下面列出了 io.netty.handler.codec.http2.DefaultHttp2HeadersFrame #io.netty.handler.codec.http2.Http2HeadersFrame 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void onHeadersRead(ChannelHandlerContext ctx, Http2HeadersFrame headers) {
if (headers.isEndStream()) {
ctx.write(new DefaultHttp2HeadersFrame(headers.headers(), true));
} else {
Http2Headers outHeaders = new DefaultHttp2Headers();
if (headers.headers().contains(EXPECT, CONTINUE)) {
if (headers.headers().contains(EXPECT_FAIL_HEADER)) {
outHeaders.status(
io.netty.handler.codec.http.HttpResponseStatus.EXPECTATION_FAILED.codeAsText());
ctx.write(new DefaultHttp2HeadersFrame(outHeaders, true));
return;
} else {
outHeaders.status(io.netty.handler.codec.http.HttpResponseStatus.CONTINUE.codeAsText());
}
} else {
outHeaders.status(io.netty.handler.codec.http.HttpResponseStatus.OK.codeAsText());
}
CharSequence contentType = headers.headers().get(CONTENT_TYPE);
if (contentType != null) {
outHeaders.add(CONTENT_TYPE, contentType);
}
outHeaders.add(HttpHeaderNames.COOKIE, headers.headers().getAll(HttpHeaderNames.COOKIE));
ctx.write(new DefaultHttp2HeadersFrame(outHeaders));
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (!(msg instanceof Http2Frame)) {
ctx.fireChannelRead(msg);
return;
}
Http2Frame frame = (Http2Frame) msg;
receivedFrames.add(frame);
if (frame instanceof Http2DataFrame) {
Http2DataFrame dataFrame = (Http2DataFrame) frame;
if (dataFrame.isEndStream()) {
Http2HeadersFrame respHeaders = new DefaultHttp2HeadersFrame(
new DefaultHttp2Headers().status("204"), true)
.stream(dataFrame.stream());
ctx.writeAndFlush(respHeaders);
}
}
ReferenceCountUtil.release(frame);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof Http2HeadersFrame){
final Http2HeadersFrame requestHeaders = (Http2HeadersFrame) msg;
final SocketChannel channel = (SocketChannel) ctx.channel()
.parent();
final Http2Headers headers = requestHeaders.headers();
accessLog = new AccessLog()
.address(channel.remoteAddress().getHostString())
.port(channel.localAddress().getPort())
.method(headers.method())
.uri(headers.path())
.protocol(H2_PROTOCOL_NAME);
}
ctx.fireChannelRead(msg);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof Http2HeadersFrame) {
Http2HeadersFrame msgHeader = (Http2HeadersFrame) msg;
if (msgHeader.isEndStream()) {
ByteBuf content = ctx.alloc()
.buffer();
content.writeBytes(RESPONSE_BYTES.duplicate());
Http2Headers headers = new DefaultHttp2Headers().status(HttpResponseStatus.OK.codeAsText());
ctx.write(new DefaultHttp2HeadersFrame(headers).stream(msgHeader.stream()));
ctx.write(new DefaultHttp2DataFrame(content, true).stream(msgHeader.stream()));
}
} else {
super.channelRead(ctx, msg);
}
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Http2Frame frame) throws Exception {
ReferenceCountUtil.retain(frame);
RequestInfo requestInfo = ctx.channel().attr(Http2NetworkClient.REQUEST_INFO).get();
requestInfo.responseFramesCount++;
long time = System.currentTimeMillis() - requestInfo.getStreamSendTime();
if (frame instanceof Http2HeadersFrame) {
http2ClientMetrics.http2StreamRoundTripTime.update(time);
requestInfo.setStreamHeaderFrameReceiveTime(System.currentTimeMillis());
logger.debug("Header Frame received. Time from send: {}ms. Request: {}", time, requestInfo);
} else if (frame instanceof Http2DataFrame) {
logger.debug("Data Frame size: {}. Time from send: {}ms. Request: {}",
((Http2DataFrame) frame).content().readableBytes(), time, requestInfo);
}
if (frame instanceof Http2DataFrame && ((Http2DataFrame) frame).isEndStream()) {
http2ClientMetrics.http2StreamFirstToLastFrameTime.update(time);
http2ClientMetrics.http2ResponseFrameCount.update(requestInfo.responseFramesCount);
logger.debug("All Frame received. Time from send: {}ms. Request: {}", time, requestInfo);
}
ctx.fireChannelRead(frame);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof Http2HeadersFrame) {
onHeadersRead(ctx, (Http2HeadersFrame) msg);
} else if (msg instanceof Http2DataFrame) {
onDataRead(ctx, (Http2DataFrame) msg);
} else {
super.channelRead(ctx, msg);
}
}
/**
* If receive a frame with end-of-stream set, send a pre-canned response.
*/
private static void onHeadersRead(ChannelHandlerContext ctx, Http2HeadersFrame headers)
throws Exception {
if (headers.isEndStream()) {
ByteBuf content = ctx.alloc().buffer();
content.writeBytes(RESPONSE_BYTES.duplicate());
ByteBufUtil.writeAscii(content, " - via HTTP/2");
sendResponse(ctx, content);
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof Http2HeadersFrame) {
onHeadersRead(ctx, (Http2HeadersFrame) msg);
} else if (msg instanceof Http2DataFrame) {
onDataRead(ctx, (Http2DataFrame) msg);
} else {
super.channelRead(ctx, msg);
}
}
/**
* If receive a frame with end-of-stream set, send a pre-canned response.
*/
private static void onHeadersRead(ChannelHandlerContext ctx, Http2HeadersFrame headers)
throws Exception {
if (headers.isEndStream()) {
ByteBuf content = ctx.alloc().buffer();
content.writeBytes(RESPONSE_BYTES.duplicate());
ByteBufUtil.writeAscii(content, " - via HTTP/2");
sendResponse(ctx, headers.stream(), content);
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof Http2HeadersFrame) {
onHeadersRead(ctx, (Http2HeadersFrame) msg);
} else if (msg instanceof Http2DataFrame) {
onDataRead(ctx, (Http2DataFrame) msg);
} else {
super.channelRead(ctx, msg);
}
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Http2Frame frame) throws Exception {
if (frame instanceof Http2DataFrame) {
onDataRead((Http2DataFrame) frame, ctx);
} else if (frame instanceof Http2HeadersFrame) {
onHeadersRead((Http2HeadersFrame) frame, ctx);
ctx.channel().read();
} else if (frame instanceof Http2ResetFrame) {
onRstStreamRead((Http2ResetFrame) frame, ctx);
} else {
// TODO this is related to the inbound window update bug. Revisit
ctx.channel().parent().read();
}
}
private void onHeadersRead(Http2HeadersFrame headersFrame, ChannelHandlerContext ctx) throws Http2Exception {
HttpResponse httpResponse = HttpConversionUtil.toHttpResponse(headersFrame.stream().id(), headersFrame.headers(), true);
ctx.fireChannelRead(httpResponse);
if (HttpStatusFamily.of(httpResponse.status().code()) == HttpStatusFamily.SERVER_ERROR) {
fireConnectionExceptionForServerError(ctx);
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (!(msg instanceof Http2Frame)) {
ctx.fireChannelRead(msg);
return;
}
Http2Frame frame = (Http2Frame) msg;
if (frame instanceof Http2DataFrame) {
Http2DataFrame dataFrame = (Http2DataFrame) frame;
ReferenceCountUtil.release(frame);
if (dataFrame.isEndStream()) {
Http2HeadersFrame respHeaders = new DefaultHttp2HeadersFrame(
new DefaultHttp2Headers().status("204"), true)
.stream(dataFrame.stream());
ctx.writeAndFlush(respHeaders);
}
if (sleeps > 0) {
--sleeps;
// Simulate a server that's slow to read data. Since our
// window size is equal to the max frame size, the client
// shouldn't be able to send more data until we update our
// window
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
ctx.writeAndFlush(new DefaultHttp2WindowUpdateFrame(dataFrame.initialFlowControlledBytes())
.stream(dataFrame.stream()));
}
}
@Override
@SuppressWarnings("FutureReturnValueIgnored")
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
boolean lastContent = false;
if (msg instanceof Http2HeadersFrame) {
final Http2HeadersFrame responseHeaders = (Http2HeadersFrame) msg;
final Http2Headers headers = responseHeaders.headers();
lastContent = responseHeaders.isEndStream();
accessLog.status(headers.status())
.chunked(true);
}
if (msg instanceof Http2DataFrame) {
final Http2DataFrame data = (Http2DataFrame) msg;
lastContent = data.isEndStream();
accessLog.increaseContentLength(data.content().readableBytes());
}
if (lastContent) {
ctx.write(msg, promise.unvoid())
.addListener(future -> {
if (future.isSuccess()) {
accessLog.log();
}
});
return;
}
//"FutureReturnValueIgnored" this is deliberate
ctx.write(msg, promise);
}
private boolean isEndOfRequestResponse(Object msg)
{
if (msg instanceof Http2HeadersFrame) {
return ((Http2HeadersFrame) msg).isEndStream();
}
if (msg instanceof Http2DataFrame) {
return ((Http2DataFrame) msg).isEndStream();
}
return false;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof Http2HeadersFrame) {
Http2HeadersFrame headersFrame = (Http2HeadersFrame) msg;
Http2Headers h2Headers = headersFrame.headers();
final HttpResponseStatus httpStatus;
if (!readHeaders) {
CharSequence status = h2Headers.getAndRemove(STATUS.value());
if (status == null) {
throw new IllegalArgumentException("a response must have " + STATUS + " header");
}
httpStatus = HttpResponseStatus.of(status);
if (httpStatus.statusClass().equals(INFORMATIONAL_1XX)) {
// We don't expose 1xx "interim responses" [2] to the user, and discard them to make way for the
// "real" response.
//
// for a response only, zero or more HEADERS frames (each followed
// by zero or more CONTINUATION frames) containing the message
// headers of informational (1xx) HTTP responses. [1]
// A client MUST be able to parse one or more 1xx responses received
// prior to a final response, even if the client does not expect one. A
// user agent MAY ignore unexpected 1xx responses. [2]
// 1xx responses are terminated by the first empty line after
// the status-line (the empty line signaling the end of the header
// section). [2]
// [1] https://tools.ietf.org/html/rfc7540#section-8.1
// [2] https://tools.ietf.org/html/rfc7231#section-6.2
return;
}
readHeaders = true;
} else {
httpStatus = null;
}
if (headersFrame.isEndStream()) {
if (httpStatus != null) {
fireFullResponse(ctx, h2Headers, httpStatus);
} else {
ctx.fireChannelRead(h2HeadersToH1HeadersClient(h2Headers, null));
}
} else if (httpStatus == null) {
throw new IllegalArgumentException("a response must have " + STATUS + " header");
} else {
StreamingHttpResponse response = newResponse(httpStatus, HTTP_2_0,
h2HeadersToH1HeadersClient(h2Headers, httpStatus), allocator, headersFactory);
ctx.fireChannelRead(response);
}
} else if (msg instanceof Http2DataFrame) {
readDataFrame(ctx, msg);
} else {
ctx.fireChannelRead(msg);
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof Http2HeadersFrame) {
Http2HeadersFrame headersFrame = (Http2HeadersFrame) msg;
Http2Headers h2Headers = headersFrame.headers();
final HttpRequestMethod httpMethod;
final String path;
if (!readHeaders) {
CharSequence method = h2Headers.getAndRemove(METHOD.value());
CharSequence pathSequence = h2Headers.getAndRemove(PATH.value());
if (pathSequence == null || method == null) {
throw new IllegalArgumentException("a request must have " + METHOD + " and " +
PATH + " headers");
}
path = pathSequence.toString();
httpMethod = sequenceToHttpRequestMethod(method);
readHeaders = true;
} else {
httpMethod = null;
path = null;
}
if (headersFrame.isEndStream()) {
if (httpMethod != null) {
fireFullRequest(ctx, h2Headers, httpMethod, path);
} else {
ctx.fireChannelRead(h2TrailersToH1TrailersServer(h2Headers));
}
} else if (httpMethod == null) {
throw new IllegalArgumentException("a request must have " + METHOD + " and " +
PATH + " headers");
} else {
StreamingHttpRequest request = newRequest(httpMethod, path, HTTP_2_0,
h2HeadersToH1HeadersServer(h2Headers, httpMethod), allocator, headersFactory);
ctx.fireChannelRead(request);
}
} else if (msg instanceof Http2DataFrame) {
readDataFrame(ctx, msg);
} else {
ctx.fireChannelRead(msg);
}
}
@Override
protected boolean isResponseHeaders(Object msg)
{
return msg instanceof Http2HeadersFrame;
}