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;
}
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");
}
}
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;
}
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;
}
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;
}
}
Aggregations