예제 #1
0
  @Override
  public void handleRequest(
      final HttpServerExchange exchange, final HttpCompletionHandler completionHandler) {
    final Deque<String> res = exchange.getRequestHeaders().get(Headers.ACCEPT_ENCODING);
    HttpHandler identityHandler = this.identityHandler;
    if (res == null || res.isEmpty()) {
      if (identityHandler != null) {
        HttpHandlers.executeHandler(identityHandler, exchange, completionHandler);
      } else {
        // we don't have an identity handler
        HttpHandlers.executeHandler(noEncodingHandler, exchange, completionHandler);
      }
      return;
    }
    boolean identityProhibited = false;
    final List<ParsedEncoding> found = new ArrayList<ParsedEncoding>();
    ParsedEncoding current = null;

    for (final String header : res) {
      final int l = header.length();
      // we do not use a string builder
      // we just keep track of where the current string starts and call substring()
      int stringStart = 0;
      for (int i = 0; i < l; ++i) {
        char c = header.charAt(i);
        switch (c) {
          case ',':
            {
              if (current != null
                  && (i - stringStart > 2
                      && header.charAt(stringStart) == 'q'
                      && header.charAt(stringStart + 1) == '=')) {
                // if this is a valid qvalue
                current.qvalue = header.substring(stringStart + 2, i);
                if (current.encoding.equals("*")) {
                  if (handleDefault(found, current)) {
                    identityProhibited = true;
                  }
                }
                current = null;
              } else if (stringStart != i) {
                current = handleNewEncoding(found, header, stringStart, i);
              }
              stringStart = i + 1;
              break;
            }
          case ';':
            {
              if (stringStart != i) {
                current = handleNewEncoding(found, header, stringStart, i);
                stringStart = i + 1;
              }
              break;
            }
          case ' ':
            {
              if (stringStart != i) {
                if (current != null
                    && (i - stringStart > 2
                        && header.charAt(stringStart) == 'q'
                        && header.charAt(stringStart + 1) == '=')) {
                  // if this is a valid qvalue
                  current.qvalue = header.substring(stringStart + 2, i);
                  if (current.encoding.equals("*")) {
                    if (handleDefault(found, current)) {
                      identityProhibited = true;
                    }
                  }
                } else {
                  current = handleNewEncoding(found, header, stringStart, i);
                }
              }
              stringStart = i + 1;
            }
        }
      }

      if (stringStart != l) {
        if (current != null
            && (l - stringStart > 2
                && header.charAt(stringStart) == 'q'
                && header.charAt(stringStart + 1) == '=')) {
          // if this is a valid qvalue
          current.qvalue = header.substring(stringStart + 2, l);
          if (current.encoding.equals("*")) {
            if (handleDefault(found, current)) {
              identityProhibited = true;
            }
          }
        } else {
          current = handleNewEncoding(found, header, stringStart, l);
        }
      }
    }
    int size = found.size();
    if (size == 0) {
      if (identityProhibited || identityHandler == null) {
        HttpHandlers.executeHandler(noEncodingHandler, exchange, completionHandler);
        return;
      }
      HttpHandlers.executeHandler(identityHandler, exchange, completionHandler);
    } else if (size == 1) {
      HttpHandlers.executeHandler(found.get(0).handler.handler, exchange, completionHandler);
    } else {
      ParsedEncoding max = found.get(0);
      for (int i = 1; i < size; ++i) {
        ParsedEncoding o = found.get(i);
        if (o.compareTo(max) > 0) {
          max = o;
        }
      }
      HttpHandlers.executeHandler(max.handler.handler, exchange, completionHandler);
    }
  }
  @Override
  public void handleRequest(final HttpServerExchange exchange) {
    final HeaderMap requestHeaders = exchange.getRequestHeaders();
    boolean persistentConnection;
    final boolean hasConnectionHeader = requestHeaders.contains(Headers.CONNECTION);
    final boolean hasTransferEncoding = requestHeaders.contains(Headers.TRANSFER_ENCODING);
    final boolean hasContentLength = requestHeaders.contains(Headers.CONTENT_LENGTH);
    if (exchange.isHttp11()) {
      persistentConnection =
          !(hasConnectionHeader
              && new HttpString(requestHeaders.getFirst(Headers.CONNECTION)).equals(Headers.CLOSE));
    } else if (exchange.isHttp10()) {
      persistentConnection = false;
      if (hasConnectionHeader) {
        for (String value : requestHeaders.get(Headers.CONNECTION)) {
          if (Headers.KEEP_ALIVE.equals(new HttpString(value))) {
            persistentConnection = true;
            break;
          }
        }
      }
    } else {
      log.trace("Connection not persistent");
      persistentConnection = false;
    }
    HttpString transferEncoding = Headers.IDENTITY;
    if (hasTransferEncoding) {
      transferEncoding = new HttpString(requestHeaders.getLast(Headers.TRANSFER_ENCODING));
    }
    if (hasTransferEncoding && !transferEncoding.equals(Headers.IDENTITY)) {
      exchange.addRequestWrapper(chunkedStreamSourceChannelWrapper());
    } else if (hasContentLength) {
      final long contentLength;
      try {
        contentLength = Long.parseLong(requestHeaders.get(Headers.CONTENT_LENGTH).getFirst());
      } catch (NumberFormatException e) {
        log.trace("Invalid request due to unparsable content length");
        // content length is bad; invalid request
        exchange.setResponseCode(400);
        exchange.endExchange();
        return;
      }
      if (contentLength == 0L) {
        log.trace("No content, starting next request");
        // no content - immediately start the next request, returning an empty stream for this one
        exchange.addRequestWrapper(emptyStreamSourceChannelWrapper());
        exchange.terminateRequest();
      } else {
        // fixed-length content - add a wrapper for a fixed-length stream
        exchange.addRequestWrapper(fixedLengthStreamSourceChannelWrapper(contentLength));
      }
    } else if (hasTransferEncoding) {
      if (transferEncoding.equals(Headers.IDENTITY)) {
        log.trace("Connection not persistent (no content length and identity transfer encoding)");
        // make it not persistent
        persistentConnection = false;
      }
    } else if (persistentConnection) {
      // no content - immediately start the next request, returning an empty stream for this one
      exchange.terminateRequest();
      exchange.addRequestWrapper(emptyStreamSourceChannelWrapper());
    }

    exchange.setPersistent(persistentConnection);

    // now the response wrapper, to add in the appropriate connection control headers
    exchange.addResponseWrapper(responseWrapper(persistentConnection));
    HttpHandlers.executeHandler(next, exchange);
  }