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; | 5 package org.chromium.net; |
6 | 6 |
7 import android.util.Log; | 7 import android.util.Log; |
8 | 8 |
9 import org.apache.http.conn.ConnectTimeoutException; | 9 import org.apache.http.conn.ConnectTimeoutException; |
10 import org.chromium.base.CalledByNative; | 10 import org.chromium.base.CalledByNative; |
(...skipping 24 matching lines...) Expand all Loading... |
35 private final ChromiumUrlRequestContext mRequestContext; | 35 private final ChromiumUrlRequestContext mRequestContext; |
36 private final String mUrl; | 36 private final String mUrl; |
37 private final int mPriority; | 37 private final int mPriority; |
38 private final Map<String, String> mHeaders; | 38 private final Map<String, String> mHeaders; |
39 private final WritableByteChannel mSink; | 39 private final WritableByteChannel mSink; |
40 private Map<String, String> mAdditionalHeaders; | 40 private Map<String, String> mAdditionalHeaders; |
41 private String mUploadContentType; | 41 private String mUploadContentType; |
42 private String mMethod; | 42 private String mMethod; |
43 private byte[] mUploadData; | 43 private byte[] mUploadData; |
44 private ReadableByteChannel mUploadChannel; | 44 private ReadableByteChannel mUploadChannel; |
45 private WritableByteChannel mOutputChannel; | 45 private boolean mChunkedUpload; |
46 private IOException mSinkException; | 46 private IOException mSinkException; |
47 private volatile boolean mStarted; | 47 private volatile boolean mStarted; |
48 private volatile boolean mCanceled; | 48 private volatile boolean mCanceled; |
49 private volatile boolean mRecycled; | 49 private volatile boolean mRecycled; |
50 private volatile boolean mFinished; | 50 private volatile boolean mFinished; |
51 private boolean mHeadersAvailable; | 51 private boolean mHeadersAvailable; |
52 private String mContentType; | 52 private String mContentType; |
53 private long mUploadContentLength; | 53 private long mUploadContentLength; |
54 private final HttpUrlRequestListener mListener; | 54 private final HttpUrlRequestListener mListener; |
55 private boolean mBufferFullResponse; | 55 private boolean mBufferFullResponse; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 * @param contentType MIME type of the upload content or null if this is not | 210 * @param contentType MIME type of the upload content or null if this is not |
211 * an upload. | 211 * an upload. |
212 * @param data The content that needs to be uploaded. | 212 * @param data The content that needs to be uploaded. |
213 */ | 213 */ |
214 public void setUploadData(String contentType, byte[] data) { | 214 public void setUploadData(String contentType, byte[] data) { |
215 synchronized (mLock) { | 215 synchronized (mLock) { |
216 validateNotStarted(); | 216 validateNotStarted(); |
217 mUploadContentType = contentType; | 217 mUploadContentType = contentType; |
218 mUploadData = data; | 218 mUploadData = data; |
219 mUploadChannel = null; | 219 mUploadChannel = null; |
| 220 mChunkedUpload = false; |
220 } | 221 } |
221 } | 222 } |
222 | 223 |
223 /** | 224 /** |
224 * Sets a readable byte channel to upload as part of a POST or PUT request. | 225 * Sets a readable byte channel to upload as part of a POST or PUT request. |
225 * | 226 * |
226 * @param contentType MIME type of the upload content or null if this is not | 227 * @param contentType MIME type of the upload content or null if this is not |
227 * an upload request. | 228 * an upload request. |
228 * @param channel The channel to read to read upload data from if this is an | 229 * @param channel The channel to read to read upload data from if this is an |
229 * upload request. | 230 * upload request. |
230 * @param contentLength The length of data to upload. | 231 * @param contentLength The length of data to upload. |
231 */ | 232 */ |
232 public void setUploadChannel(String contentType, | 233 public void setUploadChannel(String contentType, |
233 ReadableByteChannel channel, long contentLength) { | 234 ReadableByteChannel channel, long contentLength) { |
234 synchronized (mLock) { | 235 synchronized (mLock) { |
235 validateNotStarted(); | 236 validateNotStarted(); |
236 mUploadContentType = contentType; | 237 mUploadContentType = contentType; |
237 mUploadChannel = channel; | 238 mUploadChannel = channel; |
238 mUploadContentLength = contentLength; | 239 mUploadContentLength = contentLength; |
239 mUploadData = null; | 240 mUploadData = null; |
| 241 mChunkedUpload = false; |
| 242 } |
| 243 } |
| 244 |
| 245 /** |
| 246 * Sets this request up for chunked uploading. To upload data call |
| 247 * {@link #appendChunk(ByteBuffer, boolean)} after {@link #start()}. |
| 248 * |
| 249 * @param contentType MIME type of the post content or null if this is not a |
| 250 * POST request. |
| 251 */ |
| 252 public void setChunkedUpload(String contentType) { |
| 253 synchronized (mLock) { |
| 254 validateNotStarted(); |
| 255 mUploadContentType = contentType; |
| 256 mChunkedUpload = true; |
| 257 mUploadData = null; |
| 258 mUploadChannel = null; |
| 259 } |
| 260 } |
| 261 |
| 262 /** |
| 263 * Uploads a new chunk. Must have called {@link #setChunkedUpload(String)} |
| 264 * and {@link #start()}. |
| 265 * |
| 266 * @param chunk The data, which will not be modified. It must not be empty |
| 267 * and its current position must be zero. |
| 268 * @param isLastChunk Whether this chunk is the last one. |
| 269 */ |
| 270 public void appendChunk(ByteBuffer chunk, boolean isLastChunk) |
| 271 throws IOException { |
| 272 if (!chunk.hasRemaining()) { |
| 273 throw new IllegalArgumentException( |
| 274 "Attempted to write empty buffer."); |
| 275 } |
| 276 if (chunk.position() != 0) { |
| 277 throw new IllegalArgumentException("The position must be zero."); |
| 278 } |
| 279 synchronized (mLock) { |
| 280 if (!mStarted) { |
| 281 throw new IllegalStateException("Request not yet started."); |
| 282 } |
| 283 if (!mChunkedUpload) { |
| 284 throw new IllegalStateException( |
| 285 "Request not set for chunked uploadind."); |
| 286 } |
| 287 if (mUrlRequestAdapter == 0) { |
| 288 throw new IOException("Native peer destroyed."); |
| 289 } |
| 290 nativeAppendChunk(mUrlRequestAdapter, chunk, chunk.limit(), |
| 291 isLastChunk); |
240 } | 292 } |
241 } | 293 } |
242 | 294 |
243 /** | 295 /** |
244 * Sets HTTP method for upload request. Only PUT or POST are allowed. | 296 * Sets HTTP method for upload request. Only PUT or POST are allowed. |
245 */ | 297 */ |
246 public void setHttpMethod(String method) { | 298 public void setHttpMethod(String method) { |
247 validateNotStarted(); | 299 validateNotStarted(); |
248 if (!("PUT".equals(method) || "POST".equals(method))) { | 300 if (!("PUT".equals(method) || "POST".equals(method))) { |
249 throw new IllegalArgumentException("Only PUT or POST are allowed."); | 301 throw new IllegalArgumentException("Only PUT or POST are allowed."); |
(...skipping 12 matching lines...) Expand all Loading... |
262 } | 314 } |
263 | 315 |
264 validateNotStarted(); | 316 validateNotStarted(); |
265 validateNotRecycled(); | 317 validateNotRecycled(); |
266 | 318 |
267 mStarted = true; | 319 mStarted = true; |
268 | 320 |
269 String method = mMethod; | 321 String method = mMethod; |
270 if (method == null && | 322 if (method == null && |
271 ((mUploadData != null && mUploadData.length > 0) || | 323 ((mUploadData != null && mUploadData.length > 0) || |
272 mUploadChannel != null)) { | 324 mUploadChannel != null || mChunkedUpload)) { |
273 // Default to POST if there is data to upload but no method was | 325 // Default to POST if there is data to upload but no method was |
274 // specified. | 326 // specified. |
275 method = "POST"; | 327 method = "POST"; |
276 } | 328 } |
277 | 329 |
278 if (method != null) { | 330 if (method != null) { |
279 nativeSetMethod(mUrlRequestAdapter, method); | 331 nativeSetMethod(mUrlRequestAdapter, method); |
280 } | 332 } |
281 | 333 |
282 if (mHeaders != null && !mHeaders.isEmpty()) { | 334 if (mHeaders != null && !mHeaders.isEmpty()) { |
(...skipping 10 matching lines...) Expand all Loading... |
293 entry.getValue()); | 345 entry.getValue()); |
294 } | 346 } |
295 } | 347 } |
296 | 348 |
297 if (mUploadData != null && mUploadData.length > 0) { | 349 if (mUploadData != null && mUploadData.length > 0) { |
298 nativeSetUploadData(mUrlRequestAdapter, mUploadContentType, | 350 nativeSetUploadData(mUrlRequestAdapter, mUploadContentType, |
299 mUploadData); | 351 mUploadData); |
300 } else if (mUploadChannel != null) { | 352 } else if (mUploadChannel != null) { |
301 nativeSetUploadChannel(mUrlRequestAdapter, mUploadContentType, | 353 nativeSetUploadChannel(mUrlRequestAdapter, mUploadContentType, |
302 mUploadContentLength); | 354 mUploadContentLength); |
| 355 } else if (mChunkedUpload) { |
| 356 nativeEnableChunkedUpload(mUrlRequestAdapter, |
| 357 mUploadContentType); |
303 } | 358 } |
304 | 359 |
305 nativeStart(mUrlRequestAdapter); | 360 nativeStart(mUrlRequestAdapter); |
306 } | 361 } |
307 } | 362 } |
308 | 363 |
309 public void cancel() { | 364 public void cancel() { |
310 synchronized (mLock) { | 365 synchronized (mLock) { |
311 if (mCanceled) { | 366 if (mCanceled) { |
312 return; | 367 return; |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 String value); | 644 String value); |
590 | 645 |
591 private native void nativeSetMethod(long urlRequestAdapter, String method); | 646 private native void nativeSetMethod(long urlRequestAdapter, String method); |
592 | 647 |
593 private native void nativeSetUploadData(long urlRequestAdapter, | 648 private native void nativeSetUploadData(long urlRequestAdapter, |
594 String contentType, byte[] content); | 649 String contentType, byte[] content); |
595 | 650 |
596 private native void nativeSetUploadChannel(long urlRequestAdapter, | 651 private native void nativeSetUploadChannel(long urlRequestAdapter, |
597 String contentType, long contentLength); | 652 String contentType, long contentLength); |
598 | 653 |
| 654 private native void nativeEnableChunkedUpload(long urlRequestAdapter, |
| 655 String contentType); |
| 656 |
| 657 private native void nativeAppendChunk(long urlRequestAdapter, |
| 658 ByteBuffer chunk, int chunkSize, boolean isLastChunk); |
| 659 |
599 private native void nativeStart(long urlRequestAdapter); | 660 private native void nativeStart(long urlRequestAdapter); |
600 | 661 |
601 private native void nativeCancel(long urlRequestAdapter); | 662 private native void nativeCancel(long urlRequestAdapter); |
602 | 663 |
603 private native void nativeDestroyRequestAdapter(long urlRequestAdapter); | 664 private native void nativeDestroyRequestAdapter(long urlRequestAdapter); |
604 | 665 |
605 private native int nativeGetErrorCode(long urlRequestAdapter); | 666 private native int nativeGetErrorCode(long urlRequestAdapter); |
606 | 667 |
607 private native int nativeGetHttpStatusCode(long urlRequestAdapter); | 668 private native int nativeGetHttpStatusCode(long urlRequestAdapter); |
608 | 669 |
609 private native String nativeGetErrorString(long urlRequestAdapter); | 670 private native String nativeGetErrorString(long urlRequestAdapter); |
610 | 671 |
611 private native String nativeGetContentType(long urlRequestAdapter); | 672 private native String nativeGetContentType(long urlRequestAdapter); |
612 | 673 |
613 private native long nativeGetContentLength(long urlRequestAdapter); | 674 private native long nativeGetContentLength(long urlRequestAdapter); |
614 | 675 |
615 private native String nativeGetHeader(long urlRequestAdapter, String name); | 676 private native String nativeGetHeader(long urlRequestAdapter, String name); |
616 | 677 |
617 private native void nativeGetAllHeaders(long urlRequestAdapter, | 678 private native void nativeGetAllHeaders(long urlRequestAdapter, |
618 ResponseHeadersMap headers); | 679 ResponseHeadersMap headers); |
619 | 680 |
620 // Explicit class to work around JNI-generator generics confusion. | 681 // Explicit class to work around JNI-generator generics confusion. |
621 private class ResponseHeadersMap extends HashMap<String, List<String>> { | 682 private class ResponseHeadersMap extends HashMap<String, List<String>> { |
622 } | 683 } |
623 } | 684 } |
OLD | NEW |