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

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

Issue 470443005: Cronet modifications to support AGSA. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Cronet modifications to support AGSA. Created 6 years, 4 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
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; 5 package org.chromium.net;
6 6
7 import android.os.ConditionVariable;
8
7 import org.apache.http.conn.ConnectTimeoutException; 9 import org.apache.http.conn.ConnectTimeoutException;
8 import org.chromium.base.CalledByNative; 10 import org.chromium.base.CalledByNative;
9 import org.chromium.base.JNINamespace; 11 import org.chromium.base.JNINamespace;
10 12
11 import java.io.IOException; 13 import java.io.IOException;
12 import java.net.MalformedURLException; 14 import java.net.MalformedURLException;
13 import java.net.URL; 15 import java.net.URL;
14 import java.net.UnknownHostException; 16 import java.net.UnknownHostException;
15 import java.nio.ByteBuffer; 17 import java.nio.ByteBuffer;
16 import java.nio.channels.ReadableByteChannel; 18 import java.nio.channels.ReadableByteChannel;
(...skipping 15 matching lines...) Expand all
32 private final UrlRequestContext mRequestContext; 34 private final UrlRequestContext mRequestContext;
33 private final String mUrl; 35 private final String mUrl;
34 private final int mPriority; 36 private final int mPriority;
35 private final Map<String, String> mHeaders; 37 private final Map<String, String> mHeaders;
36 private final WritableByteChannel mSink; 38 private final WritableByteChannel mSink;
37 private Map<String, String> mAdditionalHeaders; 39 private Map<String, String> mAdditionalHeaders;
38 private String mUploadContentType; 40 private String mUploadContentType;
39 private String mMethod; 41 private String mMethod;
40 private byte[] mUploadData; 42 private byte[] mUploadData;
41 private ReadableByteChannel mUploadChannel; 43 private ReadableByteChannel mUploadChannel;
42 private WritableByteChannel mOutputChannel;
43 private IOException mSinkException; 44 private IOException mSinkException;
44 private volatile boolean mStarted; 45 private volatile boolean mStarted;
45 private volatile boolean mCanceled; 46 private volatile boolean mCanceled;
46 private volatile boolean mRecycled; 47 private volatile boolean mRecycled;
47 private volatile boolean mFinished; 48 private volatile boolean mFinished;
48 private boolean mHeadersAvailable; 49 private boolean mHeadersAvailable;
49 private String mContentType; 50 private String mContentType;
50 private long mContentLength; 51 private long mContentLength;
51 private long mUploadContentLength; 52 private long mUploadContentLength;
53 private ConditionVariable mAppendChunkCondition;
52 private final ContextLock mLock; 54 private final ContextLock mLock;
53 55
54 /** 56 /**
55 * Native adapter object, owned by UrlRequest. 57 * Native adapter object, owned by UrlRequest.
56 */ 58 */
57 private long mUrlRequestAdapter; 59 private long mUrlRequestAdapter;
58 60
59 /** 61 /**
60 * Constructor. 62 * Constructor.
61 * 63 *
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 * POST. 105 * POST.
104 * @param data The content that needs to be uploaded if this is a POST 106 * @param data The content that needs to be uploaded if this is a POST
105 * request. 107 * request.
106 */ 108 */
107 public void setUploadData(String contentType, byte[] data) { 109 public void setUploadData(String contentType, byte[] data) {
108 synchronized (mLock) { 110 synchronized (mLock) {
109 validateNotStarted(); 111 validateNotStarted();
110 mUploadContentType = contentType; 112 mUploadContentType = contentType;
111 mUploadData = data; 113 mUploadData = data;
112 mUploadChannel = null; 114 mUploadChannel = null;
115 mAppendChunkCondition = null;
113 } 116 }
114 } 117 }
115 118
116 /** 119 /**
117 * Sets a readable byte channel to upload as part of a POST request. 120 * Sets a readable byte channel to upload as part of a POST request.
118 * 121 *
119 * @param contentType MIME type of the post content or null if this is not a 122 * @param contentType MIME type of the post content or null if this is not a
120 * POST request. 123 * POST request.
121 * @param channel The channel to read to read upload data from if this is a 124 * @param channel The channel to read to read upload data from if this is a
122 * POST request. 125 * POST request.
123 * @param contentLength The length of data to upload. 126 * @param contentLength The length of data to upload.
124 */ 127 */
125 public void setUploadChannel(String contentType, 128 public void setUploadChannel(String contentType,
126 ReadableByteChannel channel, long contentLength) { 129 ReadableByteChannel channel, long contentLength) {
127 synchronized (mLock) { 130 synchronized (mLock) {
128 validateNotStarted(); 131 validateNotStarted();
129 mUploadContentType = contentType; 132 mUploadContentType = contentType;
130 mUploadChannel = channel; 133 mUploadChannel = channel;
131 mUploadContentLength = contentLength; 134 mUploadContentLength = contentLength;
132 mUploadData = null; 135 mUploadData = null;
136 mAppendChunkCondition = null;
133 } 137 }
134 } 138 }
135 139
140 /**
141 * Sets this request up for chunked uploading. To upload data call
142 * {@link #appendChunkBlocking(ByteBuffer, boolean)} after {@link #start()}.
143 *
144 * @param contentType MIME type of the post content or null if this is not a
145 * POST request.
146 */
147 public void setChunkedUpload(String contentType) {
mmenke 2014/08/15 15:30:21 setUploadChannel uses chunked uploads, too, so sho
mef 2014/08/15 15:42:52 Actually, I think (correct me if I'm wrong) setUpl
mmenke 2014/08/15 15:49:01 You're right, was forgetting it took a length.
148 synchronized (mLock) {
149 validateNotStarted();
150 mUploadContentType = contentType;
151 mAppendChunkCondition = new ConditionVariable();
152 mUploadData = null;
153 mUploadChannel = null;
154 }
155 }
156
157 /**
158 * Uploads a new chunk. Must have called {@link #setChunkedUpload(String)}
159 * and {@link #start()}.
160 *
161 * @param chunk The data, which will not be modified. It must not be empty
162 * and its current position must be zero.
163 * @param isLastChunk Whether this chunk is the last one.
164 */
165 // Invokes {@link #nativeAppendChunk(long, ByteBuffer, int, boolean)} and
166 // waits for it
167 // to notify completion.
mmenke 2014/08/15 15:30:21 This should be merged with the above comment, I th
mdumitrescu 2014/08/15 15:50:20 Well, the implementation details shouldn't be in t
168 public void appendChunkBlocking(ByteBuffer chunk, boolean isLastChunk)
169 throws IOException {
170 if (!chunk.hasRemaining()) {
171 throw new IllegalArgumentException(
172 "Attempted to write empty buffer.");
173 }
174 if (chunk.position() != 0) {
175 throw new IllegalArgumentException("The position must be zero.");
176 }
177 synchronized (mLock) {
178 if (!mStarted) {
179 throw new IllegalStateException("Request not yet started.");
180 }
181 if (mAppendChunkCondition == null) {
182 throw new IllegalStateException(
183 "Request not set for chunked uploadind.");
184 }
185 if (mUrlRequestAdapter == 0) {
186 throw new IOException("Native peer destroyed.");
187 }
188 mAppendChunkCondition.close();
189 nativeAppendChunk(mUrlRequestAdapter, chunk, chunk.limit(),
190 isLastChunk);
191 }
192 // Wait for the data to be actually consumed. Outside mLock to avoid
193 // deadlock.
194 mAppendChunkCondition.block();
mmenke 2014/08/15 15:30:21 We're blocking on another thread to avoid a string
mef 2014/08/15 15:42:52 I think the idea is that one thread is writing int
mmenke 2014/08/15 15:49:01 Right...but the question is if two copies is worse
mdumitrescu 2014/08/15 15:50:20 I'm very open to suggestions regarding this. A co
mmenke 2014/08/15 16:09:24 Tasks are executed in the order they're posted, si
mdumitrescu 2014/08/15 18:20:15 Done.
195 }
196
136 public void setHttpMethod(String method) { 197 public void setHttpMethod(String method) {
137 validateNotStarted(); 198 validateNotStarted();
138 if (!("PUT".equals(method) || "POST".equals(method))) { 199 if (!("PUT".equals(method) || "POST".equals(method))) {
139 throw new IllegalArgumentException("Only PUT or POST are allowed."); 200 throw new IllegalArgumentException("Only PUT or POST are allowed.");
140 } 201 }
141 mMethod = method; 202 mMethod = method;
142 } 203 }
143 204
144 public WritableByteChannel getSink() { 205 public WritableByteChannel getSink() {
145 return mSink; 206 return mSink;
146 } 207 }
147 208
148 public void start() { 209 public void start() {
149 synchronized (mLock) { 210 synchronized (mLock) {
150 if (mCanceled) { 211 if (mCanceled) {
151 return; 212 return;
152 } 213 }
153 214
154 validateNotStarted(); 215 validateNotStarted();
155 validateNotRecycled(); 216 validateNotRecycled();
156 217
157 mStarted = true; 218 mStarted = true;
158 219
159 String method = mMethod; 220 String method = mMethod;
160 if (method == null && 221 if (method == null &&
161 ((mUploadData != null && mUploadData.length > 0) || 222 ((mUploadData != null && mUploadData.length > 0) ||
162 mUploadChannel != null)) { 223 mUploadChannel != null || mAppendChunkCondition != null)) {
163 // Default to POST if there is data to upload but no method was 224 // Default to POST if there is data to upload but no method was
164 // specified. 225 // specified.
165 method = "POST"; 226 method = "POST";
166 } 227 }
167 228
168 if (method != null) { 229 if (method != null) {
169 nativeSetMethod(mUrlRequestAdapter, method); 230 nativeSetMethod(mUrlRequestAdapter, method);
170 } 231 }
171 232
172 if (mHeaders != null && !mHeaders.isEmpty()) { 233 if (mHeaders != null && !mHeaders.isEmpty()) {
(...skipping 10 matching lines...) Expand all
183 entry.getValue()); 244 entry.getValue());
184 } 245 }
185 } 246 }
186 247
187 if (mUploadData != null && mUploadData.length > 0) { 248 if (mUploadData != null && mUploadData.length > 0) {
188 nativeSetUploadData(mUrlRequestAdapter, mUploadContentType, 249 nativeSetUploadData(mUrlRequestAdapter, mUploadContentType,
189 mUploadData); 250 mUploadData);
190 } else if (mUploadChannel != null) { 251 } else if (mUploadChannel != null) {
191 nativeSetUploadChannel(mUrlRequestAdapter, mUploadContentType, 252 nativeSetUploadChannel(mUrlRequestAdapter, mUploadContentType,
192 mUploadContentLength); 253 mUploadContentLength);
254 } else if (mAppendChunkCondition != null) {
255 nativeEnableChunkedUpload(mUrlRequestAdapter,
256 mUploadContentType);
193 } 257 }
194 258
195 nativeStart(mUrlRequestAdapter); 259 nativeStart(mUrlRequestAdapter);
196 } 260 }
197 } 261 }
198 262
199 public void cancel() { 263 public void cancel() {
200 synchronized (mLock) { 264 synchronized (mLock) {
201 if (mCanceled) { 265 if (mCanceled) {
202 return; 266 return;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 345
282 // All response headers. 346 // All response headers.
283 public Map<String, List<String>> getAllHeaders() { 347 public Map<String, List<String>> getAllHeaders() {
284 validateHeadersAvailable(); 348 validateHeadersAvailable();
285 ResponseHeadersMap result = new ResponseHeadersMap(); 349 ResponseHeadersMap result = new ResponseHeadersMap();
286 nativeGetAllHeaders(mUrlRequestAdapter, result); 350 nativeGetAllHeaders(mUrlRequestAdapter, result);
287 return result; 351 return result;
288 } 352 }
289 353
290 /** 354 /**
355 * A callback invoked when appending a chunk to the request has completed.
356 */
357 @CalledByNative
358 protected void onAppendChunkCompleted() {
359 mAppendChunkCondition.open();
360 }
361
362 /**
291 * A callback invoked when the first chunk of the response has arrived. 363 * A callback invoked when the first chunk of the response has arrived.
292 */ 364 */
293 @CalledByNative 365 @CalledByNative
294 protected void onResponseStarted() { 366 protected void onResponseStarted() {
295 mContentType = nativeGetContentType(mUrlRequestAdapter); 367 mContentType = nativeGetContentType(mUrlRequestAdapter);
296 mContentLength = nativeGetContentLength(mUrlRequestAdapter); 368 mContentLength = nativeGetContentLength(mUrlRequestAdapter);
297 mHeadersAvailable = true; 369 mHeadersAvailable = true;
298 } 370 }
299 371
300 /** 372 /**
(...skipping 22 matching lines...) Expand all
323 } 395 }
324 396
325 /** 397 /**
326 * Notifies the listener, releases native data structures. 398 * Notifies the listener, releases native data structures.
327 */ 399 */
328 @SuppressWarnings("unused") 400 @SuppressWarnings("unused")
329 @CalledByNative 401 @CalledByNative
330 private void finish() { 402 private void finish() {
331 synchronized (mLock) { 403 synchronized (mLock) {
332 mFinished = true; 404 mFinished = true;
405 if (mAppendChunkCondition != null) {
406 mAppendChunkCondition.open();
407 }
333 408
334 if (mRecycled) { 409 if (mRecycled) {
335 return; 410 return;
336 } 411 }
337 try { 412 try {
338 mSink.close(); 413 mSink.close();
339 } catch (IOException e) { 414 } catch (IOException e) {
340 // Ignore 415 // Ignore
341 } 416 }
342 onRequestComplete(); 417 onRequestComplete();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 String value); 493 String value);
419 494
420 private native void nativeSetMethod(long urlRequestAdapter, String method); 495 private native void nativeSetMethod(long urlRequestAdapter, String method);
421 496
422 private native void nativeSetUploadData(long urlRequestAdapter, 497 private native void nativeSetUploadData(long urlRequestAdapter,
423 String contentType, byte[] content); 498 String contentType, byte[] content);
424 499
425 private native void nativeSetUploadChannel(long urlRequestAdapter, 500 private native void nativeSetUploadChannel(long urlRequestAdapter,
426 String contentType, long contentLength); 501 String contentType, long contentLength);
427 502
503 private native void nativeEnableChunkedUpload(long urlRequestAdapter,
504 String contentType);
505
506 private native void nativeAppendChunk(long urlRequestAdapter,
507 ByteBuffer chunk, int chunkSize, boolean isLastChunk);
508
428 private native void nativeStart(long urlRequestAdapter); 509 private native void nativeStart(long urlRequestAdapter);
429 510
430 private native void nativeCancel(long urlRequestAdapter); 511 private native void nativeCancel(long urlRequestAdapter);
431 512
432 private native void nativeDestroyRequestAdapter(long urlRequestAdapter); 513 private native void nativeDestroyRequestAdapter(long urlRequestAdapter);
433 514
434 private native int nativeGetErrorCode(long urlRequestAdapter); 515 private native int nativeGetErrorCode(long urlRequestAdapter);
435 516
436 private native int nativeGetHttpStatusCode(long urlRequestAdapter); 517 private native int nativeGetHttpStatusCode(long urlRequestAdapter);
437 518
438 private native String nativeGetErrorString(long urlRequestAdapter); 519 private native String nativeGetErrorString(long urlRequestAdapter);
439 520
440 private native String nativeGetContentType(long urlRequestAdapter); 521 private native String nativeGetContentType(long urlRequestAdapter);
441 522
442 private native long nativeGetContentLength(long urlRequestAdapter); 523 private native long nativeGetContentLength(long urlRequestAdapter);
443 524
444 private native String nativeGetHeader(long urlRequestAdapter, String name); 525 private native String nativeGetHeader(long urlRequestAdapter, String name);
445 526
446 private native void nativeGetAllHeaders(long urlRequestAdapter, 527 private native void nativeGetAllHeaders(long urlRequestAdapter,
447 ResponseHeadersMap headers); 528 ResponseHeadersMap headers);
448 529
449 // Explicit class to work around JNI-generator generics confusion. 530 // Explicit class to work around JNI-generator generics confusion.
450 private class ResponseHeadersMap extends HashMap<String, List<String>> { 531 private class ResponseHeadersMap extends HashMap<String, List<String>> {
451 } 532 }
452 } 533 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698