Merge changes I447cd196,I0c6cdae4

* changes:
  SSL-related cleanup in BrowserFrame and SslCertLookupTable
  Clean up SslErrorHandlerImpl
This commit is contained in:
Steve Block
2011-10-05 10:00:59 -07:00
committed by Android (Google) Code Review
3 changed files with 40 additions and 41 deletions

View File

@@ -471,8 +471,6 @@ class BrowserFrame extends Handler {
/** /**
* We have received an SSL certificate for the main top-level page. * We have received an SSL certificate for the main top-level page.
*
* !!!Called from the network thread!!!
*/ */
void certificate(SslCertificate certificate) { void certificate(SslCertificate certificate) {
if (mIsMainFrame) { if (mIsMainFrame) {
@@ -1186,12 +1184,11 @@ class BrowserFrame extends Handler {
SslErrorHandler handler = new SslErrorHandler() { SslErrorHandler handler = new SslErrorHandler() {
@Override @Override
public void proceed() { public void proceed() {
SslCertLookupTable.getInstance().setIsAllowed(sslError, true); SslCertLookupTable.getInstance().setIsAllowed(sslError);
nativeSslCertErrorProceed(handle); nativeSslCertErrorProceed(handle);
} }
@Override @Override
public void cancel() { public void cancel() {
SslCertLookupTable.getInstance().setIsAllowed(sslError, false);
nativeSslCertErrorCancel(handle, certError); nativeSslCertErrorCancel(handle, certError);
} }
}; };

View File

@@ -25,7 +25,8 @@ import java.net.URL;
/** /**
* Stores the user's decision of whether to allow or deny an invalid certificate. * Stores the user's decision of whether to allow or deny an invalid certificate.
* *
* This class is not threadsafe. It is used only on the WebCore thread. * This class is not threadsafe. It is used only on the WebCore thread. Also, it
* is used only by the Chromium HTTP stack.
*/ */
final class SslCertLookupTable { final class SslCertLookupTable {
private static SslCertLookupTable sTable; private static SslCertLookupTable sTable;
@@ -42,11 +43,11 @@ final class SslCertLookupTable {
table = new Bundle(); table = new Bundle();
} }
public void setIsAllowed(SslError sslError, boolean allow) { public void setIsAllowed(SslError sslError) {
// TODO: We should key on just the host. See http://b/5409251. // TODO: We should key on just the host. See http://b/5409251.
String errorString = sslErrorToString(sslError); String errorString = sslErrorToString(sslError);
if (errorString != null) { if (errorString != null) {
table.putBoolean(errorString, allow); table.putBoolean(errorString, true);
} }
} }

View File

@@ -16,8 +16,6 @@
package android.webkit; package android.webkit;
import junit.framework.Assert;
import android.net.http.SslError; import android.net.http.SslError;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
@@ -54,7 +52,7 @@ class SslErrorHandlerImpl extends SslErrorHandler {
private final SslErrorHandler mOriginHandler; private final SslErrorHandler mOriginHandler;
private final LoadListener mLoadListener; private final LoadListener mLoadListener;
// Message id for handling the response // Message id for handling the response from the client.
private static final int HANDLE_RESPONSE = 100; private static final int HANDLE_RESPONSE = 100;
@Override @Override
@@ -130,7 +128,9 @@ class SslErrorHandlerImpl extends SslErrorHandler {
} }
/** /**
* Handles SSL error(s) on the way up to the user. * Handles requests from the network stack about whether to proceed with a
* load given an SSL error(s). We may ask the client what to do, or use a
* cached response.
*/ */
/* package */ synchronized void handleSslErrorRequest(LoadListener loader) { /* package */ synchronized void handleSslErrorRequest(LoadListener loader) {
if (DebugFlags.SSL_ERROR_HANDLER) { if (DebugFlags.SSL_ERROR_HANDLER) {
@@ -147,8 +147,10 @@ class SslErrorHandlerImpl extends SslErrorHandler {
} }
/** /**
* Check the preference table for a ssl error that has already been shown * Check the preference table to see if we already have a 'proceed' decision
* to the user. * from the client for this host and for an error of equal or greater
* severity than the supplied error. If so, instruct the loader to proceed
* and return true. Otherwise return false.
*/ */
/* package */ synchronized boolean checkSslPrefTable(LoadListener loader, /* package */ synchronized boolean checkSslPrefTable(LoadListener loader,
SslError error) { SslError error) {
@@ -156,21 +158,22 @@ class SslErrorHandlerImpl extends SslErrorHandler {
final int primary = error.getPrimaryError(); final int primary = error.getPrimaryError();
if (DebugFlags.SSL_ERROR_HANDLER) { if (DebugFlags.SSL_ERROR_HANDLER) {
Assert.assertTrue(host != null && primary != 0); assert host != null;
assert primary != 0;
} }
if (mSslPrefTable.containsKey(host)) { if (mSslPrefTable.containsKey(host) && primary <= mSslPrefTable.getInt(host)) {
if (primary <= mSslPrefTable.getInt(host)) { if (!loader.cancelled()) {
handleSslErrorResponse(loader, error, true); loader.handleSslErrorResponse(true);
return true;
} }
return true;
} }
return false; return false;
} }
/** /**
* Processes queued SSL-error confirmation requests in * Processes queued SSL-error confirmation requests in
* a tight loop while there is no need to ask the user. * a tight loop while there is no need to ask the client.
*/ */
/* package */void fastProcessQueuedSslErrors() { /* package */void fastProcessQueuedSslErrors() {
while (processNextLoader()); while (processNextLoader());
@@ -195,19 +198,18 @@ class SslErrorHandlerImpl extends SslErrorHandler {
SslError error = loader.sslError(); SslError error = loader.sslError();
if (DebugFlags.SSL_ERROR_HANDLER) { if (DebugFlags.SSL_ERROR_HANDLER) {
Assert.assertNotNull(error); assert error != null;
} }
// checkSslPrefTable will handle the ssl error response if the // checkSslPrefTable() will instruct the loader to proceed if we
// answer is available. It does not remove the loader from the // have a cached 'proceed' decision. It does not remove the loader
// queue. // from the queue.
if (checkSslPrefTable(loader, error)) { if (checkSslPrefTable(loader, error)) {
mLoaderQueue.remove(loader); mLoaderQueue.remove(loader);
return true; return true;
} }
// if we do not have information on record, ask // If we can not proceed based on a cached decision, ask the client.
// the user (display a dialog)
CallbackProxy proxy = loader.getFrame().getCallbackProxy(); CallbackProxy proxy = loader.getFrame().getCallbackProxy();
proxy.onReceivedSslError(new SslErrorHandlerImpl(this, loader), error); proxy.onReceivedSslError(new SslErrorHandlerImpl(this, loader), error);
} }
@@ -217,32 +219,31 @@ class SslErrorHandlerImpl extends SslErrorHandler {
} }
/** /**
* Proceed with the SSL certificate. * Proceed with this load.
*/ */
public void proceed() { public void proceed() {
mOriginHandler.sendMessage( mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
mOriginHandler.obtainMessage( HANDLE_RESPONSE, 1, 0, mLoadListener));
HANDLE_RESPONSE, 1, 0, mLoadListener));
} }
/** /**
* Cancel this request and all pending requests for the WebView that had * Cancel this load and all pending loads for the WebView that had the
* the error. * error.
*/ */
public void cancel() { public void cancel() {
mOriginHandler.sendMessage( mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
mOriginHandler.obtainMessage( HANDLE_RESPONSE, 0, 0, mLoadListener));
HANDLE_RESPONSE, 0, 0, mLoadListener));
} }
/** /**
* Handles SSL error(s) on the way down from the user. * Handles the response from the client about whether to proceed with this
* load. We save the response to be re-used in the future.
*/ */
/* package */ synchronized void handleSslErrorResponse(LoadListener loader, /* package */ synchronized void handleSslErrorResponse(LoadListener loader,
SslError error, boolean proceed) { SslError error, boolean proceed) {
if (DebugFlags.SSL_ERROR_HANDLER) { if (DebugFlags.SSL_ERROR_HANDLER) {
Assert.assertNotNull(loader); assert loader != null;
Assert.assertNotNull(error); assert error != null;
} }
if (DebugFlags.SSL_ERROR_HANDLER) { if (DebugFlags.SSL_ERROR_HANDLER) {
@@ -253,16 +254,16 @@ class SslErrorHandlerImpl extends SslErrorHandler {
if (!loader.cancelled()) { if (!loader.cancelled()) {
if (proceed) { if (proceed) {
// update the user's SSL error preference table // Update the SSL error preference table
int primary = error.getPrimaryError(); int primary = error.getPrimaryError();
String host = loader.host(); String host = loader.host();
if (DebugFlags.SSL_ERROR_HANDLER) { if (DebugFlags.SSL_ERROR_HANDLER) {
Assert.assertTrue(host != null && primary != 0); assert host != null;
assert primary != 0;
} }
boolean hasKey = mSslPrefTable.containsKey(host); boolean hasKey = mSslPrefTable.containsKey(host);
if (!hasKey || if (!hasKey || primary > mSslPrefTable.getInt(host)) {
primary > mSslPrefTable.getInt(host)) {
mSslPrefTable.putInt(host, primary); mSslPrefTable.putInt(host, primary);
} }
} }