Jersey ClientResponse getCookies failing to parse correctly - java

I have some Java code which is calling a restful service, and needs to first authenticate and store cookies for a future call. I am using Jersey 1.8. The problem is that after making the call to authenticate, I try to retrieve the cookies using ClientResponse.getCookies() and iterate through the list of NewCookie objects. However, when calling NewCookie.getName(), the path of the cookie is returned.
The cookies returned in the response header look like this:
Set-Cookie: xsIdEEDB0766347B60DAEAA0AF57226EDD2C=385DF57B79FE0A4D84E04ED43000A81B; path=/; HttpOnly
My code looks something like this. I am just dumping the info to System.out for now because I wanted to look at the values in the debugger.
My question is why ClientResponse.getCookies() does not seem to work. Parsing the headers manually will work, but that just does not seem right. Is there a way to configure the Client or the ClientResponse to correctly get the cookies?
ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
Builder builder = client.resource(MY_PATH).accept("text/plain");
builder = builder.header(AUTHORIZATION, auth);
ClientResponse response = builder.head();
if (response.getClientResponseStatus() == Status.OK) {
// Look at cookies in the response
List<NewCookie> cs = response.getCookies();
for (NewCookie c : cs) {
System.out.println(c.getName());
System.out.println(c.getValue());
}
// Look at the cookies in the header
List<String> cookies = headers.get("Set-Cookie");
for (String cookie : cookies) {
// example: xsIdEEDB0766347B60DAEAA0AF57226EDD2C=385DF57B79FE0A4D84E04ED43000A81B; path=/; HttpOnly
int x = cookie.indexOf(';');
String cookieNameValue = cookie.substring(0, x);
String[] nameValue = cookieNameValue.split("=");
NewCookie nc = new NewCookie(nameValue[0], nameValue[1]);
}
}

Related

How do you set a token as an HTTPHeader for a get request in java?

I'm trying to write a test to receive a JSON response from an API and I need to set a security token in the header for the API call. I've already verified that I am receiving a valid token from the get/token API. When I try to execute the HttpGet I am receiving a 401 status code.
Update: Does anyone have a complete list of authorization token types?
public void listAllDoctors() throws IOException {
String listAllDoctors = "/api/doctors/search";
HttpGet getDEV = new HttpGet(DEVBASE_ENDPOINT + listAllDoctors);
getDEV.setHeader(HttpHeaders.AUTHORIZATION, "token " + TOKEN);
getDEV.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
response = client.execute(getDEV);
int actualStatus = response.getStatusLine().getStatusCode();
assertEquals(actualStatus, 200);
}
I figured out that the API uses a custom header token authentication. So the line of code goes like this:
getDev.setHeader("token", "Token value goes here");

HTTPUrlConnection maintain session

I am using Restful Services on server and trying to maintain the same session after performing login:
URL endpoint = new URL(getString(R.string.url_login));
// Create connection
HttpURLConnection myConnection = (HttpURLConnection) endpoint.openConnection();
myConnection.setRequestMethod("POST");
myConnection.setRequestProperty("User-Agent", "my-rest-app-v0.1");
// Create the data
String myData = "username=" + username + "&password=" + pwd;
// Enable data writing
myConnection.setDoOutput(true);
// Write the data
myConnection.getOutputStream().write(myData.getBytes());
rc = myConnection.getResponseCode();
if (rc == 200) {
String Cookie= myConnection.getHeaderField("Set-Cookie");
URL endpoint2 = new URL(getString(R.string.url_checkUserType));
HttpURLConnection myConnection2 =
(HttpURLConnection)endpoint2.openConnection();
myConnection2.setRequestMethod("GET");
myConnection2.setRequestProperty("User-Agent", "my-rest-app-v0.1");
myConnection2.setRequestProperty("Cookie", Cookie);
rc2 = myConnection2.getResponseCode();
....
}....
The problem is that rc2 is every time 401 as WebService doesn't recognize that requiest is part of the same session. What am I doing wrong?
You may do as follows
on the server side, it checks if the incoming request has a "sessionId" in cookie: if not, create one and return it in response; if yes, it knows the request belongs to a known session
on the client side, after a successful login, retrieve the "sessionId" from the response, and set it in the following requests
==
connection.setRequestProperty("Cookie", "JSESSIONID=" + URLEncoder.encode(jSessionId, "UTF-8"));
The solution was to use Spring RESTful services for Android that worked great for me.

Spring Boot TestRestTemplate: Pass along session id

I've got a Spring Boot application with some tests. The application's 'happy-path' requires that the user send a request to start a session, then it can make other requests to other services.
I'm trying to test these other services, but I need a session started first. My mindset was as follows:
Hit the session start endpoint
Get the session cookie from that request
Slap that cookie onto future requests made during testing.
To achieve that, I've got this mess:
String s = t.postForEntity(loginUrl, remoteSessionPacket, String.class)
.getHeaders()
.get("Set-Cookie").get(0);
String[] split = s.split(";");
String sessionId = "";
for (String s1 : split) {
if(s1.contains("SESSION"))
{
sessionId = s1;
}
}
HttpHeaders headers = new HttpHeaders();
headers.add("SESSION", sessionId);
HttpEntity<?> httpEntity = new HttpEntity<>(headers);
RemoteDTOPacket= new RemoteDTOPacket();
packet.Token = UUID.randomUUID().toString();
String url = "http://localhost:" + port + "/domain/SomeFunction";
ResponseEntity<ResponsePacket> response = t.postForEntity(url, packet, ResponsePacket.class, httpEntity);
Assert.assertEquals(0, (long) response.getBody().count);
Obviously, this doesn't work and errors are thrown with abandon.
Does anyone know how to accomplish what I'm trying to do?
Any help is greatly appreciated.
Session id is stored in cookie that is stored in "Cookie" header - not in separate request header. Something like this should work:
List<String> coockies = t.postForEntity(loginUrl, remoteSessionPacket, String.class)
.getHeaders()
.get("Set-Cookie");
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.put(HttpHeaders.COOKIE, coockies);
HttpEntity<Void> requestEntity = new HttpEntity<>(requestHeaders);
Or you can get exact session id cookie that will be most probably stored under "JSESSIONID" key.

httpservletrequest getCookies() or getHeader()

I want to accept data from a client.
What are the pros and cons of each approach?
HttpServletRequest request = retriveRequest();
Cookie [] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if ("my-cookie-name".equals(cookie.getName())) {
String value = cookie.getValue();
//do something with the cookie's value.
}
}
or
String request.getHeader("header-name");
As I read How are cookies passed in the HTTP protocol?
Cookies are passed as HTTP headers, both in the request (client -> server), and in the response (server -> client).
getCookies, frees you from parsing the Cookie header string, and creating a java object out of it. Otherwise you will have to do something like:
String rawCookie = request.getHeader("Cookie");
String[] rawCookieParams = rawCookie.split(";");
for(String rawCookieNameAndValue :rawCookieParams)
{
String[] rawCookieNameAndValuePair = rawCookieNameAndValue.split("=");
}
// so on and so forth.

How to delete a webresponse based on jsessionId in c#?

I am trying to do API testing in c#. I have a webresponse with some values uploaded to a url and a WebClient object with some headers (JSESSIONID, path etc)
string cookie = JSESSIONID : ajyrnXWREThsarfoWSGGREGarevr;
myWebClient.Headers.Add(HttpRequestHeader.Cookie, cookie);
var responseArray1 = myWebClient.UploadValues(restURL, "POST", myQueryStringCollection2);
Now I want to delete the response with the above JSESSIONID.
I was able to do this in Java with the below code:
Client client = Client.create();
Builder webResource = client.resource(restUrl).cookie(cookie);
ClientResponse response1 = webResource.type("application/json").delete(ClientResponse.class);
Please let me know how to proceed in C#.

Categories

Resources