sahaya / rest-assured

Automatically exported from code.google.com/p/rest-assured
0 stars 0 forks source link

Custom cookie parsing fails when request contains redirect #235

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Given: A request with a redirect as a result, f.e.

@Test
    public void logAll()
    {
        RestAssured.reset();

        given().log().all().when().get("/demo"); //setting cookies, HTTP 302
    }

expected: request can be used like all others.
actual result:

Request method: GET
Request path:   http://localhost:8080/demo
Request params: <none>
Query params:   <none>
Form params:    <none>
Path params:    <none>
Headers:        Content-Type=*/*
Cookies:        <none>
Body:           <none>

Assumption: Since the Apache httpclient internally handles the redirect, rest 
assured is not noticing what happens before the final result.
This leads to lost cookies and possibly other problems.

Original issue reported on code.google.com by everf...@gmail.com on 11 May 2013 at 6:15

GoogleCodeExporter commented 9 years ago
I don't see that you're setting any cookies in the request?! Or do you mean to 
log the response? Here you're only logging the request.

Original comment by johan.ha...@gmail.com on 14 May 2013 at 7:02

GoogleCodeExporter commented 9 years ago
The response is containing Set-Cookie header and HTTP status 302 
(redirect-after-post pattern)
You can see that rest-assured does not log any cookies.

Original comment by everf...@gmail.com on 18 May 2013 at 10:30

GoogleCodeExporter commented 9 years ago
You're only logging the HTTP request, not the response. In order to log the 
HTTP response you should use:

expect().log().all().when().get("/demo");

Original comment by johan.ha...@gmail.com on 21 May 2013 at 9:31

GoogleCodeExporter commented 9 years ago
Right, changed test case - still cookies not logged.

I even added a request logging filter like

final String body = given().filter(new 
RequestLoggingFilter()).expect().log().all().get("/demo").asString();

Request method: GET
Request path:   .../demo
Request params: <none>
Query params:   <none>
Form params:    <none>
Path params:    <none>
Headers:        Accept=application/json
                Content-Type=application/json
Cookies:        <none>
Body:           <none>

HTTP/1.1 404 Not Found //this is fine and expected
Date=Tue, 21 May 2013 11:00:17 GMT
Server=Apache
Strict-Transport-Security=max-age=2592000; includeSubDomains
X-Content-Type-Options=nosniff
X-XSS-Protection=1; mode=block
Vary=Accept-Encoding
Content-Encoding=gzip
Content-Length=182
Keep-Alive=timeout=5, max=100
Connection=Keep-Alive
Content-Type=text/html; charset=iso-8859-1

<html xmlns="http://www.w3.org/1999/xhtml">

What I see is the *second* request beeing logged, not the first where the 
authentication happens/cookies are beeing set and a HTTP 302 is returned.

Original comment by everf...@gmail.com on 21 May 2013 at 11:02

GoogleCodeExporter commented 9 years ago
I don't understand, I don't see that you do any authentication in your example!?

Original comment by johan.ha...@gmail.com on 21 May 2013 at 11:10

GoogleCodeExporter commented 9 years ago
Accessing the special URL ("/demo") is sufficient for authentication in my 
application.
That requests results in 
HTTP 302 + set-cookie

Original comment by everf...@gmail.com on 21 May 2013 at 11:15

GoogleCodeExporter commented 9 years ago
What kind of authentication are you using?

Original comment by johan.ha...@gmail.com on 21 May 2013 at 11:20

GoogleCodeExporter commented 9 years ago
Accessing that URL is sufficient as authentication. A session is created for 
the user then.

Original comment by everf...@gmail.com on 21 May 2013 at 11:24

GoogleCodeExporter commented 9 years ago
What if you configure RA to not follow redirects, does that mean that you get a 
cooke?

Original comment by johan.ha...@gmail.com on 21 May 2013 at 11:48

GoogleCodeExporter commented 9 years ago
final String cookie = given().redirects().follow(false).filter(new 
RequestLoggingFilter()).expect().log().all().get("/demo").cookie("JSESSIONID");
logger.info("Cookie:" +cookie);

Still no session cookie, neither in request logging filter, nor in the result 
of .cookie();

Request method: GET
Request path:   ..../demo
Request params: <none>
Query params:   <none>
Form params:    <none>
Path params:    <none>
Headers:        Content-Type=*/*
Cookies:        <none>
Body:           <none>
HTTP/1.1 302 Found
Date=Tue, 21 May 2013 17:17:47 GMT
Server=Apache-Coyote/1.1
Strict-Transport-Security=max-age=2592000; includeSubDomains
X-Content-Type-Options=nosniff
X-XSS-Protection=1; mode=block
X-Version=1.0.0.CI-SNAPSHOT-7e87603
Location=....
Content-Language=en-US
Content-Length=0
Keep-Alive=timeout=5, max=100
Connection=Keep-Alive
INFO  n.b.p.i.HttpRestIT:104 - Cookie:null

Original comment by everf...@gmail.com on 21 May 2013 at 5:22

GoogleCodeExporter commented 9 years ago
Are you really sure that your server really provides a cookie?

Original comment by johan.ha...@gmail.com on 22 May 2013 at 6:29

GoogleCodeExporter commented 9 years ago
Yes.

This is the workaround I have in place for RA-229, RA-234, RA-235 now. It is 
called in a @BeforeClass part of the junit test.

private static void authenticateQuirk() throws Exception
    {
        final CookieStore cookieStore = new BasicCookieStore();
        final HttpClient httpclient = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();
        httpclient.execute(new HttpGet("/demo"));

        final List<Cookie> cookies = cookieStore.getCookies();

        for (final Cookie cookie : cookies)
        {
            if(cookie.getName().equals("JSESSIONID"))
            {
                final String sessionId = cookie.getValue();
                //RestAssured.sessionId = sessionId; // 234
                final com.jayway.restassured.response.Cookie sessionCookie = new com.jayway.restassured.response.Cookie.Builder("JSESSIONID", sessionId).build();
                RestAssured.requestSpecification.cookie(sessionCookie);
            }
        }
    }

Original comment by everf...@gmail.com on 22 May 2013 at 9:41

GoogleCodeExporter commented 9 years ago
So if I were to reproduce this I could just create a resource that returns a 
cookie and a redirect at the same time? In these cases RA doesn't include the 
cookie? 

Original comment by johan.ha...@gmail.com on 22 May 2013 at 9:51

GoogleCodeExporter commented 9 years ago
That is my current understanding of the issue.

Original comment by everf...@gmail.com on 22 May 2013 at 9:57

GoogleCodeExporter commented 9 years ago
Ok I'll try to see if I get reproduce it when I find some time. Thank you so 
far!

Original comment by johan.ha...@gmail.com on 22 May 2013 at 10:01

GoogleCodeExporter commented 9 years ago
I've tried to reproduce this but I can't. Here's my server resource: 

get("/redirect-and-set-cookie") {
    val url: String = {params("url")}
    val cookie: Cookie = new Cookie("cookieName", "cookieValue")
    response.addCookie(cookie)
    redirect(url)
  }

And this is the test:

        given().
                redirects().follow(false).
                param("url", "/hello").
        expect().
                statusCode(302).
                cookie("cookieName", "cookieValue").
                header("location", "http://localhost:8080/hello").
        when().
                get("/redirect-and-set-cookie");

This means that I get cookies when redirects are disabled. By default Rest 
Assured is configured not to include cookies in redirects but if you change 
that it'll be included on redirects as well:

        given().
                config(newConfig().httpClient(httpClientConfig().setParam(COOKIE_POLICY, BROWSER_COMPATIBILITY))).
                param("url", "/reflect").
        expect().
                statusCode(200).
                cookie("cookieName", "cookieValue").
        when().
                get("/redirect-and-set-cookie");

Original comment by johan.ha...@gmail.com on 22 Nov 2013 at 7:53