예제 #1
0
  @Override
  public boolean parsedHeader(HttpField field) {
    HttpHeader header = field.getHeader();
    String value = field.getValue();
    if (value == null) value = "";
    if (header != null) {
      switch (header) {
        case EXPECT:
          if (_version.getVersion() >= HttpVersion.HTTP_1_1.getVersion()) {
            HttpHeaderValue expect = HttpHeaderValue.CACHE.get(value);
            switch (expect == null ? HttpHeaderValue.UNKNOWN : expect) {
              case CONTINUE:
                _expect100Continue = true;
                break;

              case PROCESSING:
                _expect102Processing = true;
                break;

              default:
                String[] values = value.split(",");
                for (int i = 0; values != null && i < values.length; i++) {
                  expect = HttpHeaderValue.CACHE.get(values[i].trim());
                  if (expect == null) _expect = true;
                  else {
                    switch (expect) {
                      case CONTINUE:
                        _expect100Continue = true;
                        break;
                      case PROCESSING:
                        _expect102Processing = true;
                        break;
                      default:
                        _expect = true;
                    }
                  }
                }
            }
          }
          break;

        case CONTENT_TYPE:
          MimeTypes.Type mime = MimeTypes.CACHE.get(value);
          String charset =
              (mime == null || mime.getCharset() == null)
                  ? MimeTypes.getCharsetFromContentType(value)
                  : mime.getCharset().toString();
          if (charset != null) _request.setCharacterEncodingUnchecked(charset);
          break;
        default:
      }
    }

    if (field.getName() != null) _request.getHttpFields().add(field);
    return false;
  }
 @Override
 public boolean startRequest(
     HttpMethod method, String methodString, ByteBuffer uri, HttpVersion httpVersion) {
   Connector connector = getConnector();
   String scheme =
       connector.getConnectionFactory(SslConnectionFactory.class) != null ? "https" : "http";
   headers.put(HTTPSPDYHeader.SCHEME.name(version), scheme);
   headers.put(HTTPSPDYHeader.METHOD.name(version), methodString);
   headers.put(
       HTTPSPDYHeader.URI.name(version),
       BufferUtil.toUTF8String(uri)); // TODO handle bad encodings
   headers.put(HTTPSPDYHeader.VERSION.name(version), httpVersion.asString());
   return false;
 }
예제 #3
0
  @Override
  public void onReply(Stream stream, ReplyInfo replyInfo) {
    HttpExchange exchange = getHttpExchange();
    if (exchange == null) return;

    try {
      HttpResponse response = exchange.getResponse();

      Fields fields = replyInfo.getHeaders();
      short spdy = stream.getSession().getVersion();
      HttpVersion version =
          HttpVersion.fromString(fields.get(HTTPSPDYHeader.VERSION.name(spdy)).getValue());
      response.version(version);
      String[] status = fields.get(HTTPSPDYHeader.STATUS.name(spdy)).getValue().split(" ", 2);

      Integer code = Integer.parseInt(status[0]);
      response.status(code);
      String reason = status.length < 2 ? HttpStatus.getMessage(code) : status[1];
      response.reason(reason);

      if (responseBegin(exchange)) {
        for (Fields.Field field : fields) {
          String name = field.getName();
          if (HTTPSPDYHeader.from(spdy, name) != null) continue;
          // TODO: handle multiple values properly
          HttpField httpField = new HttpField(name, field.getValue());
          responseHeader(exchange, httpField);
        }

        if (responseHeaders(exchange)) {
          if (replyInfo.isClose()) {
            responseSuccess(exchange);
          }
        }
      }
    } catch (Exception x) {
      responseFailure(x);
    }
  }
    @Override
    public void reply(ReplyInfo replyInfo, Callback handler) {
      try {
        Fields headers = new Fields(replyInfo.getHeaders(), false);

        headers.remove(HTTPSPDYHeader.SCHEME.name(version));

        String status = headers.remove(HTTPSPDYHeader.STATUS.name(version)).value();
        Matcher matcher = statusRegexp.matcher(status);
        matcher.matches();
        int code = Integer.parseInt(matcher.group(1));
        String reason = matcher.group(2).trim();

        HttpVersion httpVersion =
            HttpVersion.fromString(headers.remove(HTTPSPDYHeader.VERSION.name(version)).value());

        // Convert the Host header from a SPDY special header to a normal header
        Fields.Field host = headers.remove(HTTPSPDYHeader.HOST.name(version));
        if (host != null) headers.put("host", host.value());

        HttpFields fields = new HttpFields();
        for (Fields.Field header : headers) {
          String name = camelize(header.name());
          fields.put(name, header.value());
        }

        // TODO: handle better the HEAD last parameter
        HttpGenerator.ResponseInfo info =
            new HttpGenerator.ResponseInfo(httpVersion, fields, -1, code, reason, false);
        send(info, null, replyInfo.isClose());

        if (replyInfo.isClose()) completed();

        handler.succeeded();
      } catch (IOException x) {
        handler.failed(x);
      }
    }
예제 #5
0
  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    final boolean isSmile = QueryResource.APPLICATION_SMILE.equals(request.getContentType());
    final ObjectMapper objectMapper = isSmile ? smileMapper : jsonMapper;

    String host = hostFinder.getDefaultHost();
    Query inputQuery = null;
    boolean hasContent = request.getContentLength() > 0 || request.getContentType() != null;
    boolean isQuery = request.getMethod().equals(HttpMethod.POST.asString());
    long startTime = System.currentTimeMillis();

    // queries only exist for POST
    if (isQuery) {
      try {
        inputQuery = objectMapper.readValue(request.getInputStream(), Query.class);
        if (inputQuery != null) {
          host = hostFinder.getHost(inputQuery);
          if (inputQuery.getId() == null) {
            inputQuery = inputQuery.withId(UUID.randomUUID().toString());
          }
        }
      } catch (IOException e) {
        log.warn(e, "Exception parsing query");
        final String errorMessage = e.getMessage() == null ? "no error message" : e.getMessage();
        requestLogger.log(
            new RequestLogLine(
                new DateTime(),
                request.getRemoteAddr(),
                null,
                new QueryStats(
                    ImmutableMap.<String, Object>of("success", false, "exception", errorMessage))));
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        response.setContentType(QueryResource.APPLICATION_JSON);
        objectMapper.writeValue(response.getOutputStream(), ImmutableMap.of("error", errorMessage));

        return;
      } catch (Exception e) {
        handleException(response, objectMapper, e);
        return;
      }
    }

    URI rewrittenURI = rewriteURI(host, request);
    if (rewrittenURI == null) {
      onRewriteFailed(request, response);
      return;
    }

    final Request proxyRequest =
        getHttpClient()
            .newRequest(rewrittenURI)
            .method(request.getMethod())
            .version(HttpVersion.fromString(request.getProtocol()));

    // Copy headers
    for (Enumeration<String> headerNames = request.getHeaderNames();
        headerNames.hasMoreElements(); ) {
      String headerName = headerNames.nextElement();

      if (HttpHeader.TRANSFER_ENCODING.is(headerName)) {
        hasContent = true;
      }

      for (Enumeration<String> headerValues = request.getHeaders(headerName);
          headerValues.hasMoreElements(); ) {
        String headerValue = headerValues.nextElement();
        if (headerValue != null) {
          proxyRequest.header(headerName, headerValue);
        }
      }
    }

    // Add proxy headers
    addViaHeader(proxyRequest);

    addXForwardedHeaders(proxyRequest, request);

    final AsyncContext asyncContext = request.startAsync();
    // We do not timeout the continuation, but the proxy request
    asyncContext.setTimeout(0);
    proxyRequest.timeout(getTimeout(), TimeUnit.MILLISECONDS);

    if (hasContent) {
      if (inputQuery != null) {
        proxyRequest.content(new BytesContentProvider(jsonMapper.writeValueAsBytes(inputQuery)));
      } else {
        proxyRequest.content(proxyRequestContent(proxyRequest, request));
      }
    }

    customizeProxyRequest(proxyRequest, request);

    if (isQuery) {
      proxyRequest.send(
          newMetricsEmittingProxyResponseListener(request, response, inputQuery, startTime));
    } else {
      proxyRequest.send(newProxyResponseListener(request, response));
    }
  }