Chromium Code Reviews| Index: components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java |
| diff --git a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java |
| index 835bb28681591c837db0690fc39475741a1d708a..693d441b7b0d023dffff4c454d115e39dac5b3f0 100644 |
| --- a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java |
| +++ b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequest.java |
| @@ -56,6 +56,8 @@ final class CronetUrlRequest implements UrlRequest { |
| private String mInitialMethod; |
| private final HeadersList mRequestHeaders = new HeadersList(); |
| + private CronetUploadDataStream mUploadDataStream; |
| + |
| private NativeResponseInfo mResponseInfo; |
| /* |
| @@ -257,29 +259,57 @@ final class CronetUrlRequest implements UrlRequest { |
| } |
| @Override |
| + public void setUploadDataProvider(UploadDataProvider uploadDataProvider, Executor executor) { |
| + if (uploadDataProvider == null) { |
| + throw new NullPointerException("Invalid UploadDataProvider."); |
| + } |
| + if (mInitialMethod == null) { |
| + mInitialMethod = "POST"; |
| + } |
| + mUploadDataStream = new CronetUploadDataStream(uploadDataProvider, executor); |
| + } |
| + |
| + @Override |
| public void start() { |
| synchronized (mUrlRequestAdapterLock) { |
| checkNotStarted(); |
| - mUrlRequestAdapter = nativeCreateRequestAdapter( |
| - mRequestContext.getUrlRequestContextAdapter(), |
| - mInitialUrl, |
| - mPriority); |
| - mRequestContext.onRequestStarted(this); |
| - if (mInitialMethod != null) { |
| - if (!nativeSetHttpMethod(mUrlRequestAdapter, mInitialMethod)) { |
| - destroyRequestAdapter(); |
| - throw new IllegalArgumentException("Invalid http method " |
| - + mInitialMethod); |
| + |
| + try { |
| + mUrlRequestAdapter = nativeCreateRequestAdapter( |
| + mRequestContext.getUrlRequestContextAdapter(), mInitialUrl, mPriority); |
| + mRequestContext.onRequestStarted(this); |
| + if (mInitialMethod != null) { |
| + if (!nativeSetHttpMethod(mUrlRequestAdapter, mInitialMethod)) { |
| + throw new IllegalArgumentException("Invalid http method " + mInitialMethod); |
| + } |
| } |
| - } |
| - for (Pair<String, String> header : mRequestHeaders) { |
| - if (!nativeAddHeader(mUrlRequestAdapter, header.first, |
| - header.second)) { |
| - destroyRequestAdapter(); |
| - throw new IllegalArgumentException("Invalid header " |
| - + header.first + "=" + header.second); |
| + |
| + boolean hasContentType = false; |
| + for (Pair<String, String> header : mRequestHeaders) { |
| + if (header.first.equalsIgnoreCase("Content-Type") |
| + && !header.second.isEmpty()) { |
| + hasContentType = true; |
| + } |
| + if (!nativeAddHeader(mUrlRequestAdapter, header.first, header.second)) { |
| + destroyRequestAdapter(); |
| + throw new IllegalArgumentException( |
| + "Invalid header " + header.first + "=" + header.second); |
| + } |
| + } |
| + if (mUploadDataStream != null) { |
| + if (!hasContentType) { |
| + throw new IllegalArgumentException( |
| + "Requests with body must have a Content-Type."); |
|
mef
2015/02/06 21:55:21
suggest: 'Requests with upload data' to match setU
xunjieli
2015/02/09 15:59:36
Done.
|
| + } |
| + mUploadDataStream.attachToRequest(this, mUrlRequestAdapter); |
| } |
| + } catch (RuntimeException e) { |
| + // If there's an exception, cleanup and then throw the |
| + // exception to the caller. |
| + destroyRequestAdapter(); |
| + throw e; |
| } |
| + |
| mStarted = true; |
| nativeStart(mUrlRequestAdapter); |
| } |
| @@ -415,6 +445,28 @@ final class CronetUrlRequest implements UrlRequest { |
| } |
| } |
| + /** |
| + * Called when UploadDataProvider encounters an error. |
| + */ |
| + void onUploadException(Exception e) { |
| + UrlRequestException uploadError = |
| + new UrlRequestException("Exception received from UploadDataProvider", e); |
| + Log.e(CronetUrlRequestContext.LOG_TAG, "Exception in upload method", e); |
| + // Do not call into listener if request is canceled. |
| + synchronized (mUrlRequestAdapterLock) { |
| + if (isCanceled()) { |
| + return; |
| + } |
| + cancel(); |
| + } |
| + try { |
| + mListener.onFailed(this, mResponseInfo, uploadError); |
| + } catch (Exception failException) { |
| + Log.e(CronetUrlRequestContext.LOG_TAG, "Exception notifying of failed upload", |
| + failException); |
| + } |
| + } |
| + |
| //////////////////////////////////////////////// |
| // Private methods called by the native code. |
| // Always called on network thread. |