@Test
  public void shouldRemoveValidHttpVersionHeader() throws Exception {
    context.setThreadingPolicy(new Synchroniser());

    final HttpRequestMessage expectedRequest = new HttpRequestMessage();
    expectedRequest.setVersion(HTTP_1_1);
    expectedRequest.setMethod(POST);
    expectedRequest.setRequestURI(URI.create("/path"));
    expectedRequest.setContent(EMPTY);

    context.checking(
        new Expectations() {
          {
            oneOfUnconditionalWrappedResponseRequiredCheck(this);
            oneOfIsEmulatedWebSocketRequest(this, expectedRequest);

            oneOf(nextFilter).messageReceived(with(serverSession), with(equal(expectedRequest)));
          }
        });

    HttpRequestMessage httpRequest = new HttpRequestMessage();
    httpRequest.setVersion(HTTP_1_1);
    httpRequest.setMethod(POST);
    httpRequest.setRequestURI(URI.create("/path"));
    httpRequest.setHeader("X-Http-Version", "httpe-1.0");
    httpRequest.setContent(EMPTY);

    HttpProtocolCompatibilityFilter filter = new HttpProtocolCompatibilityFilter();
    filter.messageReceived(nextFilter, serverSession, httpRequest);

    context.assertIsSatisfied();
  }
  @Test
  public void shouldRemoveRandomNumberQueryParam() throws Exception {
    context.setThreadingPolicy(new Synchroniser());

    final HttpRequestMessage expectedRequest = new HttpRequestMessage();
    expectedRequest.setVersion(HTTP_1_1);
    expectedRequest.setMethod(GET);
    expectedRequest.setRequestURI(URI.create("/path?param=value"));

    context.checking(
        new Expectations() {
          {
            oneOfUnconditionalWrappedResponseRequiredCheck(this);
            oneOfIsEmulatedWebSocketRequest(this, expectedRequest);

            oneOf(nextFilter).messageReceived(with(serverSession), with(equal(expectedRequest)));
          }
        });

    HttpRequestMessage httpRequest = new HttpRequestMessage();
    httpRequest.setVersion(HTTP_1_1);
    httpRequest.setMethod(GET);
    httpRequest.setRequestURI(URI.create("/path?param=value&.krn=12345"));

    HttpProtocolCompatibilityFilter filter = new HttpProtocolCompatibilityFilter();
    filter.messageReceived(nextFilter, serverSession, httpRequest);

    context.assertIsSatisfied();
  }
  @Test
  public void shouldNotOverrideNextProtocolBasedOnOriginQueryParam() throws Exception {
    context.setThreadingPolicy(new Synchroniser());

    final HttpRequestMessage expectedRequest = new HttpRequestMessage();
    expectedRequest.setVersion(HTTP_1_1);
    expectedRequest.setMethod(POST);
    expectedRequest.setRequestURI(URI.create("/path?.ko=http://localhost:8000"));
    expectedRequest.setHeader("X-Next-Protocol", "other");
    expectedRequest.setContent(EMPTY);

    context.checking(
        new Expectations() {
          {
            oneOfUnconditionalWrappedResponseRequiredCheck(this);
            oneOfIsEmulatedWebSocketRequest(this, expectedRequest);

            oneOf(nextFilter).messageReceived(with(serverSession), with(equal(expectedRequest)));
          }
        });

    HttpRequestMessage httpRequest = new HttpRequestMessage();
    httpRequest.setVersion(HTTP_1_1);
    httpRequest.setMethod(POST);
    httpRequest.setRequestURI(URI.create("/path?.ko=http://localhost:8000"));
    httpRequest.setHeader("X-Next-Protocol", "other");
    httpRequest.setContent(EMPTY);

    HttpProtocolCompatibilityFilter filter = new HttpProtocolCompatibilityFilter();
    filter.messageReceived(nextFilter, serverSession, httpRequest);

    context.assertIsSatisfied();
  }
  @Test
  public void shouldRejectInvalidHttpVersionHeader() throws Exception {
    context.setThreadingPolicy(new Synchroniser());

    final HttpResponseMessage expectedResponse = new HttpResponseMessage();
    expectedResponse.setVersion(HTTP_1_1);
    expectedResponse.setStatus(SERVER_NOT_IMPLEMENTED);
    expectedResponse.setReason("Http-Version not supported");

    final HttpRequestMessage httpRequest = new HttpRequestMessage();
    httpRequest.setVersion(HTTP_1_1);
    httpRequest.setMethod(POST);
    httpRequest.setRequestURI(URI.create("/path"));
    httpRequest.setHeader("X-Http-Version", "unrecognized");

    context.checking(
        new Expectations() {
          {
            oneOfUnconditionalWrappedResponseRequiredCheck(this);
            oneOfIsEmulatedWebSocketRequest(this, httpRequest);

            oneOf(nextFilter).filterWrite(with(serverSession), with(hasMessage(expectedResponse)));
            oneOf(nextFilter).filterClose(with(serverSession));
          }
        });

    HttpProtocolCompatibilityFilter filter = new HttpProtocolCompatibilityFilter();
    filter.messageReceived(nextFilter, serverSession, httpRequest);

    context.assertIsSatisfied();
  }
  @Test
  public void shouldDeriveCreateEncodingFromCreateTextEscapedPathExtension() throws Exception {
    context.setThreadingPolicy(new Synchroniser());

    final HttpRequestMessage expectedRequest = new HttpRequestMessage();
    expectedRequest.setVersion(HTTP_1_1);
    expectedRequest.setMethod(POST);
    final URI requestURI = URI.create("/path/;e/cte");
    expectedRequest.setRequestURI(requestURI);
    expectedRequest.setHeader("X-Create-Encoding", "text-escaped");
    expectedRequest.setHeader("X-Next-Protocol", "wse/1.0");
    expectedRequest.setContent(EMPTY);

    context.checking(
        new Expectations() {
          {
            oneOfUnconditionalWrappedResponseRequiredCheck(this);
            oneOfIsEmulatedWebSocketRequest(this, expectedRequest);

            allowing(localAddress).getResource();
            will(returnValue(requestURI));

            oneOf(nextFilter).messageReceived(with(serverSession), with(equal(expectedRequest)));
          }
        });

    HttpRequestMessage httpRequest = new HttpRequestMessage();
    httpRequest.setVersion(HTTP_1_1);
    httpRequest.setMethod(POST);
    httpRequest.setRequestURI(requestURI);
    httpRequest.setContent(EMPTY);

    HttpProtocolCompatibilityFilter filter = new HttpProtocolCompatibilityFilter();
    filter.messageReceived(nextFilter, serverSession, httpRequest);

    context.assertIsSatisfied();
  }
  @SuppressWarnings("unchecked")
  @Test
  public void asElevatedRequestShouldPropagateSubjectAndLoginContext() throws Exception {
    final DefaultHttpSession session = context.mock(DefaultHttpSession.class, "session");
    Subject subject = new Subject();
    final ResultAwareLoginContext loginContext =
        context.mock(ResultAwareLoginContext.class, "loginContext");

    final HttpRequestMessage expectedRequest = new HttpRequestMessage();
    expectedRequest.setVersion(HTTP_1_1);
    expectedRequest.setMethod(POST);
    final URI requestURI = URI.create("/path/;e/cte");
    expectedRequest.setRequestURI(requestURI);
    expectedRequest.setContent(EMPTY);

    context.checking(
        new Expectations() {
          {
            oneOf(session).getVersion();
            will(returnValue(HTTP_1_1));
            oneOf(session).getMethod();
            will(returnValue(POST));
            oneOf(session).getParameters();
            oneOf(session).getRequestURI();
            will(returnValue(requestURI));
            oneOf(session).isSecure();
            oneOf(session).getReadCookies();
            oneOf(session).getReadHeader("Content-Length");
            will(returnValue(null));
            allowing(session).getReadHeaders();
            will(returnValue(new HashMap<String, List<String>>()));
            oneOf(session).getSubject();
            will(returnValue(subject));
            oneOf(session).getLoginContext();
            will(returnValue(loginContext));
            oneOf(session).setReadHeaders(with(any(HashMap.class)));
          }
        });

    HttpRequestMessage request = HttpElevateEmulatedRequestFilter.asElevatedRequest(session);
    assertSame(subject, request.getSubject());
    assertSame(loginContext, request.getLoginContext());

    context.assertIsSatisfied();
  }