| 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.");
|
| + }
|
| + 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.
|
|
|