OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.net.urlconnection; | 5 package org.chromium.net.urlconnection; |
6 | 6 |
7 import org.chromium.net.ExtendedResponseInfo; | 7 import org.chromium.net.ExtendedResponseInfo; |
8 import org.chromium.net.ResponseInfo; | 8 import org.chromium.net.ResponseInfo; |
9 import org.chromium.net.UrlRequest; | 9 import org.chromium.net.UrlRequest; |
10 import org.chromium.net.UrlRequestContext; | 10 import org.chromium.net.UrlRequestContext; |
11 import org.chromium.net.UrlRequestException; | 11 import org.chromium.net.UrlRequestException; |
12 import org.chromium.net.UrlRequestListener; | 12 import org.chromium.net.UrlRequestListener; |
13 | 13 |
14 import java.io.IOException; | 14 import java.io.IOException; |
15 import java.io.InputStream; | 15 import java.io.InputStream; |
16 import java.net.HttpURLConnection; | 16 import java.net.HttpURLConnection; |
| 17 import java.net.MalformedURLException; |
17 import java.net.URL; | 18 import java.net.URL; |
18 import java.nio.ByteBuffer; | 19 import java.nio.ByteBuffer; |
19 | 20 |
20 /** | 21 /** |
21 * An implementation of HttpURLConnection that uses Cronet to send requests and | 22 * An implementation of HttpURLConnection that uses Cronet to send requests and |
22 * receive response. This class inherits a {@code connected} field from the | 23 * receive response. This class inherits a {@code connected} field from the |
23 * superclass. That field indicates whether a connection has ever been | 24 * superclass. That field indicates whether a connection has ever been |
24 * attempted. | 25 * attempted. |
25 */ | 26 */ |
26 public class CronetHttpURLConnection extends HttpURLConnection { | 27 public class CronetHttpURLConnection extends HttpURLConnection { |
27 private final UrlRequestContext mUrlRequestContext; | 28 private final UrlRequestContext mUrlRequestContext; |
28 private final MessageLoop mMessageLoop; | 29 private final MessageLoop mMessageLoop; |
29 private final UrlRequest mRequest; | 30 private final UrlRequest mRequest; |
30 | 31 |
31 private CronetInputStream mInputStream; | 32 private CronetInputStream mInputStream; |
32 private ResponseInfo mResponseInfo; | 33 private ResponseInfo mResponseInfo; |
33 private ByteBuffer mResponseByteBuffer; | 34 private ByteBuffer mResponseByteBuffer; |
| 35 private boolean mOnRedirectCalled = false; |
34 | 36 |
35 protected CronetHttpURLConnection(URL url, | 37 protected CronetHttpURLConnection(URL url, |
36 UrlRequestContext urlRequestContext) { | 38 UrlRequestContext urlRequestContext) { |
37 super(url); | 39 super(url); |
38 mUrlRequestContext = urlRequestContext; | 40 mUrlRequestContext = urlRequestContext; |
39 mMessageLoop = new MessageLoop(); | 41 mMessageLoop = new MessageLoop(); |
40 mRequest = mUrlRequestContext.createRequest(url.toString(), | 42 mRequest = mUrlRequestContext.createRequest(url.toString(), |
41 new CronetUrlRequestListener(), mMessageLoop); | 43 new CronetUrlRequestListener(), mMessageLoop); |
42 mInputStream = new CronetInputStream(this); | 44 mInputStream = new CronetInputStream(this); |
43 } | 45 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 return mResponseInfo.getHttpStatusCode(); | 102 return mResponseInfo.getHttpStatusCode(); |
101 } | 103 } |
102 | 104 |
103 /** | 105 /** |
104 * Returns an InputStream for reading data from the resource pointed by this | 106 * Returns an InputStream for reading data from the resource pointed by this |
105 * URLConnection. | 107 * URLConnection. |
106 */ | 108 */ |
107 @Override | 109 @Override |
108 public InputStream getInputStream() throws IOException { | 110 public InputStream getInputStream() throws IOException { |
109 connect(); | 111 connect(); |
| 112 if (mResponseInfo == null) { |
| 113 throw new IOException(); |
| 114 } |
| 115 if (!instanceFollowRedirects && mOnRedirectCalled) { |
| 116 throw new IOException("Cannot read response body of a redirect."); |
| 117 } |
110 return mInputStream; | 118 return mInputStream; |
111 } | 119 } |
112 | 120 |
113 /** | 121 /** |
114 * Adds the given property to the request header. | 122 * Adds the given property to the request header. |
115 */ | 123 */ |
116 @Override | 124 @Override |
117 public final void addRequestProperty(String key, String value) { | 125 public final void addRequestProperty(String key, String value) { |
118 // Note that Cronet right now does not allow setting multiple headers | 126 // Note that Cronet right now does not allow setting multiple headers |
119 // of the same key, see crbug.com/432719 for more details. | 127 // of the same key, see crbug.com/432719 for more details. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 mResponseInfo = info; | 177 mResponseInfo = info; |
170 mResponseByteBuffer = ByteBuffer.allocate(byteBuffer.capacity()); | 178 mResponseByteBuffer = ByteBuffer.allocate(byteBuffer.capacity()); |
171 mResponseByteBuffer.put(byteBuffer); | 179 mResponseByteBuffer.put(byteBuffer); |
172 mResponseByteBuffer.flip(); | 180 mResponseByteBuffer.flip(); |
173 mMessageLoop.postQuitTask(); | 181 mMessageLoop.postQuitTask(); |
174 } | 182 } |
175 | 183 |
176 @Override | 184 @Override |
177 public void onRedirect(UrlRequest request, ResponseInfo info, | 185 public void onRedirect(UrlRequest request, ResponseInfo info, |
178 String newLocationUrl) { | 186 String newLocationUrl) { |
179 // TODO(xunjieli): Handle redirect and test it. | 187 mOnRedirectCalled = true; |
| 188 if (instanceFollowRedirects) { |
| 189 try { |
| 190 url = new URL(newLocationUrl); |
| 191 } catch (MalformedURLException e) { |
| 192 // Ignored. |
| 193 } |
| 194 } else { |
| 195 mResponseInfo = info; |
| 196 mRequest.cancel(); |
| 197 setResponseDataCompleted(); |
| 198 } |
180 } | 199 } |
181 | 200 |
182 @Override | 201 @Override |
183 public void onSucceeded(UrlRequest request, ExtendedResponseInfo info) { | 202 public void onSucceeded(UrlRequest request, ExtendedResponseInfo info) { |
184 mResponseInfo = info.getResponseInfo(); | 203 mResponseInfo = info.getResponseInfo(); |
185 setResponseDataCompleted(); | 204 setResponseDataCompleted(); |
186 } | 205 } |
187 | 206 |
188 @Override | 207 @Override |
189 public void onFailed(UrlRequest request, ResponseInfo info, | 208 public void onFailed(UrlRequest request, ResponseInfo info, |
190 UrlRequestException exception) { | 209 UrlRequestException exception) { |
191 // TODO(xunjieli): Handle failure. | 210 // TODO(xunjieli): Handle failure. |
192 setResponseDataCompleted(); | 211 setResponseDataCompleted(); |
193 } | 212 } |
194 | 213 |
195 /** | 214 /** |
196 * Notifies {@link #mInputStream} that transferring of response data has | 215 * Notifies {@link #mInputStream} that transferring of response data has |
197 * completed. | 216 * completed. |
198 */ | 217 */ |
199 private void setResponseDataCompleted() { | 218 private void setResponseDataCompleted() { |
200 if (mInputStream != null) { | 219 if (mInputStream != null) { |
201 mInputStream.setResponseDataCompleted(); | 220 mInputStream.setResponseDataCompleted(); |
202 } | 221 } |
203 mMessageLoop.postQuitTask(); | 222 mMessageLoop.postQuitTask(); |
204 } | 223 } |
205 } | 224 } |
206 } | 225 } |
OLD | NEW |