|
|
|
@ -342,33 +342,23 @@ final class MultipartParser extends BaseSubscriber<DataBuffer> { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* First checks whether the multipart boundary leading to this state |
|
|
|
* First checks whether the multipart boundary leading to this state |
|
|
|
* was the final boundary, or whether {@link #maxHeadersSize} is |
|
|
|
* was the final boundary. Then looks for the header-body boundary |
|
|
|
* exceeded. Then looks for the header-body boundary |
|
|
|
* ({@code CR LF CR LF}) in the given buffer. If found, checks whether |
|
|
|
* ({@code CR LF CR LF}) in the given buffer. If found, convert |
|
|
|
* the size of all header buffers does not exceed {@link #maxHeadersSize}, |
|
|
|
* all buffers collected so far into a {@link HttpHeaders} object |
|
|
|
* converts all buffers collected so far into a {@link HttpHeaders} object |
|
|
|
* and changes to {@link BodyState}, passing the remainder of the |
|
|
|
* and changes to {@link BodyState}, passing the remainder of the |
|
|
|
* buffer. If the boundary is not found, the buffer is collected. |
|
|
|
* buffer. If the boundary is not found, the buffer is collected if |
|
|
|
|
|
|
|
* its size does not exceed {@link #maxHeadersSize}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void onNext(DataBuffer buf) { |
|
|
|
public void onNext(DataBuffer buf) { |
|
|
|
long prevCount = this.byteCount.get(); |
|
|
|
if (isLastBoundary(buf)) { |
|
|
|
long count = this.byteCount.addAndGet(buf.readableByteCount()); |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
if (prevCount < 2 && count >= 2) { |
|
|
|
logger.trace("Last boundary found in " + buf); |
|
|
|
if (isLastBoundary(buf)) { |
|
|
|
|
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
|
|
|
|
logger.trace("Last boundary found in " + buf); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (changeState(this, DisposedState.INSTANCE, buf)) { |
|
|
|
|
|
|
|
emitComplete(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else if (count > MultipartParser.this.maxHeadersSize) { |
|
|
|
|
|
|
|
if (changeState(this, DisposedState.INSTANCE, buf)) { |
|
|
|
if (changeState(this, DisposedState.INSTANCE, buf)) { |
|
|
|
emitError(new DataBufferLimitException("Part headers exceeded the memory usage limit of " + |
|
|
|
emitComplete(); |
|
|
|
MultipartParser.this.maxHeadersSize + " bytes")); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -377,17 +367,23 @@ final class MultipartParser extends BaseSubscriber<DataBuffer> { |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
if (logger.isTraceEnabled()) { |
|
|
|
logger.trace("End of headers found @" + endIdx + " in " + buf); |
|
|
|
logger.trace("End of headers found @" + endIdx + " in " + buf); |
|
|
|
} |
|
|
|
} |
|
|
|
DataBuffer headerBuf = MultipartUtils.sliceTo(buf, endIdx); |
|
|
|
long count = this.byteCount.addAndGet(endIdx); |
|
|
|
this.buffers.add(headerBuf); |
|
|
|
if (belowMaxHeaderSize(count)) { |
|
|
|
DataBuffer bodyBuf = MultipartUtils.sliceFrom(buf, endIdx); |
|
|
|
DataBuffer headerBuf = MultipartUtils.sliceTo(buf, endIdx); |
|
|
|
DataBufferUtils.release(buf); |
|
|
|
this.buffers.add(headerBuf); |
|
|
|
|
|
|
|
DataBuffer bodyBuf = MultipartUtils.sliceFrom(buf, endIdx); |
|
|
|
emitHeaders(parseHeaders()); |
|
|
|
DataBufferUtils.release(buf); |
|
|
|
changeState(this, new BodyState(), bodyBuf); |
|
|
|
|
|
|
|
|
|
|
|
emitHeaders(parseHeaders()); |
|
|
|
|
|
|
|
changeState(this, new BodyState(), bodyBuf); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
this.buffers.add(buf); |
|
|
|
long count = this.byteCount.addAndGet(buf.readableByteCount()); |
|
|
|
requestBuffer(); |
|
|
|
if (belowMaxHeaderSize(count)) { |
|
|
|
|
|
|
|
this.buffers.add(buf); |
|
|
|
|
|
|
|
requestBuffer(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -407,6 +403,21 @@ final class MultipartParser extends BaseSubscriber<DataBuffer> { |
|
|
|
buf.getByte(0) == HYPHEN); |
|
|
|
buf.getByte(0) == HYPHEN); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Checks whether the given {@code count} is below or equal to {@link #maxHeadersSize} |
|
|
|
|
|
|
|
* and emits a {@link DataBufferLimitException} if not. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private boolean belowMaxHeaderSize(long count) { |
|
|
|
|
|
|
|
if (count <= MultipartParser.this.maxHeadersSize) { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
emitError(new DataBufferLimitException("Part headers exceeded the memory usage limit of " + |
|
|
|
|
|
|
|
MultipartParser.this.maxHeadersSize + " bytes")); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Parses the list of buffers into a {@link HttpHeaders} instance. |
|
|
|
* Parses the list of buffers into a {@link HttpHeaders} instance. |
|
|
|
* Converts the joined buffers into a string using ISO=8859-1, and parses |
|
|
|
* Converts the joined buffers into a string using ISO=8859-1, and parses |
|
|
|
|