类 io.netty.handler.codec.http.FullHttpMessage 源码实例Demo

下面列出了怎么用 io.netty.handler.codec.http.FullHttpMessage 的API类实例代码及写法,或者点击链接到github查看源代码。

源代码1 项目: browserup-proxy   文件: HttpObjectUtil.java

/**
 * Replaces the entity body of the message with the specified contents. Encodes the message contents according to charset in the message's
 * Content-Type header, or uses {@link BrowserUpHttpUtil#DEFAULT_HTTP_CHARSET} if none is specified.
 * <b>Note:</b> If the charset of the message is not supported on this platform, this will throw an {@link java.nio.charset.UnsupportedCharsetException}.
 *
 * TODO: Currently this method only works for FullHttpMessages, since it must modify the Content-Length header; determine if this may be applied to chunked messages as well
 *
 * @param message the HTTP message to manipulate
 * @param newContents the new entity body contents
 * @throws java.nio.charset.UnsupportedCharsetException if the charset in the message is not supported on this platform
 */
public static void replaceTextHttpEntityBody(FullHttpMessage message, String newContents) {
    // get the content type for this message so we can encode the newContents into a byte stream appropriately
    String contentTypeHeader = message.headers().get(HttpHeaderNames.CONTENT_TYPE);

    Charset messageCharset;
    try {
        messageCharset = BrowserUpHttpUtil.readCharsetInContentTypeHeader(contentTypeHeader);
    } catch (UnsupportedCharsetException e) {
        java.nio.charset.UnsupportedCharsetException cause = e.getUnsupportedCharsetExceptionCause() ;
        log.error("Found unsupported character set in Content-Type header '{}' while attempting to replace contents of HTTP message.", contentTypeHeader, cause);

        throw cause;
    }

    if (messageCharset == null) {
        messageCharset = BrowserUpHttpUtil.DEFAULT_HTTP_CHARSET;
        log.warn("No character set declared in HTTP message. Replacing text using default charset {}.", messageCharset);
    }

    byte[] contentBytes = newContents.getBytes(messageCharset);

    replaceBinaryHttpEntityBody(message, contentBytes);
}
 
源代码2 项目: browserup-proxy   文件: HttpObjectUtil.java

/**
 * Extracts the entity body from a FullHttpMessage, according to the character set in the message's Content-Type header. If the Content-Type
 * header is not present or does not specify a charset, assumes the ISO-8859-1 character set (see {@link BrowserUpHttpUtil#DEFAULT_HTTP_CHARSET}).
 *
 * @param httpMessage HTTP message to extract entity body from
 * @return String representation of the entity body
 * @throws java.nio.charset.UnsupportedCharsetException if there is a charset specified in the content-type header, but it is not supported
 */
public static String extractHttpEntityBody(FullHttpMessage httpMessage) {
    Charset charset;
    try {
        charset = getCharsetFromMessage(httpMessage);
    } catch (UnsupportedCharsetException e) {
        // the declared character set is not supported, so it is impossible to decode the contents of the message. log an error and throw an exception
        // to alert the client code.
        java.nio.charset.UnsupportedCharsetException cause = e.getUnsupportedCharsetExceptionCause();

        String contentTypeHeader = HttpHeaders.getHeader(httpMessage, HttpHeaderNames.CONTENT_TYPE);
        log.error("Cannot retrieve text contents of message because HTTP message declares a character set that is not supported on this platform. Content type header: {}.", contentTypeHeader, cause);

        throw cause;
    }

    return extractHttpEntityBody(httpMessage, charset);
}
 

@Override
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
    // only filter when the original HttpRequest comes through. the RequestFilterAdapter is not designed to filter
    // any subsequent HttpContents.
    if (httpObject instanceof HttpRequest) {
        HttpRequest httpRequest = (HttpRequest) httpObject;

        HttpMessageContents contents;
        if (httpObject instanceof FullHttpMessage) {
            FullHttpMessage httpContent = (FullHttpMessage) httpObject;
            contents = new HttpMessageContents(httpContent);
        } else {
            // the HTTP object is not a FullHttpMessage, which means that message contents are not available on this request and cannot be modified.
            contents = null;
        }

        HttpMessageInfo messageInfo = new HttpMessageInfo(originalRequest, ctx, isHttps(), getFullUrl(httpRequest), getOriginalUrl());

        HttpResponse response = requestFilter.filterRequest(httpRequest, contents, messageInfo);
        if (response != null) {
            return response;
        }
    }

    return null;
}
 

@Override
public HttpObject serverToProxyResponse(HttpObject httpObject) {
    // only filter when the original HttpResponse comes through. the ResponseFilterAdapter is not designed to filter
    // any subsequent HttpContents.
    if (httpObject instanceof HttpResponse) {
        HttpResponse httpResponse = (HttpResponse) httpObject;

        HttpMessageContents contents;
        if (httpObject instanceof FullHttpMessage) {
            FullHttpMessage httpContent = (FullHttpMessage) httpObject;
            contents = new HttpMessageContents(httpContent);
        } else {
            // the HTTP object is not a FullHttpMessage, which means that message contents will not be available on this response and cannot be modified.
            contents = null;
        }

        HttpMessageInfo messageInfo = new HttpMessageInfo(originalRequest, ctx, isHttps(), getFullUrl(modifiedHttpRequest), getOriginalUrl());

        responseFilter.filterResponse(httpResponse, contents, messageInfo);
    }

    return super.serverToProxyResponse(httpObject);
}
 

/**
 * Provides translation between HTTP/2 and HTTP header objects while ensuring the stream
 * is in a valid state for additional headers.
 *
 * @param ctx The context for which this message has been received.
 * Used to send informational header if detected.
 * @param stream The stream the {@code headers} apply to
 * @param headers The headers to process
 * @param endOfStream {@code true} if the {@code stream} has received the end of stream flag
 * @param allowAppend
 * <ul>
 * <li>{@code true} if headers will be appended if the stream already exists.</li>
 * <li>if {@code false} and the stream already exists this method returns {@code null}.</li>
 * </ul>
 * @param appendToTrailer
 * <ul>
 * <li>{@code true} if a message {@code stream} already exists then the headers
 * should be added to the trailing headers.</li>
 * <li>{@code false} then appends will be done to the initial headers.</li>
 * </ul>
 * @return The object used to track the stream corresponding to {@code stream}. {@code null} if
 *         {@code allowAppend} is {@code false} and the stream already exists.
 * @throws Http2Exception If the stream id is not in the correct state to process the headers request
 */
protected FullHttpMessage processHeadersBegin(ChannelHandlerContext ctx, Http2Stream stream, Http2Headers headers,
            boolean endOfStream, boolean allowAppend, boolean appendToTrailer) throws Http2Exception {
    FullHttpMessage msg = getMessage(stream);
    boolean release = true;
    if (msg == null) {
        msg = newMessage(stream, headers, validateHttpHeaders, ctx.alloc());
    } else if (allowAppend) {
        release = false;
        HttpConversionUtil.addHttp2ToHttpHeaders(stream.id(), headers, msg, appendToTrailer);
    } else {
        release = false;
        msg = null;
    }

    if (sendDetector.mustSendImmediately(msg)) {
        // Copy the message (if necessary) before sending. The content is not expected to be copied (or used) in
        // this operation but just in case it is used do the copy before sending and the resource may be released
        final FullHttpMessage copy = endOfStream ? null : sendDetector.copyIfNeeded(msg);
        fireChannelRead(ctx, msg, release, stream);
        return copy;
    }

    return msg;
}
 

@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 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);
    }
}
 

@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);
}
 
源代码9 项目: CapturePacket   文件: HttpObjectUtil.java

/**
 * Replaces the entity body of the message with the specified contents. Encodes the message contents according to charset in the message's
 * Content-Type header, or uses {@link BrowserMobHttpUtil#DEFAULT_HTTP_CHARSET} if none is specified.
 * <b>Note:</b> If the charset of the message is not supported on this platform, this will throw an {@link java.nio.charset.UnsupportedCharsetException}.
 *
 * TODO: Currently this method only works for FullHttpMessages, since it must modify the Content-Length header; determine if this may be applied to chunked messages as well
 *
 * @param message the HTTP message to manipulate
 * @param newContents the new entity body contents
 * @throws java.nio.charset.UnsupportedCharsetException if the charset in the message is not supported on this platform
 */
public static void replaceTextHttpEntityBody(FullHttpMessage message, String newContents) {
    // get the content type for this message so we can encode the newContents into a byte stream appropriately
    String contentTypeHeader = message.headers().get(HttpHeaders.Names.CONTENT_TYPE);

    Charset messageCharset;
    try {
        messageCharset = BrowserMobHttpUtil.readCharsetInContentTypeHeader(contentTypeHeader);
    } catch (UnsupportedCharsetException e) {
        java.nio.charset.UnsupportedCharsetException cause = e.getUnsupportedCharsetExceptionCause() ;
        log.error("Found unsupported character set in Content-Type header '{}' while attempting to replace contents of HTTP message.", contentTypeHeader, cause);

        throw cause;
    }

    if (messageCharset == null) {
        messageCharset = BrowserMobHttpUtil.DEFAULT_HTTP_CHARSET;
        log.warn("No character set declared in HTTP message. Replacing text using default charset {}.", messageCharset);
    }

    byte[] contentBytes = newContents.getBytes(messageCharset);

    replaceBinaryHttpEntityBody(message, contentBytes);
}
 
源代码10 项目: CapturePacket   文件: HttpObjectUtil.java

/**
 * Extracts the entity body from a FullHttpMessage, according to the character set in the message's Content-Type header. If the Content-Type
 * header is not present or does not specify a charset, assumes the ISO-8859-1 character set (see {@link BrowserMobHttpUtil#DEFAULT_HTTP_CHARSET}).
 *
 * @param httpMessage HTTP message to extract entity body from
 * @return String representation of the entity body
 * @throws java.nio.charset.UnsupportedCharsetException if there is a charset specified in the content-type header, but it is not supported
 */
public static String extractHttpEntityBody(FullHttpMessage httpMessage) {
    Charset charset;
    try {
        charset = getCharsetFromMessage(httpMessage);
    } catch (UnsupportedCharsetException e) {
        // the declared character set is not supported, so it is impossible to decode the contents of the message. log an error and throw an exception
        // to alert the client code.
        java.nio.charset.UnsupportedCharsetException cause = e.getUnsupportedCharsetExceptionCause();

        String contentTypeHeader = HttpHeaders.getHeader(httpMessage, HttpHeaders.Names.CONTENT_TYPE);
        log.error("Cannot retrieve text contents of message because HTTP message declares a character set that is not supported on this platform. Content type header: {}.", contentTypeHeader, cause);

        throw cause;
    }

    return extractHttpEntityBody(httpMessage, charset);
}
 
源代码11 项目: Dream-Catcher   文件: HttpObjectUtil.java

/**
 * Replaces the entity body of the message with the specified contents. Encodes the message contents according to charset in the message's
 * Content-Type header, or uses {@link BrowserMobHttpUtil#DEFAULT_HTTP_CHARSET} if none is specified.
 * <b>Note:</b> If the charset of the message is not supported on this platform, this will throw an {@link java.nio.charset.UnsupportedCharsetException}.
 *
 * TODO: Currently this method only works for FullHttpMessages, since it must modify the Content-Length header; determine if this may be applied to chunked messages as well
 *
 * @param message the HTTP message to manipulate
 * @param newContents the new entity body contents
 * @throws java.nio.charset.UnsupportedCharsetException if the charset in the message is not supported on this platform
 */
public static void replaceTextHttpEntityBody(FullHttpMessage message, String newContents) {
    // get the content type for this message so we can encode the newContents into a byte stream appropriately
    String contentTypeHeader = message.headers().get(HttpHeaders.Names.CONTENT_TYPE);

    Charset messageCharset;
    try {
        messageCharset = BrowserMobHttpUtil.readCharsetInContentTypeHeader(contentTypeHeader);
    } catch (UnsupportedCharsetException e) {
        java.nio.charset.UnsupportedCharsetException cause = e.getUnsupportedCharsetExceptionCause() ;
        log.error("Found unsupported character set in Content-Type header '{}' while attempting to replace contents of HTTP message.", contentTypeHeader, cause);

        throw cause;
    }

    if (messageCharset == null) {
        messageCharset = BrowserMobHttpUtil.DEFAULT_HTTP_CHARSET;
        log.warn("No character set declared in HTTP message. Replacing text using default charset {}.", messageCharset);
    }

    byte[] contentBytes = newContents.getBytes(messageCharset);

    replaceBinaryHttpEntityBody(message, contentBytes);
}
 
源代码12 项目: Dream-Catcher   文件: HttpObjectUtil.java

/**
 * Extracts the entity body from a FullHttpMessage, according to the character set in the message's Content-Type header. If the Content-Type
 * header is not present or does not specify a charset, assumes the ISO-8859-1 character set (see {@link BrowserMobHttpUtil#DEFAULT_HTTP_CHARSET}).
 *
 * @param httpMessage HTTP message to extract entity body from
 * @return String representation of the entity body
 * @throws java.nio.charset.UnsupportedCharsetException if there is a charset specified in the content-type header, but it is not supported
 */
public static String extractHttpEntityBody(FullHttpMessage httpMessage) {
    Charset charset;
    try {
        charset = getCharsetFromMessage(httpMessage);
    } catch (UnsupportedCharsetException e) {
        // the declared character set is not supported, so it is impossible to decode the contents of the message. log an error and throw an exception
        // to alert the client code.
        java.nio.charset.UnsupportedCharsetException cause = e.getUnsupportedCharsetExceptionCause();

        String contentTypeHeader = HttpHeaders.getHeader(httpMessage, HttpHeaders.Names.CONTENT_TYPE);
        log.error("Cannot retrieve text contents of message because HTTP message declares a character set that is not supported on this platform. Content type header: {}.", contentTypeHeader, cause);

        throw cause;
    }

    return extractHttpEntityBody(httpMessage, charset);
}
 
源代码13 项目: AndroidHttpCapture   文件: HttpObjectUtil.java

/**
 * Replaces the entity body of the message with the specified contents. Encodes the message contents according to charset in the message's
 * Content-Type header, or uses {@link BrowserMobHttpUtil#DEFAULT_HTTP_CHARSET} if none is specified.
 * <b>Note:</b> If the charset of the message is not supported on this platform, this will throw an {@link java.nio.charset.UnsupportedCharsetException}.
 *
 * TODO: Currently this method only works for FullHttpMessages, since it must modify the Content-Length header; determine if this may be applied to chunked messages as well
 *
 * @param message the HTTP message to manipulate
 * @param newContents the new entity body contents
 * @throws java.nio.charset.UnsupportedCharsetException if the charset in the message is not supported on this platform
 */
public static void replaceTextHttpEntityBody(FullHttpMessage message, String newContents) {
    // get the content type for this message so we can encode the newContents into a byte stream appropriately
    String contentTypeHeader = message.headers().get(HttpHeaders.Names.CONTENT_TYPE);

    Charset messageCharset;
    try {
        messageCharset = BrowserMobHttpUtil.readCharsetInContentTypeHeader(contentTypeHeader);
    } catch (UnsupportedCharsetException e) {
        java.nio.charset.UnsupportedCharsetException cause = e.getUnsupportedCharsetExceptionCause() ;
        log.error("Found unsupported character set in Content-Type header '{}' while attempting to replace contents of HTTP message.", contentTypeHeader, cause);

        throw cause;
    }

    if (messageCharset == null) {
        messageCharset = BrowserMobHttpUtil.DEFAULT_HTTP_CHARSET;
        log.warn("No character set declared in HTTP message. Replacing text using default charset {}.", messageCharset);
    }

    byte[] contentBytes = newContents.getBytes(messageCharset);

    replaceBinaryHttpEntityBody(message, contentBytes);
}
 
源代码14 项目: AndroidHttpCapture   文件: HttpObjectUtil.java

/**
 * Extracts the entity body from a FullHttpMessage, according to the character set in the message's Content-Type header. If the Content-Type
 * header is not present or does not specify a charset, assumes the ISO-8859-1 character set (see {@link BrowserMobHttpUtil#DEFAULT_HTTP_CHARSET}).
 *
 * @param httpMessage HTTP message to extract entity body from
 * @return String representation of the entity body
 * @throws java.nio.charset.UnsupportedCharsetException if there is a charset specified in the content-type header, but it is not supported
 */
public static String extractHttpEntityBody(FullHttpMessage httpMessage) {
    Charset charset;
    try {
        charset = getCharsetFromMessage(httpMessage);
    } catch (UnsupportedCharsetException e) {
        // the declared character set is not supported, so it is impossible to decode the contents of the message. log an error and throw an exception
        // to alert the client code.
        java.nio.charset.UnsupportedCharsetException cause = e.getUnsupportedCharsetExceptionCause();

        String contentTypeHeader = HttpHeaders.getHeader(httpMessage, HttpHeaders.Names.CONTENT_TYPE);
        log.error("Cannot retrieve text contents of message because HTTP message declares a character set that is not supported on this platform. Content type header: {}.", contentTypeHeader, cause);

        throw cause;
    }

    return extractHttpEntityBody(httpMessage, charset);
}
 
源代码15 项目: browserup-proxy   文件: HttpObjectUtil.java

/**
 * Replaces an HTTP entity body with the specified binary contents.
 * TODO: Currently this method only works for FullHttpMessages, since it must modify the Content-Length header; determine if this may be applied to chunked messages as well
 *
 * @param message the HTTP message to manipulate
 * @param newBinaryContents the new entity body contents
 */
public static void replaceBinaryHttpEntityBody(FullHttpMessage message, byte[] newBinaryContents) {
    message.content().resetWriterIndex();
    // resize the buffer if needed, since the new message may be longer than the old one
    message.content().ensureWritable(newBinaryContents.length, true);
    message.content().writeBytes(newBinaryContents);

    // update the Content-Length header, since the size may have changed
    message.headers().set(HttpHeaderNames.CONTENT_LENGTH, newBinaryContents.length);
}
 
源代码16 项目: netty-4.1.22   文件: SpdyHttpDecoder.java

/**
 * Creates a new instance with the specified parameters.
 *
 * @param version the protocol version
 * @param maxContentLength the maximum length of the message content.
 *        If the length of the message content exceeds this value,
 *        a {@link TooLongFrameException} will be raised.
 * @param messageMap the {@link Map} used to hold partially received messages.
 * @param validateHeaders {@code true} if http headers should be validated
 */
protected SpdyHttpDecoder(SpdyVersion version, int maxContentLength, Map<Integer,
        FullHttpMessage> messageMap, boolean validateHeaders) {
    if (version == null) {
        throw new NullPointerException("version");
    }
    if (maxContentLength <= 0) {
        throw new IllegalArgumentException(
                "maxContentLength must be a positive integer: " + maxContentLength);
    }
    spdyVersion = version.getVersion();
    this.maxContentLength = maxContentLength;
    this.messageMap = messageMap;
    this.validateHeaders = validateHeaders;
}
 
源代码17 项目: netty-4.1.22   文件: SpdyHttpDecoder.java

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    // Release any outstanding messages from the map
    for (Map.Entry<Integer, FullHttpMessage> entry : messageMap.entrySet()) {
        ReferenceCountUtil.safeRelease(entry.getValue());
    }
    messageMap.clear();
    super.channelInactive(ctx);
}
 
源代码18 项目: netty-4.1.22   文件: SpdyHttpEncoder.java

/**
 * Checks if the given HTTP message should be considered as a last SPDY frame.
 *
 * @param httpMessage check this HTTP message
 * @return whether the given HTTP message should generate a <em>last</em> SPDY frame.
 */
private static boolean isLast(HttpMessage httpMessage) {
    if (httpMessage instanceof FullHttpMessage) {
        FullHttpMessage fullMessage = (FullHttpMessage) httpMessage;
        if (fullMessage.trailingHeaders().isEmpty() && !fullMessage.content().isReadable()) {
            return true;
        }
    }

    return false;
}
 

@Override
public boolean mustSendImmediately(FullHttpMessage msg) {
    if (msg instanceof FullHttpResponse) {
        return ((FullHttpResponse) msg).status().codeClass() == HttpStatusClass.INFORMATIONAL;
    }
    if (msg instanceof FullHttpRequest) {
        return msg.headers().contains(HttpHeaderNames.EXPECT);
    }
    return false;
}
 

@Override
public FullHttpMessage copyIfNeeded(FullHttpMessage msg) {
    if (msg instanceof FullHttpRequest) {
        FullHttpRequest copy = ((FullHttpRequest) msg).replace(Unpooled.buffer(0));
        copy.headers().remove(HttpHeaderNames.EXPECT);
        return copy;
    }
    return null;
}
 

/**
 * The stream is out of scope for the HTTP message flow and will no longer be tracked
 * @param stream The stream to remove associated state with
 * @param release {@code true} to call release on the value if it is present. {@code false} to not call release.
 */
protected final void removeMessage(Http2Stream stream, boolean release) {
    FullHttpMessage msg = stream.removeProperty(messageKey);
    if (release && msg != null) {
        msg.release();
    }
}
 

/**
 * Make {@code message} be the state associated with {@code stream}.
 * @param stream The stream which {@code message} is associated with.
 * @param message The message which contains the HTTP semantics.
 */
protected final void putMessage(Http2Stream stream, FullHttpMessage message) {
    FullHttpMessage previous = stream.setProperty(messageKey, message);
    if (previous != message && previous != null) {
        previous.release();
    }
}
 

/**
 * 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);
    }
}
 

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

private void encodeLastContent(LastHttpContent last, List<Object> out) {
    boolean needFiller = !(last instanceof FullHttpMessage) && last.trailingHeaders().isEmpty();
    if (last.content().isReadable() || needFiller) {
        out.add(new DefaultHttp2DataFrame(last.content().retain(), last.trailingHeaders().isEmpty()));
    }
    if (!last.trailingHeaders().isEmpty()) {
        Http2Headers headers = HttpConversionUtil.toHttp2Headers(last.trailingHeaders(), validateHeaders);
        out.add(new DefaultHttp2HeadersFrame(headers, true));
    }
}
 

private FullHttpMessage newFullMessage(final int id,
                                       final Http2Headers headers,
                                       final ByteBufAllocator alloc) throws Http2Exception {
    return isServer ?
            HttpConversionUtil.toFullHttpRequest(id, headers, alloc, validateHeaders) :
            HttpConversionUtil.toFullHttpResponse(id, headers, alloc, validateHeaders);
}
 

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    if (msg instanceof FullHttpMessage) {
        handle(ctx, connection, listener, (FullHttpMessage) msg);
    } else {
        super.channelRead(ctx, msg);
    }
}
 

@Test
public void clientRequestSingleHeaderNoDataFrames() throws Exception {
    boostrapEnv(1, 1, 1);
    final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
            "/some/path/resource2", true);
    try {
        HttpHeaders httpHeaders = request.headers();
        httpHeaders.set(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), "https");
        httpHeaders.set(HttpHeaderNames.HOST, "example.org");
        httpHeaders.setInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text(), 3);
        httpHeaders.setInt(HttpHeaderNames.CONTENT_LENGTH, 0);
        httpHeaders.setShort(HttpConversionUtil.ExtensionHeaderNames.STREAM_WEIGHT.text(), (short) 16);
        final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("GET")).
                scheme(new AsciiString("https")).authority(new AsciiString("example.org"))
                .path(new AsciiString("/some/path/resource2"));
        runInChannel(clientChannel, new Http2Runnable() {
            @Override
            public void run() throws Http2Exception {
                clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, true, newPromiseClient());
                clientChannel.flush();
            }
        });
        awaitRequests();
        ArgumentCaptor<FullHttpMessage> requestCaptor = ArgumentCaptor.forClass(FullHttpMessage.class);
        verify(serverListener).messageReceived(requestCaptor.capture());
        capturedRequests = requestCaptor.getAllValues();
        assertEquals(request, capturedRequests.get(0));
    } finally {
        request.release();
    }
}
 

@Test
public void clientRequestSingleHeaderCookieSplitIntoMultipleEntries() throws Exception {
    boostrapEnv(1, 1, 1);
    final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
            "/some/path/resource2", true);
    try {
        HttpHeaders httpHeaders = request.headers();
        httpHeaders.set(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), "https");
        httpHeaders.set(HttpHeaderNames.HOST, "example.org");
        httpHeaders.setInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text(), 3);
        httpHeaders.setInt(HttpHeaderNames.CONTENT_LENGTH, 0);
        httpHeaders.set(HttpHeaderNames.COOKIE, "a=b; c=d; e=f");
        httpHeaders.setShort(HttpConversionUtil.ExtensionHeaderNames.STREAM_WEIGHT.text(), (short) 16);
        final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("GET")).
                scheme(new AsciiString("https")).authority(new AsciiString("example.org"))
                .path(new AsciiString("/some/path/resource2"))
                .add(HttpHeaderNames.COOKIE, "a=b")
                .add(HttpHeaderNames.COOKIE, "c=d")
                .add(HttpHeaderNames.COOKIE, "e=f");
        runInChannel(clientChannel, new Http2Runnable() {
            @Override
            public void run() throws Http2Exception {
                clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, true, newPromiseClient());
                clientChannel.flush();
            }
        });
        awaitRequests();
        ArgumentCaptor<FullHttpMessage> requestCaptor = ArgumentCaptor.forClass(FullHttpMessage.class);
        verify(serverListener).messageReceived(requestCaptor.capture());
        capturedRequests = requestCaptor.getAllValues();
        assertEquals(request, capturedRequests.get(0));
    } finally {
        request.release();
    }
}
 
 类方法
 同包方法