@Override public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception { Http2Stream stream = connection.stream(streamId); FullHttpMessage msg = getMessage(stream); if (msg != null) { onRstStreamRead(stream, msg); } ctx.fireExceptionCaught(Http2Exception.streamError(streamId, Http2Error.valueOf(errorCode), "HTTP/2 to HTTP layer caught stream reset")); }
@Override protected InboundHttp2ToHttpAdapter build(Http2Connection connection, int maxContentLength, boolean validateHttpHeaders, boolean propagateSettings) throws Exception { return new InboundHttp2ToHttpAdapter(connection, maxContentLength, validateHttpHeaders, propagateSettings); } }
/** * After HTTP/2 headers have been processed by {@link #processHeadersBegin} this method either * sends the result up the pipeline or retains the message for future processing. * * @param ctx The context for which this message has been received * @param stream The stream the {@code objAccumulator} corresponds to * @param msg The object which represents all headers/data for corresponding to {@code stream} * @param endOfStream {@code true} if this is the last event for the stream */ private void processHeadersEnd(ChannelHandlerContext ctx, Http2Stream stream, FullHttpMessage msg, boolean endOfStream) { if (endOfStream) { // Release if the msg from the map is different from the object being forwarded up the pipeline. fireChannelRead(ctx, msg, getMessage(stream) != msg, stream); } else { putMessage(stream, msg); } }
@Override public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endOfStream) throws Http2Exception { Http2Stream stream = connection.stream(streamId); FullHttpMessage msg = processHeadersBegin(ctx, stream, headers, endOfStream, true, true); if (msg != null) { processHeadersEnd(ctx, stream, msg, endOfStream); } }
FullHttpMessage msg = getMessage(stream); boolean release = true; if (msg == null) { msg = newMessage(stream, headers, validateHttpHeaders, ctx.alloc()); } else if (allowAppend) { release = false; fireChannelRead(ctx, msg, release, stream); return copy;
@Override public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) throws Http2Exception { Http2Stream stream = connection.stream(streamId); FullHttpMessage msg = getMessage(stream); if (msg == null) { throw connectionError(PROTOCOL_ERROR, "Data Frame received for unknown stream id %d", streamId); } ByteBuf content = msg.content(); final int dataReadableBytes = data.readableBytes(); if (content.readableBytes() > maxContentLength - dataReadableBytes) { throw connectionError(INTERNAL_ERROR, "Content length exceeded max of %d for stream id %d", maxContentLength, streamId); } content.writeBytes(data, data.readerIndex(), dataReadableBytes); if (endOfStream) { fireChannelRead(ctx, msg, false, stream); } // All bytes have been processed. return dataReadableBytes + padding; }
/** * Called if a {@code RST_STREAM} is received but we have some data for that stream. */ protected void onRstStreamRead(Http2Stream stream, FullHttpMessage msg) { removeMessage(stream, true); }
@Override public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception { inboundAdapter.onRstStreamRead(ctx, streamId, errorCode); }
@Override public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) throws Http2Exception { return inboundAdapter.onDataRead(ctx, streamId, data, padding, endOfStream); }
@Override public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int streamDependency, short weight, boolean exclusive, int padding, boolean endOfStream) throws Http2Exception { Http2Stream stream = connection.stream(streamId); FullHttpMessage msg = processHeadersBegin(ctx, stream, headers, endOfStream, true, true); if (msg != null) { // Add headers for dependency and weight. // See https://github.com/netty/netty/issues/5866 if (streamDependency != Http2CodecUtil.CONNECTION_STREAM_ID) { msg.headers().setInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_DEPENDENCY_ID.text(), streamDependency); } msg.headers().setShort(HttpConversionUtil.ExtensionHeaderNames.STREAM_WEIGHT.text(), weight); processHeadersEnd(ctx, stream, msg, endOfStream); } }
FullHttpMessage msg = getMessage(stream); boolean release = true; if (msg == null) { msg = newMessage(stream, headers, validateHttpHeaders, ctx.alloc()); } else if (allowAppend) { release = false; fireChannelRead(ctx, msg, release, stream); return copy;
@Override public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) throws Http2Exception { Http2Stream stream = connection.stream(streamId); FullHttpMessage msg = getMessage(stream); if (msg == null) { throw connectionError(PROTOCOL_ERROR, "Data Frame received for unknown stream id %d", streamId); } ByteBuf content = msg.content(); final int dataReadableBytes = data.readableBytes(); if (content.readableBytes() > maxContentLength - dataReadableBytes) { throw connectionError(INTERNAL_ERROR, "Content length exceeded max of %d for stream id %d", maxContentLength, streamId); } content.writeBytes(data, data.readerIndex(), dataReadableBytes); if (endOfStream) { fireChannelRead(ctx, msg, false, stream); } // All bytes have been processed. return dataReadableBytes + padding; }
@Override public void onStreamRemoved(Http2Stream stream) { removeMessage(stream, true); }
@Override public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception { inboundAdapter.onRstStreamRead(ctx, streamId, errorCode); }
@Override public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) throws Http2Exception { return inboundAdapter.onDataRead(ctx, streamId, data, padding, endOfStream); }
@Override public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId, Http2Headers headers, int padding) throws Http2Exception { // A push promise should not be allowed to add headers to an existing stream Http2Stream promisedStream = connection.stream(promisedStreamId); if (headers.status() == null) { // A PUSH_PROMISE frame has no Http response status. // https://tools.ietf.org/html/rfc7540#section-8.2.1 // Server push is semantically equivalent to a server responding to a // request; however, in this case, that request is also sent by the // server, as a PUSH_PROMISE frame. headers.status(OK.codeAsText()); } FullHttpMessage msg = processHeadersBegin(ctx, promisedStream, headers, false, false, false); if (msg == null) { throw connectionError(PROTOCOL_ERROR, "Push Promise Frame received for pre-existing stream id %d", promisedStreamId); } msg.headers().setInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_PROMISE_ID.text(), streamId); msg.headers().setShort(HttpConversionUtil.ExtensionHeaderNames.STREAM_WEIGHT.text(), Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT); processHeadersEnd(ctx, promisedStream, msg, false); }
/** * After HTTP/2 headers have been processed by {@link #processHeadersBegin} this method either * sends the result up the pipeline or retains the message for future processing. * * @param ctx The context for which this message has been received * @param stream The stream the {@code objAccumulator} corresponds to * @param msg The object which represents all headers/data for corresponding to {@code stream} * @param endOfStream {@code true} if this is the last event for the stream */ private void processHeadersEnd(ChannelHandlerContext ctx, Http2Stream stream, FullHttpMessage msg, boolean endOfStream) { if (endOfStream) { // Release if the msg from the map is different from the object being forwarded up the pipeline. fireChannelRead(ctx, msg, getMessage(stream) != msg, stream); } else { putMessage(stream, msg); } }
FullHttpMessage msg = getMessage(stream); boolean release = true; if (msg == null) { msg = newMessage(stream, headers, validateHttpHeaders, ctx.alloc()); } else if (allowAppend) { release = false; fireChannelRead(ctx, msg, release, stream); return copy;
@Override public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception { Http2Stream stream = connection.stream(streamId); FullHttpMessage msg = getMessage(stream); if (msg != null) { onRstStreamRead(stream, msg); } ctx.fireExceptionCaught(Http2Exception.streamError(streamId, Http2Error.valueOf(errorCode), "HTTP/2 to HTTP layer caught stream reset")); }
@Override public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) throws Http2Exception { Http2Stream stream = connection.stream(streamId); FullHttpMessage msg = getMessage(stream); if (msg == null) { throw connectionError(PROTOCOL_ERROR, "Data Frame received for unknown stream id %d", streamId); } ByteBuf content = msg.content(); final int dataReadableBytes = data.readableBytes(); if (content.readableBytes() > maxContentLength - dataReadableBytes) { throw connectionError(INTERNAL_ERROR, "Content length exceeded max of %d for stream id %d", maxContentLength, streamId); } content.writeBytes(data, data.readerIndex(), dataReadableBytes); if (endOfStream) { fireChannelRead(ctx, msg, false, stream); } // All bytes have been processed. return dataReadableBytes + padding; }