Index: components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java |
diff --git a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java |
index 593993bc380eb1018a888b3b0bda9ac3bbc07f4e..d067cf6559a912cf037252112008ddf399ca80b8 100644 |
--- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java |
+++ b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java |
@@ -38,15 +38,15 @@ public class ChromiumUrlRequest implements HttpUrlRequest { |
private final Map<String, String> mHeaders; |
private final WritableByteChannel mSink; |
private Map<String, String> mAdditionalHeaders; |
private String mUploadContentType; |
private String mMethod; |
private byte[] mUploadData; |
private ReadableByteChannel mUploadChannel; |
- private WritableByteChannel mOutputChannel; |
+ private boolean mChunkedUpload; |
private IOException mSinkException; |
private volatile boolean mStarted; |
private volatile boolean mCanceled; |
private volatile boolean mRecycled; |
private volatile boolean mFinished; |
private boolean mHeadersAvailable; |
private String mContentType; |
@@ -213,14 +213,15 @@ public class ChromiumUrlRequest implements HttpUrlRequest { |
*/ |
public void setUploadData(String contentType, byte[] data) { |
synchronized (mLock) { |
validateNotStarted(); |
mUploadContentType = contentType; |
mUploadData = data; |
mUploadChannel = null; |
+ mChunkedUpload = false; |
} |
} |
/** |
* Sets a readable byte channel to upload as part of a POST or PUT request. |
* |
* @param contentType MIME type of the upload content or null if this is not |
@@ -233,14 +234,65 @@ public class ChromiumUrlRequest implements HttpUrlRequest { |
ReadableByteChannel channel, long contentLength) { |
synchronized (mLock) { |
validateNotStarted(); |
mUploadContentType = contentType; |
mUploadChannel = channel; |
mUploadContentLength = contentLength; |
mUploadData = null; |
+ mChunkedUpload = false; |
+ } |
+ } |
+ |
+ /** |
+ * Sets this request up for chunked uploading. To upload data call |
+ * {@link #appendChunk(ByteBuffer, boolean)} after {@link #start()}. |
+ * |
+ * @param contentType MIME type of the post content or null if this is not a |
+ * POST request. |
+ */ |
+ public void setChunkedUpload(String contentType) { |
+ synchronized (mLock) { |
+ validateNotStarted(); |
+ mUploadContentType = contentType; |
+ mChunkedUpload = true; |
+ mUploadData = null; |
+ mUploadChannel = null; |
+ } |
+ } |
+ |
+ /** |
+ * Uploads a new chunk. Must have called {@link #setChunkedUpload(String)} |
+ * and {@link #start()}. |
+ * |
+ * @param chunk The data, which will not be modified. It must not be empty |
+ * and its current position must be zero. |
+ * @param isLastChunk Whether this chunk is the last one. |
+ */ |
+ public void appendChunk(ByteBuffer chunk, boolean isLastChunk) |
+ throws IOException { |
+ if (!chunk.hasRemaining()) { |
+ throw new IllegalArgumentException( |
+ "Attempted to write empty buffer."); |
+ } |
+ if (chunk.position() != 0) { |
+ throw new IllegalArgumentException("The position must be zero."); |
+ } |
+ synchronized (mLock) { |
+ if (!mStarted) { |
+ throw new IllegalStateException("Request not yet started."); |
+ } |
+ if (!mChunkedUpload) { |
+ throw new IllegalStateException( |
+ "Request not set for chunked uploadind."); |
+ } |
+ if (mUrlRequestAdapter == 0) { |
+ throw new IOException("Native peer destroyed."); |
+ } |
+ nativeAppendChunk(mUrlRequestAdapter, chunk, chunk.limit(), |
+ isLastChunk); |
} |
} |
/** |
* Sets HTTP method for upload request. Only PUT or POST are allowed. |
*/ |
public void setHttpMethod(String method) { |
@@ -265,15 +317,15 @@ public class ChromiumUrlRequest implements HttpUrlRequest { |
validateNotRecycled(); |
mStarted = true; |
String method = mMethod; |
if (method == null && |
((mUploadData != null && mUploadData.length > 0) || |
- mUploadChannel != null)) { |
+ mUploadChannel != null || mChunkedUpload)) { |
// Default to POST if there is data to upload but no method was |
// specified. |
method = "POST"; |
} |
if (method != null) { |
nativeSetMethod(mUrlRequestAdapter, method); |
@@ -296,14 +348,17 @@ public class ChromiumUrlRequest implements HttpUrlRequest { |
if (mUploadData != null && mUploadData.length > 0) { |
nativeSetUploadData(mUrlRequestAdapter, mUploadContentType, |
mUploadData); |
} else if (mUploadChannel != null) { |
nativeSetUploadChannel(mUrlRequestAdapter, mUploadContentType, |
mUploadContentLength); |
+ } else if (mChunkedUpload) { |
+ nativeEnableChunkedUpload(mUrlRequestAdapter, |
+ mUploadContentType); |
} |
nativeStart(mUrlRequestAdapter); |
} |
} |
public void cancel() { |
@@ -592,14 +647,20 @@ public class ChromiumUrlRequest implements HttpUrlRequest { |
private native void nativeSetUploadData(long urlRequestAdapter, |
String contentType, byte[] content); |
private native void nativeSetUploadChannel(long urlRequestAdapter, |
String contentType, long contentLength); |
+ private native void nativeEnableChunkedUpload(long urlRequestAdapter, |
+ String contentType); |
+ |
+ private native void nativeAppendChunk(long urlRequestAdapter, |
+ ByteBuffer chunk, int chunkSize, boolean isLastChunk); |
+ |
private native void nativeStart(long urlRequestAdapter); |
private native void nativeCancel(long urlRequestAdapter); |
private native void nativeDestroyRequestAdapter(long urlRequestAdapter); |
private native int nativeGetErrorCode(long urlRequestAdapter); |