private static Builder newBuilder(RawHttpHeaders headers, boolean validateHeaders) { Builder builder = new Builder(validateHeaders); for (Map.Entry<String, Header> entry : headers.headersByCapitalizedName.entrySet()) { builder.headersByCapitalizedName.put(entry.getKey(), entry.getValue().unfreeze()); } builder.headerNames.addAll(headers.getHeaderNames()); return builder; }
RawHttpHeaders extensions = hasExtensions ? parseExtensions(inputStream) : emptyRawHttpHeaders();
RawHttpHeaders extensions = hasExtensions ? parseExtensions(inputStream) : emptyRawHttpHeaders();
private RequestLine verifyHost(RequestLine requestLine, RawHttpHeaders.Builder headers) { List<String> hostHeaderValues = headers.get("Host"); URI requestLineUri = requestLine.getUri(); @Nullable String requestLineHost = requestLineUri.getHost(); } else { headers.with("Host", requestLineHost); RequestLine newRequestLine = requestLine.withHost(hostHeaderValues.iterator().next()); headers.overwrite("Host", newRequestLine.getUri().getHost()); return newRequestLine; } catch (IllegalArgumentException e) { int lineNumber = headers.getLineNumberAt("Host", 0); throw new InvalidHttpRequest("Invalid host header: " + e.getMessage(), lineNumber); int lineNumber = headers.getLineNumberAt("Host", 1); throw new InvalidHttpRequest("More than one Host header specified", lineNumber);
RawHttpHeaders trailingHeaders = bodyReader.asChunkedBodyContents() .map(ChunkedBodyContents::getTrailerHeaders) .orElse(emptyRawHttpHeaders()); headers = RawHttpHeaders.newBuilder(response.getHeaders()) .merge(trailingHeaders) .build(); } else { headers = response.getHeaders();
RawHttpHeaders trailingHeaders = bodyReader.asChunkedBodyContents() .map(ChunkedBodyContents::getTrailerHeaders) .orElse(emptyRawHttpHeaders()); if (trailingHeaders.isEmpty()) { headers = request.getHeaders(); } else { headers = RawHttpHeaders.newBuilder(request.getHeaders()) .merge(trailingHeaders) .build();
RawHttpHeaders trailingHeaders = bodyReader.asChunkedBodyContents() .map(ChunkedBodyContents::getTrailerHeaders) .orElse(emptyRawHttpHeaders()); if (trailingHeaders.isEmpty()) { headers = request.getHeaders(); } else { headers = RawHttpHeaders.newBuilder(request.getHeaders()) .merge(trailingHeaders) .build();
RawHttpHeaders trailingHeaders = bodyReader.asChunkedBodyContents() .map(ChunkedBodyContents::getTrailerHeaders) .orElse(emptyRawHttpHeaders()); headers = RawHttpHeaders.newBuilder(response.getHeaders()) .merge(trailingHeaders) .build(); } else { headers = response.getHeaders();
private RequestLine verifyHost(RequestLine requestLine, RawHttpHeaders.Builder headers) { List<String> hostHeaderValues = headers.get("Host"); URI requestLineUri = requestLine.getUri(); @Nullable String requestLineHost = requestLineUri.getHost(); } else { headers.with("Host", requestLineHost); RequestLine newRequestLine = requestLine.withHost(hostHeaderValues.iterator().next()); headers.overwrite("Host", newRequestLine.getUri().getHost()); return newRequestLine; } catch (IllegalArgumentException e) { int lineNumber = headers.getLineNumberAt("Host", 0); throw new InvalidHttpRequest("Invalid host header: " + e.getMessage(), lineNumber); int lineNumber = headers.getLineNumberAt("Host", 1); throw new InvalidHttpRequest("More than one Host header specified", lineNumber);
/** * Parses the HTTP request produced by the given stream. * * @param inputStream producing a HTTP request * @param senderAddress the address of the request sender, if known * @return a parsed HTTP request object * @throws InvalidHttpRequest if the request is invalid * @throws IOException if a problem occurs accessing the stream */ public RawHttpRequest parseRequest(InputStream inputStream, @Nullable InetAddress senderAddress) throws IOException { RequestLine requestLine = metadataParser.parseRequestLine(inputStream); RawHttpHeaders originalHeaders = metadataParser.parseHeaders(inputStream, (message, lineNumber) -> // add 1 to the line number to correct for the start-line new InvalidHttpRequest(message, lineNumber + 1)); RawHttpHeaders.Builder modifiableHeaders = RawHttpHeaders.newBuilder(originalHeaders); // do a little cleanup to make sure the request is actually valid requestLine = verifyHost(requestLine, modifiableHeaders); RawHttpHeaders headers = modifiableHeaders.build(); @Nullable BodyReader bodyReader = requestHasBody(headers) ? createBodyReader(inputStream, requestLine, headers) : null; return new RawHttpRequest(requestLine, headers, bodyReader, senderAddress); }
/** * Parses the HTTP request produced by the given stream. * * @param inputStream producing a HTTP request * @param senderAddress the address of the request sender, if known * @return a parsed HTTP request object * @throws InvalidHttpRequest if the request is invalid * @throws IOException if a problem occurs accessing the stream */ public RawHttpRequest parseRequest(InputStream inputStream, @Nullable InetAddress senderAddress) throws IOException { RequestLine requestLine = metadataParser.parseRequestLine(inputStream); RawHttpHeaders originalHeaders = metadataParser.parseHeaders(inputStream, (message, lineNumber) -> // add 1 to the line number to correct for the start-line new InvalidHttpRequest(message, lineNumber + 1)); RawHttpHeaders.Builder modifiableHeaders = RawHttpHeaders.newBuilder(originalHeaders); // do a little cleanup to make sure the request is actually valid requestLine = verifyHost(requestLine, modifiableHeaders); RawHttpHeaders headers = modifiableHeaders.build(); @Nullable BodyReader bodyReader = requestHasBody(headers) ? createBodyReader(inputStream, requestLine, headers) : null; return new RawHttpRequest(requestLine, headers, bodyReader, senderAddress); }
/** * Create a new set of headers, adding/replacing the provided headers into this instance. * <p> * Multi-valued headers present in both this and the provided headers are not merged. The provided headers * are guaranteed to be present and have the same values in the returned instance. * * @param headers to add or replace on this. * @return new set of headers containing both this instance's values as well as the provided values */ public RawHttpHeaders and(RawHttpHeaders headers) { Builder builder = RawHttpHeaders.newBuilderSkippingValidation(this); Set<String> visitedNames = new HashSet<>(headers.headerNames.size()); headers.forEach((name, value) -> { String key = toUppercaseAscii(name); boolean isNewKey = visitedNames.add(key); if (isNewKey) { builder.overwrite(name, value); } else { builder.with(name, value); } }); return builder.build(); }
/** * Create a new set of headers, adding/replacing the provided headers into this instance. * <p> * Multi-valued headers present in both this and the provided headers are not merged. The provided headers * are guaranteed to be present and have the same values in the returned instance. * * @param headers to add or replace on this. * @return new set of headers containing both this instance's values as well as the provided values */ public RawHttpHeaders and(RawHttpHeaders headers) { Builder builder = RawHttpHeaders.newBuilderSkippingValidation(this); Set<String> visitedNames = new HashSet<>(headers.headerNames.size()); headers.forEach((name, value) -> { String key = toUppercaseAscii(name); boolean isNewKey = visitedNames.add(key); if (isNewKey) { builder.overwrite(name, value); } else { builder.with(name, value); } }); return builder.build(); }
/** * @param headers headers object to adapt to include this HTTP message body. * @return adjusted headers for this HTTP message body. * The Content-Type and Content-Length headers may be modified to fit a HTTP message * containing this body. If the body is encoded, the Transfer-Encoding header will be set. */ public RawHttpHeaders headersFrom(RawHttpHeaders headers) { RawHttpHeaders.Builder builder = RawHttpHeaders.newBuilder(headers); getContentType().ifPresent(contentType -> builder.overwrite("Content-Type", contentType)); getContentLength().ifPresent(length -> builder.overwrite("Content-Length", Long.toString(length))); Optional.ofNullable(bodyDecoder).ifPresent(decoder -> { if (!decoder.getEncodings().isEmpty()) { builder.overwrite("Transfer-Encoding", String.join(",", decoder.getEncodings())); } }); return builder.build(); }
/** * @param headers headers object to adapt to include this HTTP message body. * @return adjusted headers for this HTTP message body. * The Content-Type and Content-Length headers may be modified to fit a HTTP message * containing this body. If the body is encoded, the Transfer-Encoding header will be set. */ public RawHttpHeaders headersFrom(RawHttpHeaders headers) { RawHttpHeaders.Builder builder = RawHttpHeaders.newBuilder(headers); getContentType().ifPresent(contentType -> builder.overwrite("Content-Type", contentType)); getContentLength().ifPresent(length -> builder.overwrite("Content-Length", Long.toString(length))); Optional.ofNullable(bodyDecoder).ifPresent(decoder -> { if (!decoder.getEncodings().isEmpty()) { builder.overwrite("Transfer-Encoding", String.join(",", decoder.getEncodings())); } }); return builder.build(); }
/** * Parses the HTTP messages' headers from the given input stream. * * @param inputStream supplying the header fields * @param createError error factory - used in case an error is encountered * @return the {@link RawHttpHeaders} * @throws IOException if an error occurs while consuming the stream */ public RawHttpHeaders parseHeaders(InputStream inputStream, BiFunction<String, Integer, RuntimeException> createError) throws IOException { RawHttpHeaders headers = buildHeaders(inputStream, createError).build(); options.getHttpHeadersOptions().getHeadersValidator().accept(headers); return headers; }
/** * Parses the HTTP messages' headers from the given input stream. * * @param inputStream supplying the header fields * @param createError error factory - used in case an error is encountered * @return the {@link RawHttpHeaders} * @throws IOException if an error occurs while consuming the stream */ public RawHttpHeaders parseHeaders(InputStream inputStream, BiFunction<String, Integer, RuntimeException> createError) throws IOException { RawHttpHeaders headers = buildHeaders(inputStream, createError).build(); options.getHttpHeadersOptions().getHeadersValidator().accept(headers); return headers; }
private RawHttpHeaders readHeaders(CloseableHttpResponse response) { Header[] allHeaders = response.getAllHeaders(); RawHttpHeaders.Builder headers = RawHttpHeaders.newBuilder(); for (Header header : allHeaders) { String meta = header.getElements().length > 0 ? ";" + Arrays.stream(header.getElements()) .flatMap(it -> Arrays.stream(it.getParameters()).map(v -> v.getName() + "=" + v.getValue())) .collect(joining(";")) : ""; headers.with(header.getName(), header.getValue() + meta); } return headers.build(); }