List of usage examples for io.netty.handler.codec.http HttpExpectationFailedEvent INSTANCE
HttpExpectationFailedEvent INSTANCE
To view the source code for io.netty.handler.codec.http HttpExpectationFailedEvent INSTANCE.
Click Source Link
From source file:cn.wantedonline.puppy.httpserver.component.HttpObjectAggregator.java
License:Apache License
@Override protected void decode(final ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception { AggregatedFullHttpMessage currentMessage = this.currentMessage; if (msg instanceof HttpMessage) { tooLongFrameFound = false;/* w w w .j ava 2 s . c om*/ assert currentMessage == null; HttpMessage m = (HttpMessage) msg; // Handle the 'Expect: 100-continue' header if necessary. if (is100ContinueExpected(m)) { if (HttpHeaders.getContentLength(m, 0) > maxContentLength) { tooLongFrameFound = true; final ChannelFuture future = ctx.writeAndFlush(EXPECTATION_FAILED.duplicate().retain()); future.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { ctx.fireExceptionCaught(future.cause()); } } }); if (closeOnExpectationFailed) { future.addListener(ChannelFutureListener.CLOSE); } ctx.pipeline().fireUserEventTriggered(HttpExpectationFailedEvent.INSTANCE); return; } ctx.writeAndFlush(CONTINUE.duplicate().retain()).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { ctx.fireExceptionCaught(future.cause()); } } }); } if (!m.getDecoderResult().isSuccess()) { removeTransferEncodingChunked(m); out.add(toFullMessage(m)); this.currentMessage = null; return; } if (msg instanceof HttpRequest) { HttpRequest header = (HttpRequest) msg; this.currentMessage = currentMessage = new AggregatedFullHttpRequest(header, ctx.alloc().compositeBuffer(maxCumulationBufferComponents), null); } else if (msg instanceof HttpResponse) { HttpResponse header = (HttpResponse) msg; this.currentMessage = currentMessage = new AggregatedFullHttpResponse(header, Unpooled.compositeBuffer(maxCumulationBufferComponents), null); } else { throw new Error(); } // A streamed message - initialize the cumulative buffer, and wait for incoming chunks. removeTransferEncodingChunked(currentMessage); } else if (msg instanceof HttpContent) { if (tooLongFrameFound) { if (msg instanceof LastHttpContent) { this.currentMessage = null; } // already detect the too long frame so just discard the content return; } assert currentMessage != null; // Merge the received chunk into the content of the current message. HttpContent chunk = (HttpContent) msg; CompositeByteBuf content = (CompositeByteBuf) currentMessage.content(); if (content.readableBytes() > maxContentLength - chunk.content().readableBytes()) { tooLongFrameFound = true; // release current message to prevent leaks currentMessage.release(); this.currentMessage = null; throw new TooLongFrameException("HTTP content length exceeded " + maxContentLength + " bytes."); } // Append the content of the chunk if (chunk.content().isReadable()) { chunk.retain(); content.addComponent(chunk.content()); content.writerIndex(content.writerIndex() + chunk.content().readableBytes()); } final boolean last; if (!chunk.getDecoderResult().isSuccess()) { currentMessage.setDecoderResult(DecoderResult.failure(chunk.getDecoderResult().cause())); last = true; } else { last = chunk instanceof LastHttpContent; } if (last) { this.currentMessage = null; // Merge trailing headers into the message. if (chunk instanceof LastHttpContent) { LastHttpContent trailer = (LastHttpContent) chunk; currentMessage.setTrailingHeaders(trailer.trailingHeaders()); } else { currentMessage.setTrailingHeaders(new DefaultHttpHeaders()); } // Set the 'Content-Length' header. If one isn't already set. // This is important as HEAD responses will use a 'Content-Length' header which // does not match the actual body, but the number of bytes that would be // transmitted if a GET would have been used. // // See rfc2616 14.13 Content-Length if (!isContentLengthSet(currentMessage)) { currentMessage.headers().set(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(content.readableBytes())); } // All done out.add(currentMessage); } } else { throw new Error(); } }