I have a problem with the HttpClient in Android: By using the following code, I want to use the cookies which are already set before by logging in through a webview. So the login data should be there and is indeed there, I tested it. But when I use the cookies in an httppost or httpget it doesn't use the login data. but these cookies actually should be enough to receive that page for which a login is necessary, shouldn't they? I'm not really sure if I need to send the cookies in a special way to the server or so or if it is enough to load it into the httpcontext. Here is the code:
DefaultHttpClient httpclient = new DefaultHttpClient();
CookieStore lCS = new BasicCookieStore();
if (CookieManager.getInstance().getCookie(pUrl) != null) {
String cookieString = CookieManager.getInstance().getCookie(pUrl);
String[] urlCookieArray = cookieString.split(";");
for (int i = 0; i < urlCookieArray.length; i++) {
System.out.println(urlCookieArray[i]);
String[] singleCookie = urlCookieArray[i].split("=");
Cookie urlCookie = new BasicClientCookie(singleCookie[0], singleCookie[1]);
lCS.addCookie(urlCookie);
}
}
HttpContext localContext = new BasicHttpContext();
httpclient.setCookieStore(lCS);
localContext.setAttribute(ClientContext.COOKIE_STORE, lCS);
HttpPost httppost = new HttpPost(pUrl);
// get the url connection
try {
StringBuilder sb = new StringBuilder();
HttpResponse response = httpclient.execute(httppost, localContext);
InputStream is = response.getEntity().getContent();
InputStreamReader isr = new InputStreamReader(is);
And if I run the code I only receive the login page of that site, so it didn't accept the cookie.
Thanks for help in advance
Greets, timo
I had the same problem and I used similar approach as in the question with no luck.
The thing that made it work for me was to add the domain for each copied cookie.
(BasicClientCookie cookie.setDomain(String))
My util function:
public static BasicCookieStore getCookieStore(String cookies, String domain) {
String[] cookieValues = cookies.split(";");
BasicCookieStore cs = new BasicCookieStore();
BasicClientCookie cookie;
for (int i = 0; i < cookieValues.length; i++) {
String[] split = cookieValues[i].split("=");
if (split.length == 2)
cookie = new BasicClientCookie(split[0], split[1]);
else
cookie = new BasicClientCookie(split[0], null);
cookie.setDomain(domain);
cs.addCookie(cookie);
}
return cs;
}
String cookies = CookieManager.getInstance().getCookie(url);
BasicCookieStore lCS = getCookieStore(cookies, MyApp.sDomain);
HttpContext localContext = new BasicHttpContext();
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setCookieStore(lCS);
localContext.setAttribute(ClientContext.COOKIE_STORE, lCS);
...
if you still have this problem, be careful with the given cookies, some might be malformed, check these two sites out:
http://www.codeproject.com/Articles/3106/On-The-Care-and-Handling-of-Cookies
this one helped me:
Getting "Set-Cookie" header
It seems you are copying the cookies correctly, and generally you don't need to do anything special for HttpClient to send the cookies. However, some of those may be bound to a session, and when you open a new connection with HttpClient you open a new session. The server will probably ignore cookies that don't match the current session. This might work if the session ID is in a cookie and you are able to get into the same session, but you really need to know exactly what the server does.
Related
What I want:
Send a GET request with a preemtive bassic authentication.
The request looks about like this:
<startURL>/app/process?job=doSomething¶m=value1,value2
whereas startURL is always a https link depends on the enviroment.
Looks something like this:
https://testABC.com
https://prodABC.com
startURL is also placed in a properties file as is for the diffrent enviroments.
What I looked into:
http://www.baeldung.com/httpclient-4-basic-authentication
http://www.java-tips.org/other-api-tips/httpclient/how-to-use-basic-authentication.html
http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html
It all contains a
HttpHost targetHost = new HttpHost("hostname", portnumber, "scheme");
Which is what I am having trouble with. This method is also the only one that lets you specify the scheme as "https".
One issue is, hat I don't know the portnumber. I think (?) I probably could just specify -1 for the default port, to make it work, but even aside that I also don't have the hostname, only the above mentioned startURL. I don't really want to parse this extra each time, while I also don't really want to add another property, just for the hostname.
I digged around and found this snippet, which looks like just what I want:
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://foo.com/bar");
httpGet.addHeader(BasicScheme.authenticate(
new UsernamePasswordCredentials("user", "password"),
"UTF-8", false));
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity responseEntity = httpResponse.getEntity();
from HTTP requests with basic authentication
It gives the complete request URL and simply adds the basic header and does not need any port specified. Only that this is now deprecated since Version 4.2:
Deprecated. (4.2) Use ContextAwareAuthScheme.authenticate( Credentials, HttpRequest, org.apache.http.protocol.HttpContext)
I couldn't find a single example for this method to return the basic auth header. It also wants a context as a parameter, which above snipped doesn't have. I really have no real clue how this is supposed to be used.
So, what i want to know concretely:
I just want to set up a request with the complete link, that contains all that there is, like:
https://testABC.com/app/process?job=doSomething¶m=value1,value2
and just give this as a parameter for a request that does preemptive basic authentication.
Is there any way to do this without digging up the deprecated methods and how does it look like?
I ran into the same problem as yours.
What worked for me is the following:
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "12345");
HttpGet get = new HttpGet("https://foo.bar.com/rest");
HttpHost targetHost = new HttpHost("foo.bar.com", 443, "https");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
creds);
credsProvider.setCredentials(AuthScope.ANY,creds);
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
HttpResponse response = client.execute(targetHost, get, context);
And I found this solution on: HttpClientBuilder basic auth
In the end I wound up writing the header manually on my own and sending things with that:
String header = "Basic ";
String headerValue = "username" + ":" + "password";
String encodedHeaderValue = Base64.encodeBase64String(headerValue.getBytes());
String headerBasic = header + encodedHeaderValue;
Header authHeader = new BasicHeader("Authorization", headerBasic);
ArrayList<Header> headers = new ArrayList<Header>();
headers.add(authHeader);
ArrayList<Header> headers = getHttpHeaders();
HttpClient client = HttpClients.custom().setDefaultHeaders(headers).build();
HttpUriRequest request = RequestBuilder.get().setUri(uri).build();
HttpResponse response = client.execute(request);
int responseCode = response.getStatusLine().getStatusCode();
This has now come to a point where I cannot take it anymore! i have seen a lot of people have had the same problem as this one but their solution do not work for me.
I am trying to call a REST service from my Android application. I am still new to Android BTW.
The calling code looks like this:
String httpResult = "";
HttpClient httpClient = new DefaulthttpClient();
HttpContext httpContext = new BasicHttpContext();
String url = myURL;
HttpGet httpGet = new HttpGet(myURL);
HttpResponse response = httpClient.execute(httpGet, httpContext);
//receive response in input stream
InputStream is = response.getEntity().getContent();
//convert the stream into a string
if(is != null){
//call method that will convert stream to string
httpResult = cString(is);
}else{
httpResult = "Error";
}
When I debug the code, I see that throws an exception when the compiler hits the "HttpClient httpClient = new DefaultHttpClient()" line of code and shows "No Source Found" screen.
"No Source Found"occurred when you debug a class without the source file.
You should just use F6 to step over when debugging.
I try to send cookies with a form post using the Apache HttpClient and, for some reason, the server gets the request but not the cookies. Here is my code:
DefaultHttpClient client = new DefaultHttpClient();
// Set the cookies...
{
String Domain = MyGetParameter("Domain");
BasicCookieStore cookieStore = new BasicCookieStore();
String[] strs = GetParameterSplitted("PostCookies");
int size = strs.length;
for (int i=0; i<size-1; i+=2)
{
//JOptionPane.showMessageDialog(null, strs[i]+" = "+FromBase64(strs[i+1], "UTF-8"));
BasicClientCookie cookie = new BasicClientCookie(strs[i], FromBase64(strs[i+1], "UTF-8"));
cookie.setDomain(Domain);
cookie.setPath("/");
//cookie.setSecure(true);
cookieStore.addCookie(cookie);
}
client.setCookieStore(cookieStore);
}
HttpPost post = new HttpPost(url.toURI());
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(10);
// Set the form POST parameters...
{
String[] strs = GetParameterSplitted("PostParams");
int size = strs.length;
for(int i=0; i<size-1; i+=2)
{
String name = strs[i].trim();
String value = FromBase64(strs[i+1].trim(), "UTF-8");//, "UTF-8"
nameValuePairs.add(new BasicNameValuePair(name, value));
}
}
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
post.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
post.getParams().setParameter(ClientPNames.COOKIE_POLICY, org.apache.http.client.params.CookiePolicy.BROWSER_COMPATIBILITY);
HttpResponse response = client.execute(post);
int StatusCode = response.getStatusLine().getStatusCode();
The site uses HTTP (not HTTPS), I make sure the domain name is set correctly to the cookies (http://mysite) and the cookies seem to be set correctly when the above code executes.
Does anyone have any idea why it's failing to pass them to the server?
I have seen other similar questions on this site but nothing seemed to help.
You look closely, if the date of your cookie expired httptClient not send this cookie, on this that you should put the cookies date.
And in domain name will be no "http://", only simply domain name.
For Example:(http://www.gmail.com => like this to write setDomain("www.gmail.com"))
This example i add 100 day to current day and set cookie.
Example send post data via HttpClient with cookie:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR, 100);
Date date = calendar.getTime();
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY,CookiePolicy.BROWSER_COMPATIBILITY);
httpClient.setCookieStore(new BasicCookieStore());
BasicClientCookie cookie = new BasicClientCookie(YourCookieName, YourCookieValue);
cookie.setDomain(YourDomain);
cookie.setExpiryDate(date);
cookie.setPath("/");
httpClient.getCookieStore().addCookie(cookie);
....
httpClient.execute(yourHttpUriRequest);
I have a an app that should send a GET request to a URL and send some cookies along with it. I've been looking at a few code examples for BasicCookieStore and Cookie classes, but I'm not able to figure out how to use them. Can anyone point me in the right direction?
To use cookies you need something along the lines of:
CookieStore cookieStore = new BasicCookieStore();
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpContext ctx = new BasicHttpContext();
ctx.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet get = new HttpGet("your URL here");
HttpResponse response = httpclient.execute(get,ctx);
And if you want to keep cookies between requests, you have to reuse cookieStore and ctx for every request.
Also, you may read your cookieStore to see what's inside:
List<Cookie> cookies = cookieStore.getCookies();
if( !cookies.isEmpty() ){
for (Cookie cookie : cookies){
String cookieString = cookie.getName() + " : " + cookie.getValue();
Log.info(TAG, cookieString);
}
}
Hi I am trying to make 2 GET requests to a single connection. ie
HttpGet get1 = new HttpGet("http://www.google.com/search?q=HelloWorld");
HttpGet get2 = new HttpGet("http://www.google.com/search?q=SecondSearch");
HttpResponse response = null;
response = client.execute(get1);
response = client.execute(get2);
I would like to get the body from the second execution. Obviously this fails, because it says you must release the connection first. I need to maintain the exact session - for instance, if I navigate to a site where the first step is to login, I need to navigate to any subsequent pages with the same cookie.
It's probably something incredibly simple that I am doing wrong!
You need to use a CookieStore
CookieStore cookieStore = new BasicCookieStore();
DefaultHttpClient client1 = new DefaultHttpClient();
client1.setCookieStore(cookieStore);
HttpGet httpGet1 = new HttpGet("...");
HttpResponse response1 = client1.execute(httpGet1);
DefaultHttpClient client2 = new DefaultHttpClient();
client2.setCookieStore(cookieStore);
HttpGet httpGet2 = new HttpGet("...");
HttpResponse response2 = client2.execute(httpGet2);
In the above code, both client2 will re-use cookies from the client1 request.