/** * Create a configured instance of {@link RawHttp}. * * @param options configuration options */ public RawHttp(RawHttpOptions options) { this.options = options; this.metadataParser = new HttpMetadataParser(options); }
/** * Parses the HTTP messages' request-line from the given input stream. * * @param inputStream supplying the request-line * @return request-line * @throws IOException if an error occurs while consuming the stream */ public RequestLine parseRequestLine(InputStream inputStream) throws IOException { return buildRequestLine(parseStartLine(inputStream, InvalidHttpRequest::new, options.ignoreLeadingEmptyLine())); }
/** * Parses a HTTP response's status-line. * * @param inputStream providing the status-line * @return the status-line * @throws InvalidHttpResponse if the status-line is invalid * @throws IOException if an error occurs while consuming the stream */ public StatusLine parseStatusLine(InputStream inputStream) throws IOException { return buildStatusLine(parseStartLine(inputStream, InvalidHttpResponse::new, options.ignoreLeadingEmptyLine())); }
/** * 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 response produced by the given stream. * * @param inputStream producing a HTTP response * @param requestLine optional {@link RequestLine} of the request which results in this response. * If provided, it is taken into consideration when deciding whether the response contains * a body. See <a href="https://tools.ietf.org/html/rfc7230#section-3.3">Section 3.3</a> * of RFC-7230 for details. * @return a parsed HTTP response object * @throws InvalidHttpResponse if the response is invalid * @throws IOException if a problem occurs accessing the stream */ public RawHttpResponse<Void> parseResponse(InputStream inputStream, @Nullable RequestLine requestLine) throws IOException { StatusLine statusLine = metadataParser.parseStatusLine(inputStream); RawHttpHeaders headers = metadataParser.parseHeaders(inputStream, (message, lineNumber) -> // add 1 to the line number to correct for the start-line new InvalidHttpResponse(message, lineNumber + 1)); @Nullable BodyReader bodyReader = responseHasBody(statusLine, requestLine) ? createBodyReader(inputStream, statusLine, headers) : null; return new RawHttpResponse<>(null, null, statusLine, headers, bodyReader); }
/** * Parses a HTTP request's request-line. * * @param statusLine the request-line * @return the request-line * @throws InvalidHttpRequest if the request-line is invalid */ public RequestLine parseRequestLine(String statusLine) { return buildRequestLine(statusLine); }
private RawHttpHeaders.Builder buildHeaders( InputStream stream, BiFunction<String, Integer, RuntimeException> createError) throws IOException { RawHttpHeaders.Builder builder = RawHttpHeaders.newBuilderSkippingValidation(); int lineNumber = 1; Map.Entry<String, String> header; while ((header = parseHeaderField(stream, lineNumber, createError)) != null) { builder.with(header.getKey(), header.getValue()); lineNumber++; } return builder; }
public ChunkedBodyParser(HttpMetadataParser metadataParser) { this.metadataParser = metadataParser; this.allowNewLineWithoutReturn = metadataParser.getOptions().allowNewLineWithoutReturn(); }
/** * Parses a HTTP response's status-line. * <p> * This method does not perform validation of characters and is provided for * performance reasons where the status-line is known to be legal. * Prefer to use {@link HttpMetadataParser#parseStatusLine(InputStream)} in case the input cannot be trusted. * * @param statusLine the status-line * @return the status-line * @throws InvalidHttpResponse if the status-line is invalid */ public StatusLine parseStatusLine(String statusLine) { return buildStatusLine(statusLine); }
/** * 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; }
/** * Read the trailer-part. * <p> * This method must only be called after the last chunk has been read via * {@link ChunkedBodyParser#readNextChunk(InputStream)}. * * @param inputStream to read trailer from * @return the trailer part of the message * @throws IOException if an error occurs while reading the stream */ public RawHttpHeaders readTrailer(InputStream inputStream) throws IOException { BiFunction<String, Integer, RuntimeException> errorCreator = (msg, lineNumber) -> new IllegalStateException(msg + " (trailer header)"); try { return metadataParser.parseHeaders(inputStream, errorCreator); } catch (InvalidHttpHeader e) { throw new InvalidHttpHeader(e.getMessage() + " (trailer header)"); } }
int userInfoEnd = hierPart.indexOf('@'); userInfo = (userInfoEnd < 0) ? null : hierPart.substring(0, userInfoEnd); Map.Entry<String, String> hostAndPort = parseHostAndPort( hierPart.substring( (userInfo == null) ? 0 : userInfoEnd + 1,
/** * 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 response produced by the given stream. * * @param inputStream producing a HTTP response * @param requestLine optional {@link RequestLine} of the request which results in this response. * If provided, it is taken into consideration when deciding whether the response contains * a body. See <a href="https://tools.ietf.org/html/rfc7230#section-3.3">Section 3.3</a> * of RFC-7230 for details. * @return a parsed HTTP response object * @throws InvalidHttpResponse if the response is invalid * @throws IOException if a problem occurs accessing the stream */ public RawHttpResponse<Void> parseResponse(InputStream inputStream, @Nullable RequestLine requestLine) throws IOException { StatusLine statusLine = metadataParser.parseStatusLine(inputStream); RawHttpHeaders headers = metadataParser.parseHeaders(inputStream, (message, lineNumber) -> // add 1 to the line number to correct for the start-line new InvalidHttpResponse(message, lineNumber + 1)); @Nullable BodyReader bodyReader = responseHasBody(statusLine, requestLine) ? createBodyReader(inputStream, statusLine, headers) : null; return new RawHttpResponse<>(null, null, statusLine, headers, bodyReader); }
/** * Parses a HTTP request's request-line. * * @param statusLine the request-line * @return the request-line * @throws InvalidHttpRequest if the request-line is invalid */ public RequestLine parseRequestLine(String statusLine) { return buildRequestLine(statusLine); }
private RawHttpHeaders.Builder buildHeaders( InputStream stream, BiFunction<String, Integer, RuntimeException> createError) throws IOException { RawHttpHeaders.Builder builder = RawHttpHeaders.newBuilderSkippingValidation(); int lineNumber = 1; Map.Entry<String, String> header; while ((header = parseHeaderField(stream, lineNumber, createError)) != null) { builder.with(header.getKey(), header.getValue()); lineNumber++; } return builder; }
public ChunkedBodyParser(HttpMetadataParser metadataParser) { this.metadataParser = metadataParser; this.allowNewLineWithoutReturn = metadataParser.getOptions().allowNewLineWithoutReturn(); }
/** * Parses a HTTP response's status-line. * <p> * This method does not perform validation of characters and is provided for * performance reasons where the status-line is known to be legal. * Prefer to use {@link HttpMetadataParser#parseStatusLine(InputStream)} in case the input cannot be trusted. * * @param statusLine the status-line * @return the status-line * @throws InvalidHttpResponse if the status-line is invalid */ public StatusLine parseStatusLine(String statusLine) { return buildStatusLine(statusLine); }
/** * 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; }
/** * Read the trailer-part. * <p> * This method must only be called after the last chunk has been read via * {@link ChunkedBodyParser#readNextChunk(InputStream)}. * * @param inputStream to read trailer from * @return the trailer part of the message * @throws IOException if an error occurs while reading the stream */ public RawHttpHeaders readTrailer(InputStream inputStream) throws IOException { BiFunction<String, Integer, RuntimeException> errorCreator = (msg, lineNumber) -> new IllegalStateException(msg + " (trailer header)"); try { return metadataParser.parseHeaders(inputStream, errorCreator); } catch (InvalidHttpHeader e) { throw new InvalidHttpHeader(e.getMessage() + " (trailer header)"); } }