Index: components/cronet/android/java/src/org/chromium/net/UrlRequest.java |
diff --git a/components/cronet/android/java/src/org/chromium/net/UrlRequest.java b/components/cronet/android/java/src/org/chromium/net/UrlRequest.java |
index 73e9abac4030dd20e16712b8e4dad5d8ea893d22..0ba6bb51503cde897cab39497a8f75035f05d0b5 100644 |
--- a/components/cronet/android/java/src/org/chromium/net/UrlRequest.java |
+++ b/components/cronet/android/java/src/org/chromium/net/UrlRequest.java |
@@ -35,15 +35,15 @@ public class UrlRequest { |
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; |
mef
2014/08/15 19:42:27
what happened to mOutputChannel?
mmenke
2014/08/15 19:54:52
See mSink?
mdumitrescu
2014/08/18 11:28:34
Yeah. mOutputChannel is never used - mSink is.
|
+ 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; |
@@ -106,14 +106,15 @@ public class UrlRequest { |
*/ |
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 request. |
* |
* @param contentType MIME type of the post content or null if this is not a |
@@ -126,14 +127,65 @@ public class UrlRequest { |
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); |
} |
} |
public void setHttpMethod(String method) { |
validateNotStarted(); |
if (!("PUT".equals(method) || "POST".equals(method))) { |
throw new IllegalArgumentException("Only PUT or POST are allowed."); |
@@ -155,15 +207,15 @@ public class UrlRequest { |
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); |
@@ -186,14 +238,17 @@ public class UrlRequest { |
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() { |
@@ -421,14 +476,20 @@ public class UrlRequest { |
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); |