Ejemplo n.º 1
0
  private boolean exitAfterSpecialCases(
      final HttpResponse response, final Channel channel, final NettyResponseFuture<?> future)
      throws Exception {

    HttpRequest httpRequest = future.getNettyRequest().getHttpRequest();
    ProxyServer proxyServer = future.getProxyServer();
    int statusCode = response.getStatus().code();
    Request request = future.getCurrentRequest();
    Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();

    if (statusCode == UNAUTHORIZED_401) {
      return exitAfterHandling401(
          channel, future, response, request, statusCode, realm, proxyServer, httpRequest);

    } else if (statusCode == PROXY_AUTHENTICATION_REQUIRED_407) {
      return exitAfterHandling407(
          channel, future, response, request, statusCode, proxyServer, httpRequest);

    } else if (statusCode == CONTINUE_100) {
      return exitAfterHandling100(channel, future, statusCode);

    } else if (REDIRECT_STATUSES.contains(statusCode)) {
      return exitAfterHandlingRedirect(channel, future, response, request, statusCode, realm);

    } else if (httpRequest.getMethod() == HttpMethod.CONNECT && statusCode == OK_200) {
      return exitAfterHandlingConnect(
          channel, future, request, proxyServer, statusCode, httpRequest);
    }
    return false;
  }
Ejemplo n.º 2
0
  private boolean handleResponseAndExit(
      final Channel channel,
      final NettyResponseFuture<?> future,
      AsyncHandler<?> handler,
      HttpRequest httpRequest,
      ProxyServer proxyServer,
      HttpResponse response)
      throws Exception {

    // store the original headers so we can re-send all them to
    // the handler in case of trailing headers
    future.setHttpHeaders(response.headers());

    future.setKeepAlive(
        !HttpHeaders.Values.CLOSE.equalsIgnoreCase(
            response.headers().get(HttpHeaders.Names.CONNECTION)));

    HttpResponseStatus status = new ResponseStatus(future.getURI(), response, config);
    int statusCode = response.getStatus().code();
    Request request = future.getRequest();
    Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();
    HttpResponseHeaders responseHeaders = new ResponseHeaders(future.getURI(), response.headers());

    return handleResponseFiltersReplayRequestAndExit(channel, future, status, responseHeaders) //
        || handleUnauthorizedAndExit(
            statusCode, realm, request, response, future, proxyServer, channel) //
        || handleContinueAndExit(channel, future, statusCode) //
        || handleProxyAuthenticationRequiredAndExit(
            statusCode, realm, request, response, future, proxyServer)
        || handleConnectOKAndExit(
            statusCode, realm, request, httpRequest, response, future, proxyServer, channel) //
        || handleRedirectAndExit(request, future, response, channel) //
        || handleHanderAndExit(channel, future, handler, status, responseHeaders, response);
  }
    @Override
    public void call() throws Exception {

      WebSocketUpgradeHandler handler =
          WebSocketUpgradeHandler.class.cast(future.getAsyncHandler());
      Request request = future.getRequest();

      HttpResponseStatus status =
          new NettyResponseStatus(future.getUri(), config, response, channel);
      HttpResponseHeaders responseHeaders = new NettyResponseHeaders(response.headers());
      Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();

      if (exitAfterProcessingFilters(channel, future, handler, status, responseHeaders)) {
        return;
      }

      future.setHttpHeaders(response.headers());
      if (exitAfterHandlingRedirect(
          channel, future, response, request, response.getStatus().code(), realm)) return;

      boolean validStatus = response.getStatus().equals(SWITCHING_PROTOCOLS);
      boolean validUpgrade = response.headers().get(HttpHeaders.Names.UPGRADE) != null;
      String connection = response.headers().get(HttpHeaders.Names.CONNECTION);
      if (connection == null)
        connection =
            response.headers().get(HttpHeaders.Names.CONNECTION.toLowerCase(Locale.ENGLISH));
      boolean validConnection = HttpHeaders.Values.UPGRADE.equalsIgnoreCase(connection);
      boolean statusReceived = handler.onStatusReceived(status) == State.UPGRADE;

      if (!statusReceived) {
        try {
          handler.onCompleted();
        } finally {
          future.done();
        }
        return;
      }

      final boolean headerOK = handler.onHeadersReceived(responseHeaders) == State.CONTINUE;
      if (!headerOK || !validStatus || !validUpgrade || !validConnection) {
        requestSender.abort(channel, future, new IOException("Invalid handshake response"));
        return;
      }

      String accept = response.headers().get(HttpHeaders.Names.SEC_WEBSOCKET_ACCEPT);
      String key =
          getAcceptKey(
              future
                  .getNettyRequest()
                  .getHttpRequest()
                  .headers()
                  .get(HttpHeaders.Names.SEC_WEBSOCKET_KEY));
      if (accept == null || !accept.equals(key)) {
        requestSender.abort(
            channel,
            future,
            new IOException(
                String.format("Invalid challenge. Actual: %s. Expected: %s", accept, key)));
      }

      channelManager.upgradePipelineForWebSockets(channel.pipeline());

      invokeOnSucces(channel, handler);
      future.done();
      // set back the future so the protocol gets notified of frames
      Channels.setAttribute(channel, future);
    }
  public NettyRequest newNettyRequest(
      Request request, boolean forceConnect, ProxyServer proxyServer) throws IOException {

    Uri uri = request.getUri();
    HttpMethod method = forceConnect ? HttpMethod.CONNECT : HttpMethod.valueOf(request.getMethod());
    boolean connect = method == HttpMethod.CONNECT;

    boolean allowConnectionPooling =
        config.isAllowPoolingConnections()
            && (!HttpUtils.isSecure(uri) || config.isAllowPoolingSslConnections());

    HttpVersion httpVersion =
        !allowConnectionPooling || (connect && proxyServer.isForceHttp10())
            ? HttpVersion.HTTP_1_0
            : HttpVersion.HTTP_1_1;
    String requestUri = requestUri(uri, proxyServer, connect);

    NettyBody body = body(request, connect);

    HttpRequest httpRequest;
    NettyRequest nettyRequest;
    if (body instanceof NettyDirectBody) {
      ChannelBuffer buffer = NettyDirectBody.class.cast(body).channelBuffer();
      httpRequest = new DefaultHttpRequest(httpVersion, method, requestUri);
      // body is passed as null as it's written directly with the request
      httpRequest.setContent(buffer);
      nettyRequest = new NettyRequest(httpRequest, null);

    } else {
      httpRequest = new DefaultHttpRequest(httpVersion, method, requestUri);
      nettyRequest = new NettyRequest(httpRequest, body);
    }

    HttpHeaders headers = httpRequest.headers();

    if (!connect) {
      // assign headers as configured on request
      for (Entry<String, List<String>> header : request.getHeaders()) {
        headers.set(header.getKey(), header.getValue());
      }

      if (isNonEmpty(request.getCookies()))
        headers.set(COOKIE, CookieEncoder.encode(request.getCookies()));

      if (config.isCompressionEnforced() && !headers.contains(ACCEPT_ENCODING))
        headers.set(ACCEPT_ENCODING, GZIP_DEFLATE);
    }

    if (body != null) {
      if (body.getContentLength() < 0) headers.set(TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED);
      else headers.set(CONTENT_LENGTH, body.getContentLength());

      if (body.getContentType() != null) headers.set(CONTENT_TYPE, body.getContentType());
    }

    // connection header and friends
    boolean webSocket = isWebSocket(uri.getScheme());
    if (!connect && webSocket) {
      String origin =
          "http://"
              + uri.getHost()
              + ":"
              + (uri.getPort() == -1 ? isSecure(uri.getScheme()) ? 443 : 80 : uri.getPort());
      headers
          .set(UPGRADE, HttpHeaders.Values.WEBSOCKET) //
          .set(CONNECTION, HttpHeaders.Values.UPGRADE) //
          .set(ORIGIN, origin) //
          .set(SEC_WEBSOCKET_KEY, getKey()) //
          .set(SEC_WEBSOCKET_VERSION, "13");

    } else if (!headers.contains(CONNECTION)) {
      String connectionHeaderValue =
          connectionHeader(allowConnectionPooling, httpVersion == HttpVersion.HTTP_1_1);
      if (connectionHeaderValue != null) headers.set(CONNECTION, connectionHeaderValue);
    }

    if (!headers.contains(HOST)) headers.set(HOST, hostHeader(request, uri));

    Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();

    // don't override authorization but append
    addAuthorizationHeader(headers, systematicAuthorizationHeader(request, realm));

    setProxyAuthorizationHeader(
        headers, systematicProxyAuthorizationHeader(request, proxyServer, realm, connect));

    // Add default accept headers
    if (!headers.contains(ACCEPT)) headers.set(ACCEPT, "*/*");

    // Add default user agent
    if (!headers.contains(USER_AGENT) && config.getUserAgent() != null)
      headers.set(USER_AGENT, config.getUserAgent());

    return nettyRequest;
  }