Allow RFC2965-style attributes in Cookie header #290

Merged
merged 3 commits into from Oct 26, 2016

Projects

None yet

2 participants

@amcvitty
Contributor
amcvitty commented Oct 26, 2016 edited

This patch allows the Mock Server to gracefully handle HTTP requests that include the extra attributes that are defined in IETF's RFC2965 https://tools.ietf.org/html/rfc2965. All existing functionality is preserved, and the code now relies on Netty's implementation for the parsing of the Cookie header instead of splitting the string explicitly.

I would like for this to be reviewed, and hopefully merged and released so that I can revert to using a production version of the library in my project instead of patching the library to be compatible with existing code).

These RFC2965 attributes start with a dollar sign "$". Here's an example Cookie header:
Cookie = $Version=1; cookieName=CookieValue ; $Path=/resource

Before this patch, MockServer would throw an exception while trying to parse this header. The root cause is that it is using Netty's ClientCookieDecoder instead of the ServerCookieDecoder (and these attributes beginning with a dollar-sign are passed from client to server, rather than from server to client)

This is important to me because I'm using the Jersey library on a project with a REST service that uses a cookie, and Jersey follows this style of adding the $Version to all cookies.

To show the issue - this simple JUnit test with some example Jersey client code will fail without the patch, and will now pass after the patch.

package org.mockserver.codec;

import static org.mockserver.integration.ClientAndServer.startClientAndServer;
import static org.mockserver.model.Cookie.cookie;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.junit.Test;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.socket.PortFactory;
/*
 * 
 * Demonstrate the feature required and why it's important...
 * 
 <dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>2.12</version>
</dependency>
 */
public class JerseyTest {


    @Test 
    public void shouldWorkWithJersey() { 
        int SERVER_HTTP_PORT = PortFactory.findFreePort();
        ClientAndServer mockServerClient = startClientAndServer(SERVER_HTTP_PORT);

        // given
        mockServerClient.when(request("/resource").withMethod("GET"))
        .respond(response().withBody("Hiya!"));;


        Client client = ClientBuilder.newClient();
        WebTarget target = client.target("http://localhost:"+ SERVER_HTTP_PORT).path("resource");

        target.request().cookie("k","v").get();

        mockServerClient.verify(request().withCookie(cookie("k", "v")));

        // stop mock server and client
        if (mockServerClient instanceof ClientAndServer) {
            mockServerClient.stop();
        }
    }

}
@jamesdbloom jamesdbloom merged commit c2bde15 into jamesdbloom:master Oct 26, 2016

1 check passed

Snap CI The Snap CI build passed on Oct 26, 2016!
Details
@amcvitty
Contributor

Brilliant. Thanks James!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment