Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Unified Diff: components/cronet/android/test/src/org/chromium/net/Http2TestHandler.java

Issue 1529643002: [Cronet] Use prebuilt Netty Http/2 server for Cronet BidirectionalStream testing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bidi_impl_helen8
Patch Set: Sync Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/cronet.gypi ('k') | components/cronet/android/test/src/org/chromium/net/Http2TestServer.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/cronet/android/test/src/org/chromium/net/Http2TestHandler.java
diff --git a/components/cronet/android/test/src/org/chromium/net/Http2TestHandler.java b/components/cronet/android/test/src/org/chromium/net/Http2TestHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..3472d1fe76d8f46bb87996c6196927f401df615c
--- /dev/null
+++ b/components/cronet/android/test/src/org/chromium/net/Http2TestHandler.java
@@ -0,0 +1,199 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.net;
+
+import java.util.Locale;
+import java.util.Map;
+
+import static io.netty.buffer.Unpooled.copiedBuffer;
+import static io.netty.buffer.Unpooled.unreleasableBuffer;
+import static io.netty.handler.codec.http.HttpResponseStatus.OK;
+import static io.netty.handler.logging.LogLevel.INFO;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.http2.DefaultHttp2Headers;
+import io.netty.handler.codec.http2.Http2ConnectionDecoder;
+import io.netty.handler.codec.http2.Http2ConnectionEncoder;
+import io.netty.handler.codec.http2.Http2ConnectionHandler;
+import io.netty.handler.codec.http2.Http2Exception;
+import io.netty.handler.codec.http2.Http2Flags;
+import io.netty.handler.codec.http2.Http2FrameListener;
+import io.netty.handler.codec.http2.Http2FrameLogger;
+import io.netty.handler.codec.http2.Http2Headers;
+import io.netty.handler.codec.http2.Http2Settings;
+import io.netty.util.CharsetUtil;
+
+/**
+ * HTTP/2 test handler for Cronet BidirectionalStream tests.
+ */
+final class Http2TestHandler extends Http2ConnectionHandler implements Http2FrameListener {
+ private static final Http2FrameLogger sLogger =
+ new Http2FrameLogger(INFO, Http2TestHandler.class);
+ private static final ByteBuf RESPONSE_BYTES =
+ unreleasableBuffer(copiedBuffer("HTTP/2 Test Server", CharsetUtil.UTF_8));
+ private boolean mEchoStream = false;
+
+ static final class Builder extends BuilderBase<Http2TestHandler, Builder> {
+ public Builder() {
+ frameLogger(sLogger);
+ }
+
+ @Override
+ public Http2TestHandler build0(
+ Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder) {
+ Http2TestHandler handler = new Http2TestHandler(decoder, encoder, initialSettings());
+ frameListener(handler);
+ return handler;
+ }
+ }
+
+ private Http2TestHandler(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
+ Http2Settings initialSettings) {
+ super(decoder, encoder, initialSettings);
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ super.exceptionCaught(ctx, cause);
+ cause.printStackTrace();
+ ctx.close();
+ }
+
+ private void sendResponse(ChannelHandlerContext ctx, int streamId, ByteBuf payload) {
+ // Send a frame for the response status
+ Http2Headers headers = new DefaultHttp2Headers().status(OK.codeAsText());
+ encoder().writeHeaders(ctx, streamId, headers, 0, false, ctx.newPromise());
+ encoder().writeData(ctx, streamId, payload, 0, true, ctx.newPromise());
+ ctx.flush();
+ }
+
+ @Override
+ public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding,
+ boolean endOfStream) throws Http2Exception {
+ int processed = data.readableBytes() + padding;
+ if (mEchoStream) {
+ encoder().writeData(ctx, streamId, data.retain(), 0, endOfStream, ctx.newPromise());
+ ctx.flush();
+ } else if (endOfStream) {
+ sendResponse(ctx, streamId, data.retain());
+ }
+ return processed;
+ }
+
+ private void doEchoStream(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
+ int padding, boolean endOfStream) {
+ mEchoStream = true;
+ // Send a frame for the response status
+ Http2Headers responseHeaders = new DefaultHttp2Headers().status(OK.codeAsText());
+ responseHeaders.add(headers);
+ encoder().writeHeaders(ctx, streamId, responseHeaders, 0, endOfStream, ctx.newPromise());
+ ctx.flush();
+ }
+
+ private void doEchoTrailers(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
+ int padding, boolean endOfStream) {
+ Http2Headers responseHeaders = new DefaultHttp2Headers().status(OK.codeAsText());
+ encoder().writeHeaders(ctx, streamId, responseHeaders, 0, false, ctx.newPromise());
+ encoder().writeData(ctx, streamId, RESPONSE_BYTES.duplicate(), 0, false, ctx.newPromise());
+ Http2Headers responseTrailers =
+ new DefaultHttp2Headers().add("trailer", "value1", "Value2");
+ responseTrailers.add(headers);
+ encoder().writeHeaders(ctx, streamId, responseTrailers, 0, true, ctx.newPromise());
+ ctx.flush();
+ }
+
+ private String getEchoAllHeadersResponse(Http2Headers headers) {
+ StringBuilder response = new StringBuilder();
+ for (Map.Entry<CharSequence, CharSequence> header : headers) {
+ response.append(header.getKey() + ": " + header.getValue() + "\r\n");
+ }
+ return response.toString();
+ }
+
+ private String getEchoHeaderResponse(Http2Headers headers) {
+ String[] split_path = headers.path().toString().split("\\?");
+ if (split_path.length <= 1) return "Header name not found.";
+
+ String header_name = split_path[1].toLowerCase(Locale.US);
+ if (headers.get(header_name) == null) return "Header not found:" + header_name;
+
+ return headers.get(header_name).toString();
+ }
+
+ @Override
+ public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
+ int padding, boolean endOfStream) throws Http2Exception {
+ String path = headers.path().toString();
+ if (path.startsWith("/echostream")) {
+ doEchoStream(ctx, streamId, headers, padding, endOfStream);
+ } else if (path.startsWith("/echotrailers")) {
+ doEchoTrailers(ctx, streamId, headers, padding, endOfStream);
+ } else if (endOfStream) {
+ ByteBuf content = ctx.alloc().buffer();
+ try {
+ if (path.startsWith("/echoallheaders")) {
+ ByteBufUtil.writeAscii(content, getEchoAllHeadersResponse(headers));
+ } else if (path.startsWith("/echoheader")) {
+ ByteBufUtil.writeAscii(content, getEchoHeaderResponse(headers));
+ } else if (path.startsWith("/echomethod")) {
+ ByteBufUtil.writeAscii(content, headers.method());
+ } else {
+ content.writeBytes(RESPONSE_BYTES.duplicate());
+ ByteBufUtil.writeAscii(content, " - via HTTP/2");
+ }
+ } catch (Exception e) {
+ ByteBufUtil.writeAscii(content, "Exception: " + e.toString());
+ }
+
+ sendResponse(ctx, streamId, content);
+ }
+ }
+
+ @Override
+ public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers,
+ int streamDependency, short weight, boolean exclusive, int padding, boolean endOfStream)
+ throws Http2Exception {
+ onHeadersRead(ctx, streamId, headers, padding, endOfStream);
+ }
+
+ @Override
+ public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int streamDependency,
+ short weight, boolean exclusive) throws Http2Exception {}
+
+ @Override
+ public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode)
+ throws Http2Exception {}
+
+ @Override
+ public void onSettingsAckRead(ChannelHandlerContext ctx) throws Http2Exception {}
+
+ @Override
+ public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings)
+ throws Http2Exception {}
+
+ @Override
+ public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {}
+
+ @Override
+ public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {}
+
+ @Override
+ public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId,
+ Http2Headers headers, int padding) throws Http2Exception {}
+
+ @Override
+ public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long errorCode,
+ ByteBuf debugData) throws Http2Exception {}
+
+ @Override
+ public void onWindowUpdateRead(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement)
+ throws Http2Exception {}
+
+ @Override
+ public void onUnknownFrame(ChannelHandlerContext ctx, byte frameType, int streamId,
+ Http2Flags flags, ByteBuf payload) throws Http2Exception {}
+}
« no previous file with comments | « components/cronet.gypi ('k') | components/cronet/android/test/src/org/chromium/net/Http2TestServer.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698