Search in sources :

Example 1 with MessageConstraintException

use of org.apache.hc.core5.http.MessageConstraintException in project httpcomponents-core by apache.

the class AbstractMessageParser method parse.

@Override
public T parse(final SessionInputBuffer sessionBuffer, final boolean endOfStream) throws IOException, HttpException {
    Args.notNull(sessionBuffer, "Session input buffer");
    while (this.state != State.COMPLETED) {
        if (this.lineBuf == null) {
            this.lineBuf = new CharArrayBuffer(64);
        } else {
            this.lineBuf.clear();
        }
        final boolean lineComplete = sessionBuffer.readLine(this.lineBuf, endOfStream);
        final int maxLineLen = this.messageConstraints.getMaxLineLength();
        if (maxLineLen > 0 && (this.lineBuf.length() > maxLineLen || (!lineComplete && sessionBuffer.length() > maxLineLen))) {
            throw new MessageConstraintException("Maximum line length limit exceeded");
        }
        if (!lineComplete) {
            break;
        }
        switch(this.state) {
            case READ_HEAD_LINE:
                this.message = parseHeadLine();
                if (this.message != null) {
                    this.state = State.READ_HEADERS;
                }
                break;
            case READ_HEADERS:
                if (this.lineBuf.length() > 0) {
                    final int maxHeaderCount = this.messageConstraints.getMaxHeaderCount();
                    if (maxHeaderCount > 0 && headerBufs.size() >= maxHeaderCount) {
                        throw new MessageConstraintException("Maximum header count exceeded");
                    }
                    parseHeader();
                } else {
                    this.state = State.COMPLETED;
                }
                break;
        }
        if (endOfStream && !sessionBuffer.hasData()) {
            this.state = State.COMPLETED;
        }
    }
    if (this.state == State.COMPLETED) {
        for (final CharArrayBuffer buffer : this.headerBufs) {
            this.message.addHeader(this.lineParser.parseHeader(buffer));
        }
        return this.message;
    }
    return null;
}
Also used : CharArrayBuffer(org.apache.hc.core5.util.CharArrayBuffer) MessageConstraintException(org.apache.hc.core5.http.MessageConstraintException)

Example 2 with MessageConstraintException

use of org.apache.hc.core5.http.MessageConstraintException in project httpcomponents-core by apache.

the class ChunkDecoder method readChunkHead.

private void readChunkHead() throws IOException {
    if (this.lineBuf == null) {
        this.lineBuf = new CharArrayBuffer(32);
    } else {
        this.lineBuf.clear();
    }
    if (this.endOfChunk) {
        if (this.buffer.readLine(this.lineBuf, this.endOfStream)) {
            if (!this.lineBuf.isEmpty()) {
                throw new MalformedChunkCodingException("CRLF expected at end of chunk");
            }
        } else {
            if (this.buffer.length() > 2 || this.endOfStream) {
                throw new MalformedChunkCodingException("CRLF expected at end of chunk");
            }
            return;
        }
        this.endOfChunk = false;
    }
    final boolean lineComplete = this.buffer.readLine(this.lineBuf, this.endOfStream);
    final int maxLineLen = this.http1Config.getMaxLineLength();
    if (maxLineLen > 0 && (this.lineBuf.length() > maxLineLen || (!lineComplete && this.buffer.length() > maxLineLen))) {
        throw new MessageConstraintException("Maximum line length limit exceeded");
    }
    if (lineComplete) {
        int separator = this.lineBuf.indexOf(';');
        if (separator < 0) {
            separator = this.lineBuf.length();
        }
        final String s = this.lineBuf.substringTrimmed(0, separator);
        try {
            this.chunkSize = Long.parseLong(s, 16);
        } catch (final NumberFormatException e) {
            throw new MalformedChunkCodingException("Bad chunk header: " + s);
        }
        this.pos = 0L;
    } else if (this.endOfStream) {
        throw new ConnectionClosedException("Premature end of chunk coded message body: closing chunk expected");
    }
}
Also used : MalformedChunkCodingException(org.apache.hc.core5.http.MalformedChunkCodingException) CharArrayBuffer(org.apache.hc.core5.util.CharArrayBuffer) ConnectionClosedException(org.apache.hc.core5.http.ConnectionClosedException) MessageConstraintException(org.apache.hc.core5.http.MessageConstraintException)

Example 3 with MessageConstraintException

use of org.apache.hc.core5.http.MessageConstraintException in project httpcomponents-core by apache.

the class SessionInputBufferImpl method readLine.

@Override
public boolean readLine(final CharArrayBuffer lineBuffer, final boolean endOfStream) throws IOException {
    setOutputMode();
    // See if there is LF char present in the buffer
    int pos = -1;
    for (int i = buffer().position(); i < buffer().limit(); i++) {
        final int b = buffer().get(i);
        if (b == Chars.LF) {
            pos = i + 1;
            break;
        }
    }
    if (this.maxLineLen > 0) {
        final int currentLen = (pos > 0 ? pos : buffer().limit()) - buffer().position();
        if (currentLen >= this.maxLineLen) {
            throw new MessageConstraintException("Maximum line length limit exceeded");
        }
    }
    if (pos == -1) {
        if (endOfStream && buffer().hasRemaining()) {
            // No more data. Get the rest
            pos = buffer().limit();
        } else {
            // or no more data is expected
            return false;
        }
    }
    final int origLimit = buffer().limit();
    buffer().limit(pos);
    final int requiredCapacity = buffer().limit() - buffer().position();
    // Ensure capacity of len assuming ASCII as the most likely charset
    lineBuffer.ensureCapacity(requiredCapacity);
    if (this.charDecoder == null) {
        if (buffer().hasArray()) {
            final byte[] b = buffer().array();
            final int off = buffer().position();
            final int len = buffer().remaining();
            lineBuffer.append(b, buffer().arrayOffset() + off, len);
            buffer().position(off + len);
        } else {
            while (buffer().hasRemaining()) {
                lineBuffer.append((char) (buffer().get() & 0xff));
            }
        }
    } else {
        if (this.charbuffer == null) {
            this.charbuffer = CharBuffer.allocate(this.lineBuffersize);
        }
        this.charDecoder.reset();
        for (; ; ) {
            final CoderResult result = this.charDecoder.decode(buffer(), this.charbuffer, true);
            if (result.isError()) {
                result.throwException();
            }
            if (result.isOverflow()) {
                this.charbuffer.flip();
                lineBuffer.append(this.charbuffer.array(), this.charbuffer.arrayOffset() + this.charbuffer.position(), this.charbuffer.remaining());
                this.charbuffer.clear();
            }
            if (result.isUnderflow()) {
                break;
            }
        }
        // flush the decoder
        this.charDecoder.flush(this.charbuffer);
        this.charbuffer.flip();
        // append the decoded content to the line buffer
        if (this.charbuffer.hasRemaining()) {
            lineBuffer.append(this.charbuffer.array(), this.charbuffer.arrayOffset() + this.charbuffer.position(), this.charbuffer.remaining());
        }
    }
    buffer().limit(origLimit);
    // discard LF if found
    int l = lineBuffer.length();
    if (l > 0) {
        if (lineBuffer.charAt(l - 1) == Chars.LF) {
            l--;
            lineBuffer.setLength(l);
        }
        // discard CR if found
        if (l > 0 && lineBuffer.charAt(l - 1) == Chars.CR) {
            l--;
            lineBuffer.setLength(l);
        }
    }
    return true;
}
Also used : MessageConstraintException(org.apache.hc.core5.http.MessageConstraintException) CoderResult(java.nio.charset.CoderResult)

Example 4 with MessageConstraintException

use of org.apache.hc.core5.http.MessageConstraintException in project httpcomponents-core by apache.

the class AbstractMessageParser method parseHeaders.

/**
 * Parses HTTP headers from the data receiver stream according to the generic
 * format as specified by the HTTP/1.1 protocol specification.
 *
 * @param inBuffer Session input buffer
 * @param inputStream Input stream
 * @param maxHeaderCount maximum number of headers allowed. If the number
 *  of headers received from the data stream exceeds maxCount value, an
 *  IOException will be thrown. Setting this parameter to a negative value
 *  or zero will disable the check.
 * @param maxLineLen maximum number of characters for a header line,
 *  including the continuation lines. Setting this parameter to a negative
 *  value or zero will disable the check.
 * @param parser line parser to use.
 * @param headerLines List of header lines. This list will be used to store
 *   intermediate results. This makes it possible to resume parsing of
 *   headers in case of a {@link java.io.InterruptedIOException}.
 *
 * @return array of HTTP headers
 *
 * @throws IOException in case of an I/O error
 * @throws HttpException in case of HTTP protocol violation
 *
 * @since 4.1
 */
public static Header[] parseHeaders(final SessionInputBuffer inBuffer, final InputStream inputStream, final int maxHeaderCount, final int maxLineLen, final LineParser parser, final List<CharArrayBuffer> headerLines) throws HttpException, IOException {
    Args.notNull(inBuffer, "Session input buffer");
    Args.notNull(inputStream, "Input stream");
    Args.notNull(parser, "Line parser");
    Args.notNull(headerLines, "Header line list");
    CharArrayBuffer current = null;
    CharArrayBuffer previous = null;
    for (; ; ) {
        if (current == null) {
            current = new CharArrayBuffer(64);
        } else {
            current.clear();
        }
        final int readLen = inBuffer.readLine(current, inputStream);
        if (readLen == -1 || current.length() < 1) {
            break;
        }
        // discussion on folded headers
        if ((current.charAt(0) == ' ' || current.charAt(0) == '\t') && previous != null) {
            // we have continuation folded header
            // so append value
            int i = 0;
            while (i < current.length()) {
                final char ch = current.charAt(i);
                if (ch != ' ' && ch != '\t') {
                    break;
                }
                i++;
            }
            if (maxLineLen > 0 && previous.length() + 1 + current.length() - i > maxLineLen) {
                throw new MessageConstraintException("Maximum line length limit exceeded");
            }
            previous.append(' ');
            previous.append(current, i, current.length() - i);
        } else {
            headerLines.add(current);
            previous = current;
            current = null;
        }
        if (maxHeaderCount > 0 && headerLines.size() >= maxHeaderCount) {
            throw new MessageConstraintException("Maximum header count exceeded");
        }
    }
    final Header[] headers = new Header[headerLines.size()];
    for (int i = 0; i < headerLines.size(); i++) {
        final CharArrayBuffer buffer = headerLines.get(i);
        headers[i] = parser.parseHeader(buffer);
    }
    return headers;
}
Also used : Header(org.apache.hc.core5.http.Header) CharArrayBuffer(org.apache.hc.core5.util.CharArrayBuffer) MessageConstraintException(org.apache.hc.core5.http.MessageConstraintException)

Example 5 with MessageConstraintException

use of org.apache.hc.core5.http.MessageConstraintException in project httpcomponents-core by apache.

the class AbstractMessageParser method parseHeader.

private void parseHeader() throws IOException {
    final CharArrayBuffer current = this.lineBuf;
    final int count = this.headerBufs.size();
    if ((this.lineBuf.charAt(0) == ' ' || this.lineBuf.charAt(0) == '\t') && count > 0) {
        // Handle folded header line
        final CharArrayBuffer previous = this.headerBufs.get(count - 1);
        int i = 0;
        while (i < current.length()) {
            final char ch = current.charAt(i);
            if (ch != ' ' && ch != '\t') {
                break;
            }
            i++;
        }
        final int maxLineLen = this.messageConstraints.getMaxLineLength();
        if (maxLineLen > 0 && previous.length() + 1 + current.length() - i > maxLineLen) {
            throw new MessageConstraintException("Maximum line length limit exceeded");
        }
        previous.append(' ');
        previous.append(current, i, current.length() - i);
    } else {
        this.headerBufs.add(current);
        this.lineBuf = null;
    }
}
Also used : CharArrayBuffer(org.apache.hc.core5.util.CharArrayBuffer) MessageConstraintException(org.apache.hc.core5.http.MessageConstraintException)

Aggregations

MessageConstraintException (org.apache.hc.core5.http.MessageConstraintException)7 CharArrayBuffer (org.apache.hc.core5.util.CharArrayBuffer)6 CoderResult (java.nio.charset.CoderResult)1 ConnectionClosedException (org.apache.hc.core5.http.ConnectionClosedException)1 Header (org.apache.hc.core5.http.Header)1 MalformedChunkCodingException (org.apache.hc.core5.http.MalformedChunkCodingException)1 TruncatedChunkException (org.apache.hc.core5.http.TruncatedChunkException)1