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

Side by Side Diff: components/cronet/android/java/src/org/chromium/net/urlconnection/CronetHttpURLConnection.java

Issue 725683002: [Cronet] Initial implementation of HttpURLConnection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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 2014 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.urlconnection;
6
7 import android.os.Handler;
8 import android.os.Looper;
9
10 import org.chromium.net.ExtendedResponseInfo;
11 import org.chromium.net.ResponseInfo;
12 import org.chromium.net.UrlRequest;
13 import org.chromium.net.UrlRequestContext;
14 import org.chromium.net.UrlRequestException;
15 import org.chromium.net.UrlRequestListener;
16
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.net.HttpURLConnection;
20 import java.net.URL;
21 import java.nio.ByteBuffer;
22 import java.util.concurrent.Executor;
23
24 /**
25 * An implementation of HttpURLConnection that uses Cronet to send requests and
26 * receive response. This class inherits a {@code connected} field from the
27 * superclass. That field indicates whether a connection has ever been
28 * attempted.
29 */
30 public class CronetHttpURLConnection extends HttpURLConnection {
31
32 private final UrlRequestContext mUrlRequestContext;
33
34 private UrlRequest mRequest;
35
36 private ResponseInfo mResponseInfo;
37
38 private InputStream mResponseBody;
39
40 protected CronetHttpURLConnection(URL url,
41 UrlRequestContext urlRequestContext) {
42 super(url);
43 mUrlRequestContext = urlRequestContext;
44 }
45
46 /**
47 * Wrapper executor class which posts tasks to current looper.
48 */
49 private static class HandlerThreadExecutor implements Executor {
mef 2014/11/13 19:16:17 Maybe we should consider passing Looper to Async A
50 private final Handler mHandler;
51
52 public HandlerThreadExecutor() {
53 if (Looper.myLooper() == null) {
54 Looper.prepare();
55 }
56 mHandler = new Handler(Looper.myLooper());
57 }
58
59 @Override
60 public void execute(Runnable command) {
61 mHandler.post(command);
62 }
63 }
64
65 /**
66 * Opens a connection to the resource.
67 */
68 @Override
69 public void connect() throws IOException {
70 maybeStartRequest();
71 }
72
73 /**
74 * Releases this connection so that its resources may be either reused or
75 * closed.
76 */
77 @Override
78 public void disconnect() {
79 if (mResponseBody != null) {
80 try {
81 mResponseBody.close();
82 } catch (IOException e) {
83 e.printStackTrace();
84 }
85 }
86 }
87
88 /**
89 * Returns the response message returned by the remote HTTP server.
90 */
91 @Override
92 public String getResponseMessage() {
93 maybeStartRequest();
94 return mResponseInfo.getHttpStatusText();
95 }
96
97 /**
98 * Returns the response code returned by the remote HTTP server.
99 */
100 @Override
101 public int getResponseCode() {
102 maybeStartRequest();
103 return mResponseInfo.getHttpStatusCode();
104 }
105
106 /**
107 * Returns an InputStream for reading data from the resource pointed by this
108 * URLConnection.
109 */
110 @Override
111 public InputStream getInputStream() {
112 maybeStartRequest();
113 return mResponseBody;
114 }
115
116 /**
117 * Adds the given property to the request header.
118 */
119 @Override
120 public final void addRequestProperty(String key, String value) {
mef 2014/11/13 19:16:17 I guess 'add' should allow multiple headers with t
xunjieli 2014/11/13 19:24:11 Yes, that's the desired behavior. But due to a lim
121 setRequestProperty(key, value);
122 }
123
124 /**
125 * Sets the value of the specified request header field.
126 */
127 @Override
128 public final void setRequestProperty(String key, String value) {
129 if (connected) {
130 throw new IllegalStateException(
131 "Cannot set request property after connection is made");
132 }
133 maybeCreateRequest();
134 mRequest.addHeader(key, value);
135 }
136
137 /**
138 * Returns whether this connection uses a proxy server or not.
139 */
140 @Override
141 public boolean usingProxy() {
142 // TODO(xunjieli): implement this.
143 return false;
144 }
145
146 private class CronetUrlRequestListener implements UrlRequestListener {
147
148 public CronetUrlRequestListener() {
149 }
150
151 @Override
152 public void onResponseStarted(UrlRequest request, ResponseInfo info) {
153 mResponseInfo = info;
154 }
155
156 @Override
157 public void onDataReceived(UrlRequest request, ResponseInfo info,
158 ByteBuffer byteBuffer) {
159 mResponseInfo = info;
160 // TODO(xunjieli): handle streaming.
161 mResponseBody = new ByteBufferInputStream(byteBuffer);
mef 2014/11/13 19:16:17 Yeah, this is wrong. You need to copy data from |b
xunjieli 2014/11/13 19:24:11 Acknowledged. Will do.
162 }
163
164 @Override
165 public void onRedirect(UrlRequest request, ResponseInfo info,
166 String newLocationUrl) {
167 // TODO(xunjieli): handle redirect.
168 mResponseInfo = info;
169 }
170
171 @Override
172 public void onSucceeded(UrlRequest request, ExtendedResponseInfo info) {
173 Looper.myLooper().quit();
174 }
175
176 @Override
177 public void onFailed(UrlRequest request, ResponseInfo info,
178 UrlRequestException exception) {
179 // TODO(xunjieli): handle failure.
180 Looper.myLooper().quit();
181 }
182 }
183
184 /**
185 * Maybe starts {@code mRequest}, and waits for it to complete.
186 */
187 private void maybeStartRequest() {
188 if (connected) {
189 return;
190 }
191 maybeCreateRequest();
192 mRequest.start();
193 connected = true;
194 Looper.loop();
mmenke 2014/11/13 19:31:27 Problem: This is noticeable to the embedder, and
195 }
196
197 /**
198 * Maybe creates {@code mRequest} if it is null.
199 */
200 private void maybeCreateRequest() {
201 if (mRequest != null) {
202 return;
203 }
204 mRequest = mUrlRequestContext.createRequest(url.toString(),
205 new CronetUrlRequestListener(), new HandlerThreadExecutor());
206 }
207 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698