Get cookies from redirect URL - java

I have one url, which make 2 internal redirects then finally returns ok response.
First URL: : http://www.someurl.com/
Redirect URL 1: : http://www.someurl_1.com/ with response 302
Redirect URL 2: : http://www.someurl_2.com/ with response 302
Final URL: : http://www.finalurl.com/ with response 200
Internally Redirect URL 1 send some cookie to Redirect URL 2.
What I have to do is get cookie of which set for Redirect URL 2:.
Here is my java code.
HttpClient client = HttpClientBuilder.create().build();
HttpGet get = new HttpGet(myurl);
get.setHeader("User-Agent", "Mozilla");
get.setHeader("Accept"," text/html,application/xhtml+xml,application/xml;");
get.setHeader("Accept-Language", "en-US,en;q=0.8");
get.setHeader("Accept-Encoding"," gzip, deflate");
get.setHeader("Connection","keep-alive");
get.setHeader("Cookie",JSESSIONID+");
// get.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
Header[] requestheaders = get.getAllHeaders();
System.out.println("requestheaders >>> ");
for(Header header: requestheaders){
System.out.println(header.getName()+"-------------------- "+header.getValue());
}
HttpResponse response = client.execute(get);
System.out.println("response 7 "+response);
System.out.println("Headers are");
Header[] headers = response.getAllHeaders();
for (int i = 0; i < headers.length; i++) {
System.out.println((headers[i].getName()+"___________________"+headers[i].getValue()));
}
This code gives me final response rather than intermediate redirected response. So can anyone please suggest me what is better way of doing it.
Other thing I have checked is:-
I have disable redirect, this response gives me very first url of this process.
I have used Jsoup to disable redirect which gives same out put as above.
Whereas fetching such redirected cookie is possible in ruby , i have done that.
But I have to do this in java.
httpclient 4.5

This worked for me
HttpClient client = HttpClientBuilder.create().setRedirectStrategy(new DefaultRedirectStrategy() {
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
boolean isRedirect=false;
try {
isRedirect = super.isRedirected(request, response, context);
Header[] requestheaders = response.getAllHeaders();
System.out.println("getAuthToken >>> ");
for(Header header: requestheaders){
System.out.println(header.getName()+"-------------------- "+header.getValue());
if(header.getName().equalsIgnoreCase("Set-Cookie") && header.getValue().startsWith("auth-token")){
System.out.println("Auth_Cookie "+header.getValue().split(";")[0]);
auth_token = header.getValue().split(";")[0];
}
}
} catch (ProtocolException e) {
e.printStackTrace();
}
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return false;
}
}).build();
HttpGet get = new HttpGet(url);
client.execute(get);
For more technical detail check my blog here.

If you want more control over the redirection behavior, you can probably change the RedirectStrategy of the http client.
You can create your own RedirectStrategy and use it:
HttpClient instance = HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy()).build();

I had the same issue where I had a number of redirects but I needed the cookies from each response to be passed on to the redirects. I could have probably done more work to figure out what cookies each redirect really needed but I just built up a map of all the cookies and each redirect got the full set of cookies from the combined redirects before it. Here is my code...
import java.util.HashMap;
import java.util.Map;
import org.apache.http.Header;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.RedirectStrategy;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultRedirectStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
...
RestTemplate restTemplate = new RestTemplate();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
RedirectStrategy rs = new DefaultRedirectStrategy() {
Map<String, Header> cookies = new HashMap<>();
#Override
public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response,
HttpContext context) throws ProtocolException {
//
// Get the cookies out of the response so we can inject them into the redirect.
//
for (Header header : response.getHeaders("Set-Cookie")) {
this.cookies.put(header.getName(), header);
}
HttpUriRequest redirect = super.getRedirect(request, response, context);
for (Header cookie : this.cookies.values()) {
redirect.addHeader("Cookie", cookie.getValue());
}
return redirect;
}
};
final HttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(rs).build();
factory.setHttpClient(httpClient);
restTemplate.setRequestFactory(factory);
ResponseEntity<String> response = restTemplate.getForEntity("<my_url>", String.class);

Related

Apache HttpClient 4.5 redirect POST request to GET request

Am traying to hit a post endpoint but It is giving error 302, When I tried another get Url on the same server it gives me 200. Then I redirected the post request using LaxRedirectStrategy() The post request is redirecting to the get request(same endpoint only method name is GET and POST) it is not getting response from the post method. Can anyone tell me how to redirect post request to post request using apahce httpClient 4.5
HttpClient client= HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy()).build();
HttpPost post = new HttpPost("url");
post.addHeader("content-type", " application/json");
HttpResponse response = client.execute(post);
I had the same issue I solved it by using using LaxRedirectStrategy with overridden getRedirect method.
Apparently the default behaviour for POST requests is to make the redirected call as a GET request when the initial redirect response is different than 307 or 308.
See:
DefaultRedirectStrategy which LaxRedirectStrategy inherits from.
In my case the redirect response code was a 302.
So if you want something different, you can just override the getRedirect method and provide your own implementation.
Something like:
new LaxRedirectStrategy() {
#Override
public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
return new HttpGet(uri);
} else {
final int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_TEMPORARY_REDIRECT || status == HttpStatus.SC_MOVED_TEMPORARILY) { //HttpStatus.SC_MOVED_TEMPORARILY == 302
return RequestBuilder.copy(request).setUri(uri).build();
} else {
return new HttpGet(uri);
}
}
}
}
HttpClient httpClient =
HttpClients.custom().setRedirectStrategy(new LaxRedirectStrategy() {
/*
* (non-Javadoc)
*
* #see org.apache.http.impl.client.DefaultRedirectStrategy#
* getRedirect(org.apache.http.HttpRequest,
* org.apache.http.HttpResponse,
* org.apache.http.protocol.HttpContext)
*/
#Override
public HttpUriRequest getRedirect(
HttpRequest request, HttpResponse response,
HttpContext context) throws ProtocolException
{
final URI uri = getLocationURI(request, response, context);
final String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpPost.METHOD_NAME)) {
HttpPost post = new HttpPost(uri);
post.setEntity(entity);
return post;
} else if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
return new HttpGet(uri);
} else {
final int status =
response.getStatusLine().getStatusCode();
return status == HttpStatus.SC_TEMPORARY_REDIRECT
? RequestBuilder.copy(request).setUri(uri).build()
: new HttpGet(uri);
}
}
})

Httpclient-4.5.2.jar setEntity showing "cannot find symbol" (JAVA - netbeans 8)

I am trying to use some code that I got from a website that has sports data served publically via an API (http://developer.fantasydata.com).
The site provide some sample JAVA code to make the http request. For some reason the setEntity method for the declared request (request) is showing a "cannot find symbol error.
package epl.fixtures.test.app;
import java.net.URI;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class EPLFixturesTestApp {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder("https://api.fantasydata.net/soccer/v2/json/CompetitionDetails/EPL");
URI uri = builder.build();
HttpGet request = new HttpGet(uri);
request.setHeader("Ocp-Apim-Subscription-Key", "****************");
// Request body
StringEntity reqEntity = new StringEntity("{body}");
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println(EntityUtils.toString(entity));
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
The line causing the issue is the request.setEntity(reqEntity); line
Can anyone explain this to me please? I have all the relevant jar files from apache added to the project libraries directory.
Thanks
HttpGet does not have a setEntity method.
This makes sense, since the request body has no meaning in GET requests.
Only classes implementing HttpEntityEnclosingRequest have this method.
I don't know why the documentation uses it, but it seems to work when omitting those two lines (which look meaningless anyway). Code:
URIBuilder builder = new URIBuilder("https://api.fantasydata.net/soccer/v2/json/CompetitionDetails/EPL");
URI uri = builder.build();
HttpGet request = new HttpGet(uri);
request.setHeader("Ocp-Apim-Subscription-Key", "****************");
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println(EntityUtils.toString(entity));
}

org.apache.http.client.HttpResponseException: Bad Request - Sending JSON request via REST

I am receiving an error org.apache.http.client.HttpResponseException: Bad Request when I try to run this program.
Could you please help me understand where I should modify the code ?
I am using the following libraries
httpclient-4.4.1.jar
httpcore-4.4.1.jar
commons-logging-1.1.2.jar
org.apache.http.client.HttpResponseException: Bad Request
Here is the code :
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
public class Test {
public static void main(String args[]) throws Exception {
HttpClient httpclient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("http://localhost:8080/engine-rest/process-definition/key/demo-scaling/start");
try {
StringEntity input = new StringEntity("(\"variables\":{}, \"businessKey\" : \"AAA001\")");
postRequest.addHeader("Accept", "application/json");
postRequest.setEntity(input);
postRequest.addHeader("Content-Type", "application/json");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(postRequest, responseHandler);
System.out.println(responseBody);
} catch (Exception e) {
e.printStackTrace();
} finally {
httpclient.getConnectionManager().shutdown();
}
}
}
Ok, try this:
HttpClient httpClient = HttpClientBuilder.create().build();
try {
HttpPost request = new HttpPost("http://localhost:8080/engine-rest/process-definition/key/demo-scaling/start");
StringEntity params =new StringEntity("variables={\"businessKey\":\"AAA001\"}");
request.addHeader("content-type", "application/x-www-form-urlencoded");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
System.out.println(response);
}catch (Exception ex) {
// handle Exceptions
}
Use httpclientbuilder to get client (DefaultHttpClient -> Deprecated) and i am not sure if you have a valid JSON data, this is only my suggest.

Can not perform a login programmatically to a website

I have this code, witch compiles and runs without a problem:
package isitup;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.CookieStore;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.CookieSpec;
import org.apache.http.cookie.CookieSpecFactory;
import org.apache.http.cookie.MalformedCookieException;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.cookie.BrowserCompatSpec;
import org.apache.http.params.HttpParams;
public class Test {
public static void main(String args[])
{
try
{
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://www.cashialize.com/wp-login.php");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
EntityUtils.consume(entity);
}
System.out.println("Initial set of cookies:");
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (Cookie cooky : cookies) {
System.out.println("- " + cooky.toString());
}
}
HttpPost httpost = new HttpPost("http://www.cashialize.com/wp-login.php");
List <NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("log", "test"));
nvps.add(new BasicNameValuePair("pwd", "test"));
nvps.add(new BasicNameValuePair("rememberme", "forever"));
nvps.add(new BasicNameValuePair("redirect_to", "http://www.articlepub.com/wp-admin/"));
nvps.add(new BasicNameValuePair("testcookie", "1"));
nvps.add(new BasicNameValuePair("wp-submit", "Log In"));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
response = httpclient.execute(httpost);
entity = response.getEntity();
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
EntityUtils.consume(entity);
}
System.out.println("Post logon cookies:");
cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (Cookie cooky : cookies) {
CookieStore cookieStore = new BasicCookieStore();
// Bind custom cookie store to the local context
httpclient.setCookieStore(cookieStore);
CookieSpecFactory csf = new CookieSpecFactory() {
public CookieSpec newInstance(HttpParams params) {
return new BrowserCompatSpec() {
#Override
public void validate(Cookie cookie, CookieOrigin origin)
throws MalformedCookieException {
// allow all cookies
}
};
}
};
httpclient.getCookieSpecs().register("easy", csf);
httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY, "easy");
}
}
HttpGet httpGet = new HttpGet("http://www.articlepub.com/wp-admin/profile.php");
response = httpclient.execute(httpGet);
entity = response.getEntity();
// System.out.println("Page Contents: " + EntityUtils.toString(entity));
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
EntityUtils.consume(entity);
}
System.out.println("Post get cookies:");
cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (Cookie cooky : cookies) {
System.out.println("- " + cooky.toString());
}
}
httpclient.getConnectionManager().shutdown();
} catch (Exception e) {
System.out.println(e);
}
}
}
The problem is that I can't get the user logged in. I'm pretty sure that I'm missing something in the cookies setting, but I'm inable to spot it, as it is one of my first login tries.
The console output also seems good - the only problem is that I can't spot the cookies. Here it is:
Login form get: HTTP/1.1 200 OK
Initial set of cookies:
None
Login form get: HTTP/1.1 302 Found
Post logon cookies:
None
Login form get: HTTP/1.1 200 OK
Post get cookies:
None
Please, help me with this nightmare! I'm pretty sure that I'm missing something really small, but I can't figure it out.
I'm thinking you need to configure a cookie store on the client before you execute. You can possibly also configure an HttpContext with a cookie manager.
Try looking at this document: http://hc.apache.org/httpcomponents-client-4.2.x/tutorial/html/statemgmt.html

How to specify the target URL path in HTTP Proxy authentication

I need to get the API response contents from an API server to my local server, via a proxy authentication. The API request will be like:
http://api.example.com/nav_page/head?locale=in&pointer=old&cont=/resque/&scope=old&release=new
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
public class ClientProxyAuthentication {
public static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
httpclient.getCredentialsProvider().setCredentials(
new AuthScope("proxy.example.com", 8080),
new UsernamePasswordCredentials("Domain\user", "pass"));
HttpHost targetHost = new HttpHost("api.example.com", 80, "http");
HttpHost proxy = new HttpHost("proxy.example.com", 8080);
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
HttpGet httpget = new HttpGet("/");
System.out.println("executing request: " + httpget.getRequestLine());
System.out.println("via proxy: " + proxy);
System.out.println("to target: " + targetHost);
HttpResponse response = httpclient.execute(targetHost, httpget);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
System.out.println(EntityUtils.toString(entity));
}
Header[] headers = response.getAllHeaders();
for (int i = 0; i<headers.length; i++) {
System.out.println(headers[i]);
}
EntityUtils.consume(entity);
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
}
}
In this code, if target URL is specified as api.example.com, The authentication succeeds and getting the resource (but there is no resource in base dir, hence nothing useful received). But to get correct response, I need to provide the navigation path inside that host.
Hence if i append the path like
HttpHost targetHost = new HttpHost("api.example.com/nav_page/head?locale=in&pointer=old&cont=/resque/&scope=old&release=new", 80, "http");
I am getting some error response, but not correct one.
HTTP/1.1 503 Service Unavailable
Response content length: 442
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>503 Service Temporarily Unavailable</title>
</head><body>
<h1>Service Temporarily Unavailable</h1>
<p>The server is temporarily unable to service your
request due to maintenance downtime or capacity
problems. Please try again later.</p>
<p>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body></html>
I am able to get the response, if i hit URL directly in browser.
May i know how to send the request for the navigation path?

Categories