private static RequestHandler wrapHandlerIfFormPost(RequestHandler requestHandler, HttpServletRequest servletRequest, boolean removeBodyForFormPost) { if (!servletRequest.getMethod().equals("POST")) { return requestHandler; } String contentType = servletRequest.getHeader(HttpHeaders.Names.CONTENT_TYPE); if (contentType == null) { return requestHandler; } if (!contentType.startsWith(APPLICATION_X_WWW_FORM_URLENCODED)) { return requestHandler; } return new FormPostRequestHandler(requestHandler, getCharsetName(contentType), removeBodyForFormPost); }
@Override public ContentChannel handleRequest(final Request request, final ResponseHandler responseHandler) { Preconditions.checkArgument(request instanceof HttpRequest, "Expected HttpRequest, got " + request); Objects.requireNonNull(responseHandler, "responseHandler"); this.contentCharset = getCharsetByName(contentCharsetName); this.responseHandler = responseHandler; this.request = (HttpRequest) request; this.requestReference = request.refer(); return this; }
/** * Parses application/x-www-form-urlencoded data into a map of parameters. * * @param formContent raw form content data (body) * @return map of decoded parameters */ private static Map<String, List<String>> parseFormParameters(final String formContent) { if (formContent.isEmpty()) { return Collections.emptyMap(); } final Map<String, List<String>> parameterMap = new HashMap<>(); final String[] params = formContent.split("&"); for (final String param : params) { final String[] parts = param.split("="); final String paramName = urlDecode(parts[0]); final String paramValue = parts.length > 1 ? urlDecode(parts[1]) : ""; List<String> currentValues = parameterMap.get(paramName); if (currentValues == null) { currentValues = new LinkedList<>(); parameterMap.put(paramName, currentValues); } currentValues.add(paramValue); } return parameterMap; }
@SuppressWarnings("try") @Override public void close(final CompletionHandler completionHandler) { try (final ResourceReference ref = requestReference) { final byte[] requestContentBytes = accumulatedRequestContent.toByteArray(); final String content = new String(requestContentBytes, contentCharset); completionHandler.completed(); final Map<String, List<String>> parameterMap = parseFormParameters(content); mergeParameters(parameterMap, request.parameters()); final ContentChannel contentChannel = delegateHandler.handleRequest(request, responseHandler); if (contentChannel != null) { if (!removeBody) { final ByteBuffer byteBuffer = ByteBuffer.wrap(requestContentBytes); contentChannel.write(byteBuffer, NOOP_COMPLETION_HANDLER); } contentChannel.close(NOOP_COMPLETION_HANDLER); } } }