Reputation: 145
while making connection using HttpClient in android from HttpResponse able to get all possible "set-cookie" header value (JESSIONID and XSCRF-TOKEN).Check below screenshot.
Now working with android studio with volley api for connection , i am getting only single value of "set-cookie" header (JESSIONID only).See below :
I have also check https://groups.google.com/forum/#!topic/volley-users/rNTlV-LORzY. For which have to make change in volley api jar project. But don't know how to edit volley api. If any other solution present kindly guide.
Kindly help to retrieve multiple value of "set-cookie" using volley api.
Upvotes: 1
Views: 912
Reputation: 4501
There is workaround for this in:
implementation "com.android.volley:volley:1.1.0"
"NetworkResponse (and Cache.Entry) now includes an "allHeaders" field which is the raw list of all headers returned by the server and thus can include duplicates by name."
Source: https://github.com/google/volley/issues/21
Example:
private static final String COOKIE_KEY = "Set-Cookie";
private static final String COOKIE_NAME = "NameOfOneOfTheCookies";
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
handleCookies(response);
String parsed;
try {
parsed = new String(response.data, "utf-8");
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed,
HttpHeaderParser.parseCacheHeaders(response));
}
private void handleCookies(NetworkResponse response) {
for (Header header : response.allHeaders) {
if (header.getName().equals(COOKIE_KEY) && header.getValue().startsWith(COOKIE_NAME)) {
getCookies(response);
}
}
}
private void getCookies(NetworkResponse response) {
ArrayList<String> cookiesList = new ArrayList<>();
for (Header header : response.allHeaders) {
if (header.getName().equals(COOKIE_KEY)) {
cookiesList.add(header.getValue());
}
}
// TODO Do something with the cookiesList
}
Upvotes: 1
Reputation: 1800
Problem:
The problem is inside the Volley unfortunately. I had this problem and after many searches i figured out that there is a method called convertHeaders
in BasicNetwork
class that handles headers like this:
protected static Map<String, String> convertHeaders(Header[] headers) {
Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
for (int i = 0; i < headers.length; i++) {
result.put(headers[i].getName(), headers[i].getValue());
}
return result;
}
You see the result is Map<String, String>
which can't contain same keys with different values. so you always have only last cookie.
The standard of cookie setting tells us we should separate cookies with ;
for example if you want to contain 2 key-value in a request cookie you should put them like this:
Cookies: k1=v1;k2=v2
Solution:
In your case you have two options.
1 - change your code in Server-Side so that the response contains only 1 Set-Cookie
separated key-values by ;
. example of your response:
Set-Cookie: JESSIONID=qZtQ...;Path=/;HttpOnly;XSRF-TOKEN=6c65...
2 - get Volley source code and change that buggy method and make a fixed .jar again! this option is my favorite cause you didn't touch the response of server
My implementation of this method is:
protected static Map<String, String> convertHeaders(Header[] headers) {
TreeMap result = new TreeMap(String.CASE_INSENSITIVE_ORDER);
for(int i = 0; i < headers.length; ++i) {
String headerName = headers[i].getName();
if(!result.containsKey(headerName)) {
result.put(headers[i].getName(), headers[i].getValue());
} else {
String value = (String)result.get(headerName);
String mergedValue = value + ";" + headers[i].getValue();
result.remove(headerName);
result.put(headerName, mergedValue);
}
}
return result;
}
Upvotes: 3