@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); }