@Test
  public void shouldNotRejectMissingHttpVersionHeader() 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.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();
  }
  /**
   * Does the provided request form a valid web socket handshake request?
   *
   * @param request the candidate web socket handshake request
   * @return true iff the provided request is a web socket handshake request.
   */
  protected boolean doValidate(HttpRequestMessage request, final boolean isPostMethodAllowed) {

    if (!isPostMethodAllowed) {
      if (request.getMethod() != HttpMethod.GET) {
        return false;
      }
    } else {
      if (request.getMethod() != HttpMethod.GET || request.getMethod() == HttpMethod.POST) {
        return false;
      }
    }

    if (request.getVersion() != HttpVersion.HTTP_1_1) {
      return false;
    }

    if (request.getRequestURI() == null) {
      return false;
    }

    boolean ok = requireHeader(request, "Connection", "Upgrade");
    if (!ok) {
      return false;
    }

    ok = requireHeader(request, "Upgrade", "WebSocket");
    if (!ok) {
      return false;
    }

    ok = requireHeader(request, "Host");

    return ok;
  }
  @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();
  }
 public static WebSocketWireProtocol guessWireProtocolVersion(HttpRequestMessage httpRequest) {
   String httpRequestVersionHeader =
       httpRequest.getHeader(WsHandshakeValidator.SEC_WEB_SOCKET_VERSION);
   if (httpRequestVersionHeader == null || httpRequestVersionHeader.length() == 0) {
     // Let's see if the request looks like Hixie 75 or 76
     if (httpRequest.getHeader(WsHandshakeValidator.SEC_WEB_SOCKET_KEY1) != null
         && httpRequest.getHeader(WsHandshakeValidator.SEC_WEB_SOCKET_KEY2) != null) {
       return WebSocketWireProtocol.HIXIE_76;
     } else {
       return WebSocketWireProtocol.HIXIE_75;
     }
   } else {
     try {
       return WebSocketWireProtocol.valueOf(Integer.parseInt(httpRequestVersionHeader));
     } catch (NumberFormatException e) {
       return null;
     }
   }
 }
  @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();
  }
  public boolean requireHeader(HttpRequestMessage request, String name, String value) {
    if (request == null || name == null || value == null) {
      return false;
    }

    List<String> headers = request.getHeaderValues(name, false);
    if (headers != null) {
      boolean found = false;
      for (String header : headers) {
        if (header != null && header.trim().equalsIgnoreCase(value)) {
          found = true;
        }
      }
      return found;
    }
    return false;
  }
 private void oneOfIsEmulatedWebSocketRequest(
     Expectations exp, HttpRequestMessage expectedRequest) {
   exp.allowing(serverSession).getRequestURI();
   exp.will(returnValue(expectedRequest.getRequestURI()));
 }
  @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();
  }
  @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();
  }