OSDN Git Service

Fix #2025900. If a https request is canceled while openConnection is called
authorGrace Kloba <klobag@google.com>
Fri, 31 Jul 2009 06:13:34 +0000 (23:13 -0700)
committerGrace Kloba <klobag@google.com>
Fri, 31 Jul 2009 06:13:34 +0000 (23:13 -0700)
and a ssl error happened, the http thread can be blocked for up to 10 min.
Added code to detect this case and unlock the thread.

core/java/android/net/http/EventHandler.java
core/java/android/net/http/HttpsConnection.java
core/java/android/net/http/LoggingEventHandler.java
core/java/android/webkit/LoadListener.java

index 830d1f1..a035c19 100644 (file)
@@ -141,7 +141,10 @@ public interface EventHandler {
      * SSL certificate error callback. Handles SSL error(s) on the way
      * up to the user. The callback has to make sure that restartConnection() is called,
      * otherwise the connection will be suspended indefinitely.
+     * @return True if the callback can handle the error, which means it will
+     *              call restartConnection() to unblock the thread later,
+     *              otherwise return false.
      */
-    public void handleSslErrorRequest(SslError error);
+    public boolean handleSslErrorRequest(SslError error);
 
 }
index 55b733f..8a69d0d 100644 (file)
@@ -323,7 +323,10 @@ public class HttpsConnection extends Connection {
                 mSuspended = true;
             }
             // don't hold the lock while calling out to the event handler
-            eventHandler.handleSslErrorRequest(error);
+            boolean canHandle = eventHandler.handleSslErrorRequest(error);
+            if(!canHandle) {
+                throw new IOException("failed to handle "+ error);
+            }
             synchronized (mSuspendLock) {
                 if (mSuspended) {
                     try {
index 1b18651..bdafa0b 100644 (file)
@@ -82,9 +82,11 @@ public class LoggingEventHandler implements EventHandler {
         }
     }
 
-    public void handleSslErrorRequest(SslError error) {
+    public boolean handleSslErrorRequest(SslError error) {
         if (HttpLog.LOGV) {
             HttpLog.v("LoggingEventHandler: handleSslErrorRequest():" + error);
         }
+        // return false so that the caller thread won't wait forever
+        return false;
     }
 }
index 9ca2909..c3f3594 100644 (file)
@@ -106,6 +106,7 @@ class LoadListener extends Handler implements EventHandler {
     private String   mErrorDescription;
     private SslError mSslError;
     private RequestHandle mRequestHandle;
+    private RequestHandle mSslErrorRequestHandle;
 
     // Request data. It is only valid when we are doing a load from the
     // cache. It is needed if the cache returns a redirect
@@ -693,7 +694,7 @@ class LoadListener extends Handler implements EventHandler {
      * IMPORTANT: as this is called from network thread, can't call native
      * directly
      */
-    public void handleSslErrorRequest(SslError error) {
+    public boolean handleSslErrorRequest(SslError error) {
         if (WebView.LOGV_ENABLED) {
             Log.v(LOGTAG,
                     "LoadListener.handleSslErrorRequest(): url:" + url() +
@@ -701,6 +702,15 @@ class LoadListener extends Handler implements EventHandler {
                     " certificate: " + error.getCertificate());
         }
         sendMessageInternal(obtainMessage(MSG_SSL_ERROR, error));
+        // if it has been canceled, return false so that the network thread
+        // won't be blocked. If it is not canceled, save the mRequestHandle
+        // so that if it is canceled when MSG_SSL_ERROR is handled, we can
+        // still call handleSslErrorResponse which will call restartConnection
+        // to unblock the network thread.
+        if (!mCancelled) {
+            mSslErrorRequestHandle = mRequestHandle;
+        }
+        return !mCancelled;
     }
 
     // Handle the ssl error on the WebCore thread.
@@ -708,7 +718,10 @@ class LoadListener extends Handler implements EventHandler {
         if (!mCancelled) {
             mSslError = error;
             Network.getInstance(mContext).handleSslErrorRequest(this);
+        } else if (mSslErrorRequestHandle != null) {
+            mSslErrorRequestHandle.handleSslErrorResponse(true);
         }
+        mSslErrorRequestHandle = null;
     }
 
     /**