| 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 db833d782842dcf26d6094659e6e6332da7ce776..593993bc380eb1018a888b3b0bda9ac3bbc07f4e 100644
|
| --- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java
|
| +++ b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java
|
| @@ -4,6 +4,8 @@
|
|
|
| package org.chromium.net;
|
|
|
| +import android.util.Log;
|
| +
|
| import org.apache.http.conn.ConnectTimeoutException;
|
| import org.chromium.base.CalledByNative;
|
| import org.chromium.base.JNINamespace;
|
| @@ -401,41 +403,63 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
|
| // Private methods called by native library.
|
|
|
| /**
|
| + * If @CalledByNative method throws an exception, request gets cancelled
|
| + * and exception could be retrieved from request using getException().
|
| + */
|
| + private void onCalledByNativeException(Exception e) {
|
| + mSinkException = new IOException(
|
| + "CalledByNative method has thrown an exception", e);
|
| + Log.e(ChromiumUrlRequestContext.LOG_TAG,
|
| + "Exception in CalledByNative method", e);
|
| + try {
|
| + cancel();
|
| + } catch (Exception cancel_exception) {
|
| + Log.e(ChromiumUrlRequestContext.LOG_TAG,
|
| + "Exception trying to cancel request", cancel_exception);
|
| + }
|
| + }
|
| +
|
| + /**
|
| * A callback invoked when the first chunk of the response has arrived.
|
| */
|
| @CalledByNative
|
| private void onResponseStarted() {
|
| - mContentType = nativeGetContentType(mUrlRequestAdapter);
|
| - mContentLength = nativeGetContentLength(mUrlRequestAdapter);
|
| - mHeadersAvailable = true;
|
| -
|
| - if (mContentLengthLimit > 0 && mContentLength > mContentLengthLimit
|
| - && mCancelIfContentLengthOverLimit) {
|
| - onContentLengthOverLimit();
|
| - return;
|
| - }
|
| + try {
|
| + mContentType = nativeGetContentType(mUrlRequestAdapter);
|
| + mContentLength = nativeGetContentLength(mUrlRequestAdapter);
|
| + mHeadersAvailable = true;
|
| +
|
| + if (mContentLengthLimit > 0 &&
|
| + mContentLength > mContentLengthLimit &&
|
| + mCancelIfContentLengthOverLimit) {
|
| + onContentLengthOverLimit();
|
| + return;
|
| + }
|
|
|
| - if (mBufferFullResponse && mContentLength != -1
|
| - && !mContentLengthOverLimit) {
|
| - ((ChunkedWritableByteChannel)getSink()).setCapacity(
|
| - (int)mContentLength);
|
| - }
|
| + if (mBufferFullResponse && mContentLength != -1 &&
|
| + !mContentLengthOverLimit) {
|
| + ((ChunkedWritableByteChannel)getSink()).setCapacity(
|
| + (int)mContentLength);
|
| + }
|
|
|
| - if (mOffset != 0) {
|
| - // The server may ignore the request for a byte range, in which case
|
| - // status code will be 200, instead of 206. Note that we cannot call
|
| - // getHttpStatusCode as it rewrites 206 into 200.
|
| - if (nativeGetHttpStatusCode(mUrlRequestAdapter) == 200) {
|
| - // TODO(mef): Revisit this logic.
|
| - if (mContentLength != -1) {
|
| - mContentLength -= mOffset;
|
| + if (mOffset != 0) {
|
| + // The server may ignore the request for a byte range, in which
|
| + // case status code will be 200, instead of 206. Note that we
|
| + // cannot call getHttpStatusCode as it rewrites 206 into 200.
|
| + if (nativeGetHttpStatusCode(mUrlRequestAdapter) == 200) {
|
| + // TODO(mef): Revisit this logic.
|
| + if (mContentLength != -1) {
|
| + mContentLength -= mOffset;
|
| + }
|
| + mSkippingToOffset = true;
|
| + } else {
|
| + mSize = mOffset;
|
| }
|
| - mSkippingToOffset = true;
|
| - } else {
|
| - mSize = mOffset;
|
| }
|
| + mListener.onResponseStarted(this);
|
| + } catch (Exception e) {
|
| + onCalledByNativeException(e);
|
| }
|
| - mListener.onResponseStarted(this);
|
| }
|
|
|
| /**
|
| @@ -447,37 +471,36 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
|
| */
|
| @CalledByNative
|
| private void onBytesRead(ByteBuffer buffer) {
|
| - if (mContentLengthOverLimit) {
|
| - return;
|
| - }
|
| -
|
| - int size = buffer.remaining();
|
| - mSize += size;
|
| - if (mSkippingToOffset) {
|
| - if (mSize <= mOffset) {
|
| + try {
|
| + if (mContentLengthOverLimit) {
|
| return;
|
| - } else {
|
| - mSkippingToOffset = false;
|
| - buffer.position((int)(mOffset - (mSize - size)));
|
| }
|
| - }
|
|
|
| - boolean contentLengthOverLimit =
|
| - (mContentLengthLimit != 0 && mSize > mContentLengthLimit);
|
| - if (contentLengthOverLimit) {
|
| - buffer.limit(size - (int)(mSize - mContentLengthLimit));
|
| - }
|
| + int size = buffer.remaining();
|
| + mSize += size;
|
| + if (mSkippingToOffset) {
|
| + if (mSize <= mOffset) {
|
| + return;
|
| + } else {
|
| + mSkippingToOffset = false;
|
| + buffer.position((int)(mOffset - (mSize - size)));
|
| + }
|
| + }
|
| +
|
| + boolean contentLengthOverLimit =
|
| + (mContentLengthLimit != 0 && mSize > mContentLengthLimit);
|
| + if (contentLengthOverLimit) {
|
| + buffer.limit(size - (int)(mSize - mContentLengthLimit));
|
| + }
|
|
|
| - try {
|
| while (buffer.hasRemaining()) {
|
| mSink.write(buffer);
|
| }
|
| - } catch (IOException e) {
|
| - mSinkException = e;
|
| - cancel();
|
| - }
|
| - if (contentLengthOverLimit) {
|
| - onContentLengthOverLimit();
|
| + if (contentLengthOverLimit) {
|
| + onContentLengthOverLimit();
|
| + }
|
| + } catch (Exception e) {
|
| + onCalledByNativeException(e);
|
| }
|
| }
|
|
|
| @@ -487,21 +510,32 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
|
| @SuppressWarnings("unused")
|
| @CalledByNative
|
| private void finish() {
|
| - synchronized (mLock) {
|
| - mFinished = true;
|
| + try {
|
| + synchronized (mLock) {
|
| + mFinished = true;
|
|
|
| - if (mRecycled) {
|
| - return;
|
| - }
|
| - try {
|
| - mSink.close();
|
| - } catch (IOException e) {
|
| - // Ignore
|
| + if (mRecycled) {
|
| + return;
|
| + }
|
| + try {
|
| + mSink.close();
|
| + } catch (IOException e) {
|
| + // Ignore
|
| + }
|
| + try {
|
| + if (mUploadChannel != null && mUploadChannel.isOpen()) {
|
| + mUploadChannel.close();
|
| + }
|
| + } catch (IOException e) {
|
| + // Ignore
|
| + }
|
| + onRequestComplete();
|
| + nativeDestroyRequestAdapter(mUrlRequestAdapter);
|
| + mUrlRequestAdapter = 0;
|
| + mRecycled = true;
|
| }
|
| - onRequestComplete();
|
| - nativeDestroyRequestAdapter(mUrlRequestAdapter);
|
| - mUrlRequestAdapter = 0;
|
| - mRecycled = true;
|
| + } catch (Exception e) {
|
| + mSinkException = new IOException("Exception in finish", e);
|
| }
|
| }
|
|
|
| @@ -512,10 +546,14 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
|
| @CalledByNative
|
| private void onAppendResponseHeader(ResponseHeadersMap headersMap,
|
| String name, String value) {
|
| - if (!headersMap.containsKey(name)) {
|
| - headersMap.put(name, new ArrayList<String>());
|
| + try {
|
| + if (!headersMap.containsKey(name)) {
|
| + headersMap.put(name, new ArrayList<String>());
|
| + }
|
| + headersMap.get(name).add(value);
|
| + } catch (Exception e) {
|
| + onCalledByNativeException(e);
|
| }
|
| - headersMap.get(name).add(value);
|
| }
|
|
|
| /**
|
| @@ -527,25 +565,19 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
|
| @SuppressWarnings("unused")
|
| @CalledByNative
|
| private int readFromUploadChannel(ByteBuffer dest) {
|
| - if (mUploadChannel == null || !mUploadChannel.isOpen())
|
| - return -1;
|
| try {
|
| + if (mUploadChannel == null || !mUploadChannel.isOpen())
|
| + return -1;
|
| int result = mUploadChannel.read(dest);
|
| if (result < 0) {
|
| mUploadChannel.close();
|
| return 0;
|
| }
|
| return result;
|
| - } catch (IOException e) {
|
| - mSinkException = e;
|
| - try {
|
| - mUploadChannel.close();
|
| - } catch (IOException ignored) {
|
| - // Ignore this exception.
|
| - }
|
| - cancel();
|
| - return -1;
|
| + } catch (Exception e) {
|
| + onCalledByNativeException(e);
|
| }
|
| + return -1;
|
| }
|
|
|
| // Native methods are implemented in chromium_url_request.cc.
|
|
|