Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Unified Diff: components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java

Issue 945843003: [Cronet] Do not call into native adapter after it is destroyed in ChromiumUrlRequest.java (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: typo Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 05f933fed38ff8f74fd9942190623386aaed1ca9..9ec0f9efd78fd3d8783e2fcec3c1de41cf0c6b2c 100644
--- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java
+++ b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequest.java
@@ -47,22 +47,40 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
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;
private long mUploadContentLength;
private final HttpUrlRequestListener mListener;
private boolean mBufferFullResponse;
private long mOffset;
- private long mContentLength;
private long mContentLengthLimit;
private boolean mCancelIfContentLengthOverLimit;
private boolean mContentLengthOverLimit;
private boolean mSkippingToOffset;
private long mSize;
+
// Indicates whether redirects have been disabled.
private boolean mDisableRedirects;
+
+ // Http status code. Default to 0. Populated in onResponseStarted().
+ private int mHttpStatusCode = 0;
+
+ // Http status text. Default to null. Populated in onResponseStarted().
+ private String mHttpStatusText;
+
+ // Content type. Default to null. Populated in onResponseStarted().
+ private String mContentType;
+
+ // Compressed content length as reported by the server. Populated in onResponseStarted().
+ private long mContentLength;
+
+ // Native error code. Default to no error. Populated in onRequestComplete().
+ private int mErrorCode = ChromiumUrlRequestError.SUCCESS;
+
+ // Native error string. Default to null. Populated in onRequestComplete().
+ private String mErrorString;
+
+ // Protects access of mUrlRequestAdapter, mStarted, mCanceled, and mFinished.
private final Object mLock = new Object();
public ChromiumUrlRequest(ChromiumUrlRequestContext requestContext,
@@ -132,26 +150,24 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
@Override
public int getHttpStatusCode() {
- int httpStatusCode = nativeGetHttpStatusCode(mUrlRequestAdapter);
-
// TODO(mef): Investigate the following:
// If we have been able to successfully resume a previously interrupted
// download, the status code will be 206, not 200. Since the rest of the
// application is expecting 200 to indicate success, we need to fake it.
- if (httpStatusCode == 206) {
- httpStatusCode = 200;
+ if (mHttpStatusCode == 206) {
+ return 200;
}
- return httpStatusCode;
+ return mHttpStatusCode;
}
@Override
public String getHttpStatusText() {
- return nativeGetHttpStatusText(mUrlRequestAdapter);
+ return mHttpStatusText;
}
/**
- * Returns an exception if any, or null if the request was completed
- * successfully.
+ * Returns an exception if any, or null if the request has not completed or
+ * completed successfully.
*/
@Override
public IOException getException() {
@@ -159,18 +175,14 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
return mSinkException;
}
- validateNotRecycled();
-
- int errorCode = nativeGetErrorCode(mUrlRequestAdapter);
- switch (errorCode) {
+ switch (mErrorCode) {
case ChromiumUrlRequestError.SUCCESS:
if (mContentLengthOverLimit) {
return new ResponseTooLargeException();
}
return null;
case ChromiumUrlRequestError.UNKNOWN:
- return new IOException(
- nativeGetErrorString(mUrlRequestAdapter));
+ return new IOException(mErrorString);
case ChromiumUrlRequestError.MALFORMED_URL:
return new MalformedURLException("Malformed URL: " + mUrl);
case ChromiumUrlRequestError.CONNECTION_TIMED_OUT:
@@ -188,7 +200,7 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
+ "many redirects or redirects have been disabled");
default:
throw new IllegalStateException(
- "Unrecognized error code: " + errorCode);
+ "Unrecognized error code: " + mErrorCode);
}
}
@@ -317,9 +329,12 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
@Override
public void disableRedirects() {
- mDisableRedirects = true;
- validateNotStarted();
- nativeDisableRedirects(mUrlRequestAdapter);
+ synchronized (mLock) {
+ validateNotStarted();
+ validateNativeAdapterNotDestroyed();
+ mDisableRedirects = true;
+ nativeDisableRedirects(mUrlRequestAdapter);
+ }
}
public WritableByteChannel getSink() {
@@ -334,7 +349,7 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
}
validateNotStarted();
- validateNotRecycled();
+ validateNativeAdapterNotDestroyed();
mStarted = true;
@@ -384,7 +399,7 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
mCanceled = true;
- if (!mRecycled) {
+ if (mUrlRequestAdapter != 0) {
nativeCancel(mUrlRequestAdapter);
}
}
@@ -397,17 +412,13 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
}
}
- public boolean isRecycled() {
- synchronized (mLock) {
- return mRecycled;
- }
- }
-
@Override
public String getNegotiatedProtocol() {
- validateNotRecycled();
- validateHeadersAvailable();
- return nativeGetNegotiatedProtocol(mUrlRequestAdapter);
+ synchronized (mLock) {
+ validateNativeAdapterNotDestroyed();
+ validateHeadersAvailable();
+ return nativeGetNegotiatedProtocol(mUrlRequestAdapter);
+ }
}
@Override
@@ -417,19 +428,23 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
@Override
public String getHeader(String name) {
- validateNotRecycled();
- validateHeadersAvailable();
- return nativeGetHeader(mUrlRequestAdapter, name);
+ synchronized (mLock) {
+ validateNativeAdapterNotDestroyed();
+ validateHeadersAvailable();
+ return nativeGetHeader(mUrlRequestAdapter, name);
+ }
}
// All response headers.
@Override
public Map<String, List<String>> getAllHeaders() {
- validateNotRecycled();
- validateHeadersAvailable();
- ResponseHeadersMap result = new ResponseHeadersMap();
- nativeGetAllHeaders(mUrlRequestAdapter, result);
- return result;
+ synchronized (mLock) {
+ validateNativeAdapterNotDestroyed();
+ validateHeadersAvailable();
+ ResponseHeadersMap result = new ResponseHeadersMap();
+ nativeGetAllHeaders(mUrlRequestAdapter, result);
+ return result;
+ }
}
@Override
@@ -463,12 +478,23 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
* A callback invoked when the response has been fully consumed.
*/
private void onRequestComplete() {
+ mErrorCode = nativeGetErrorCode(mUrlRequestAdapter);
+ mErrorString = nativeGetErrorString(mUrlRequestAdapter);
+ // When there is an error or redirects have been disabled,
+ // onResponseStarted is often not invoked.
+ // Populate status code and status text if that's the case.
+ // Note that besides redirects, these two fields may be set on the
+ // request for AUTH and CERT requests.
+ if (mErrorCode != ChromiumUrlRequestError.SUCCESS) {
+ mHttpStatusCode = nativeGetHttpStatusCode(mUrlRequestAdapter);
+ mHttpStatusText = nativeGetHttpStatusText(mUrlRequestAdapter);
+ }
mListener.onRequestComplete(this);
}
- private void validateNotRecycled() {
- if (mRecycled) {
- throw new IllegalStateException("Accessing recycled request");
+ private void validateNativeAdapterNotDestroyed() {
+ if (mUrlRequestAdapter == 0) {
+ throw new IllegalStateException("Adapter has been destroyed");
}
}
@@ -515,6 +541,8 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
@CalledByNative
private void onResponseStarted() {
try {
+ mHttpStatusCode = nativeGetHttpStatusCode(mUrlRequestAdapter);
+ mHttpStatusText = nativeGetHttpStatusText(mUrlRequestAdapter);
mContentType = nativeGetContentType(mUrlRequestAdapter);
mContentLength = nativeGetContentLength(mUrlRequestAdapter);
mHeadersAvailable = true;
@@ -536,7 +564,7 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
// 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) {
+ if (mHttpStatusCode == 200) {
// TODO(mef): Revisit this logic.
if (mContentLength != -1) {
mContentLength -= mOffset;
@@ -607,7 +635,7 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
}
mFinished = true;
- if (mRecycled) {
+ if (mUrlRequestAdapter == 0) {
return;
}
try {
@@ -625,7 +653,6 @@ public class ChromiumUrlRequest implements HttpUrlRequest {
onRequestComplete();
nativeDestroyRequestAdapter(mUrlRequestAdapter);
mUrlRequestAdapter = 0;
- mRecycled = true;
}
} catch (Exception e) {
mSinkException = new IOException("Exception in finish", e);

Powered by Google App Engine
This is Rietveld 408576698