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

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

Issue 1412243012: Initial implementation of CronetBidirectionalStream. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Helen's comments. Created 4 years, 10 months 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.net;
6
7 import org.chromium.base.Log;
8
9 import java.util.Locale;
10 import java.util.Map;
11
12 import static io.netty.buffer.Unpooled.copiedBuffer;
13 import static io.netty.buffer.Unpooled.unreleasableBuffer;
14 import static io.netty.handler.codec.http.HttpResponseStatus.OK;
15 import static io.netty.handler.logging.LogLevel.INFO;
16
17 import io.netty.buffer.ByteBuf;
18 import io.netty.buffer.ByteBufUtil;
19 import io.netty.channel.ChannelHandlerContext;
20 import io.netty.handler.codec.http2.AbstractHttp2ConnectionHandlerBuilder;
21 import io.netty.handler.codec.http2.DefaultHttp2Headers;
22 import io.netty.handler.codec.http2.Http2ConnectionDecoder;
23 import io.netty.handler.codec.http2.Http2ConnectionEncoder;
24 import io.netty.handler.codec.http2.Http2ConnectionHandler;
25 import io.netty.handler.codec.http2.Http2Exception;
26 import io.netty.handler.codec.http2.Http2Flags;
27 import io.netty.handler.codec.http2.Http2FrameListener;
28 import io.netty.handler.codec.http2.Http2FrameLogger;
29 import io.netty.handler.codec.http2.Http2Headers;
30 import io.netty.handler.codec.http2.Http2Settings;
31 import io.netty.util.CharsetUtil;
32
33 /**
34 * HTTP/2 test handler for Cronet BidirectionalStream tests.
35 */
36 public final class Http2TestHandler extends Http2ConnectionHandler implements Ht tp2FrameListener {
37 // Some Url Paths that have special meaning.
38 public static final String ECHO_ALL_HEADERS_PATH = "/echoallheaders";
39 public static final String ECHO_HEADER_PATH = "/echoheader";
40 public static final String ECHO_METHOD_PATH = "/echomethod";
41 public static final String ECHO_STREAM_PATH = "/echostream";
42 public static final String ECHO_TRAILERS_PATH = "/echotrailers";
43
44 private static final String TAG = "cr_Http2TestHandler";
45 private static final Http2FrameLogger sLogger =
46 new Http2FrameLogger(INFO, Http2TestHandler.class);
47 private static final ByteBuf RESPONSE_BYTES =
48 unreleasableBuffer(copiedBuffer("HTTP/2 Test Server", CharsetUtil.UT F_8));
49 private boolean mEchoStream;
xunjieli 2016/01/27 22:17:10 Seems like this handler can only handle one active
xunjieli 2016/01/27 22:23:24 Also bug here. If first url is echo stream, and th
mef 2016/01/29 00:15:30 Great catch! Currently there are no tests that use
mef 2016/01/29 00:15:30 Done.
50 private Http2Headers mResponseHeaders;
51
52 /**
53 * Builder for HTTP/2 test handler.
54 */
55 public static final class Builder
56 extends AbstractHttp2ConnectionHandlerBuilder<Http2TestHandler, Buil der> {
57 public Builder() {
58 frameLogger(sLogger);
59 }
60
61 @Override
62 public Http2TestHandler build() {
63 return super.build();
64 }
65
66 @Override
67 protected Http2TestHandler build(Http2ConnectionDecoder decoder,
68 Http2ConnectionEncoder encoder, Http2Settings initialSettings) {
69 Http2TestHandler handler = new Http2TestHandler(decoder, encoder, in itialSettings);
70 frameListener(handler);
71 return handler;
72 }
73 }
74
75 private Http2TestHandler(Http2ConnectionDecoder decoder, Http2ConnectionEnco der encoder,
76 Http2Settings initialSettings) {
77 super(decoder, encoder, initialSettings);
78 }
79
80 @Override
81 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) thro ws Exception {
82 super.exceptionCaught(ctx, cause);
83 Log.e(TAG, "An exception was caught", cause);
84 ctx.close();
85 throw new Exception("Exception Caught", cause);
86 }
87
88 private static Http2Headers createResponseHeadersFromRequestHeaders(
89 Http2Headers requestHeaders) {
90 // Create response headers by echoing request headers.
91 Http2Headers responseHeaders = new DefaultHttp2Headers().status(OK.codeA sText());
92 for (Map.Entry<CharSequence, CharSequence> header : requestHeaders) {
93 if (!header.getKey().toString().startsWith(":")) {
94 responseHeaders.add("echo-" + header.getKey(), header.getValue() );
95 }
96 }
97
98 responseHeaders.add("echo-method", requestHeaders.get(":method").toStrin g());
99 return responseHeaders;
100 }
101
102 private static String getEchoAllHeadersResponse(Http2Headers headers) {
103 StringBuilder response = new StringBuilder();
104 for (Map.Entry<CharSequence, CharSequence> header : headers) {
105 response.append(header.getKey() + ": " + header.getValue() + "\r\n") ;
106 }
107 return response.toString();
108 }
109
110 private static String getEchoHeaderResponse(Http2Headers headers) {
111 String[] splitPath = headers.path().toString().split("\\?");
112 if (splitPath.length <= 1) return "Header name not found.";
113
114 String headerName = splitPath[1].toLowerCase(Locale.US);
115 if (headers.get(headerName) == null) return "Header not found:" + header Name;
116
117 return headers.get(headerName).toString();
118 }
119
120 private void doSendResponse(ChannelHandlerContext ctx, int streamId, ByteBuf payload) {
121 // Send a frame for the response status
122 encoder().writeHeaders(ctx, streamId, mResponseHeaders, 0, false, ctx.ne wPromise());
123 encoder().writeData(ctx, streamId, payload, 0, true, ctx.newPromise());
124 ctx.flush();
125 }
126
127 private void doEchoStream(ChannelHandlerContext ctx, int streamId, Http2Head ers headers,
xunjieli 2016/01/27 22:17:10 This method is confusingly named. I was expecting
mef 2016/01/29 00:15:30 Done.
128 int padding, boolean endOfStream) {
129 mEchoStream = true;
130 // Send a frame for the response headers.
131 encoder().writeHeaders(ctx, streamId, mResponseHeaders, 0, endOfStream, ctx.newPromise());
132 ctx.flush();
133 }
134
135 private void doEchoTrailers(ChannelHandlerContext ctx, int streamId) {
136 Http2Headers responseHeaders = new DefaultHttp2Headers().status(OK.codeA sText());
137 encoder().writeHeaders(ctx, streamId, responseHeaders, 0, false, ctx.new Promise());
138 encoder().writeData(ctx, streamId, RESPONSE_BYTES.duplicate(), 0, false, ctx.newPromise());
139 Http2Headers responseTrailers = mResponseHeaders.add("trailer", "value1" , "Value2");
140 encoder().writeHeaders(ctx, streamId, responseTrailers, 0, true, ctx.new Promise());
141 ctx.flush();
142 }
143
144 @Override
145 public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding,
146 boolean endOfStream) throws Http2Exception {
147 int processed = data.readableBytes() + padding;
148 if (mEchoStream) {
149 encoder().writeData(ctx, streamId, data.retain(), 0, endOfStream, ct x.newPromise());
xunjieli 2016/01/27 22:17:10 use doEchoStream? see previous comment.
mef 2016/01/29 00:15:30 Done.
150 ctx.flush();
151 } else if (endOfStream) {
152 doSendResponse(ctx, streamId, data.retain());
153 }
154 return processed;
155 }
156
157 @Override
158 public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Head ers headers,
159 int padding, boolean endOfStream) throws Http2Exception {
160 mResponseHeaders = createResponseHeadersFromRequestHeaders(headers);
161 String path = headers.path().toString();
162 if (path.startsWith(ECHO_STREAM_PATH)) {
163 doEchoStream(ctx, streamId, headers, padding, endOfStream);
164 } else if (path.startsWith(ECHO_TRAILERS_PATH)) {
165 doEchoTrailers(ctx, streamId);
166 } else if (endOfStream) {
167 mResponseHeaders = new DefaultHttp2Headers().status(OK.codeAsText()) ;
168 ByteBuf content = ctx.alloc().buffer();
169 try {
170 if (path.startsWith(ECHO_ALL_HEADERS_PATH)) {
171 ByteBufUtil.writeAscii(content, getEchoAllHeadersResponse(he aders));
172 } else if (path.startsWith(ECHO_HEADER_PATH)) {
173 ByteBufUtil.writeAscii(content, getEchoHeaderResponse(header s));
174 } else if (path.startsWith(ECHO_METHOD_PATH)) {
175 ByteBufUtil.writeAscii(content, headers.method());
176 } else {
177 content.writeBytes(RESPONSE_BYTES.duplicate());
178 ByteBufUtil.writeAscii(content, " - via HTTP/2");
179 }
180 } catch (Exception e) {
181 ByteBufUtil.writeAscii(content, "Exception: " + e.toString());
182 }
183
184 doSendResponse(ctx, streamId, content);
185 }
186 }
187
188 @Override
189 public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Head ers headers,
190 int streamDependency, short weight, boolean exclusive, int padding, boolean endOfStream)
191 throws Http2Exception {
192 onHeadersRead(ctx, streamId, headers, padding, endOfStream);
193 }
194
195 @Override
196 public void onPriorityRead(ChannelHandlerContext ctx, int streamId, int stre amDependency,
197 short weight, boolean exclusive) throws Http2Exception {}
198
199 @Override
200 public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long er rorCode)
201 throws Http2Exception {}
202
203 @Override
204 public void onSettingsAckRead(ChannelHandlerContext ctx) throws Http2Excepti on {}
205
206 @Override
207 public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings )
208 throws Http2Exception {}
209
210 @Override
211 public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2 Exception {}
212
213 @Override
214 public void onPingAckRead(ChannelHandlerContext ctx, ByteBuf data) throws Ht tp2Exception {}
215
216 @Override
217 public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int p romisedStreamId,
218 Http2Headers headers, int padding) throws Http2Exception {}
219
220 @Override
221 public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long e rrorCode,
222 ByteBuf debugData) throws Http2Exception {}
223
224 @Override
225 public void onWindowUpdateRead(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement)
226 throws Http2Exception {}
227
228 @Override
229 public void onUnknownFrame(ChannelHandlerContext ctx, byte frameType, int st reamId,
230 Http2Flags flags, ByteBuf payload) throws Http2Exception {}
231 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698