summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuahui Wu <hwu@google.com>2010-12-15 09:41:59 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-12-15 09:42:00 -0800
commit4ab61e100d25f6998a1b91e1949a0c81ddf00beb (patch)
tree06c69ff92995b61067e1a851aafc82318b7513ba
parenta27aeefa969a6478d8defe52be7526d611970b49 (diff)
parent1f9212cd9a5e957562b12e8c3294b7f357fa1f85 (diff)
downloadexternal_webkit-4ab61e100d25f6998a1b91e1949a0c81ddf00beb.zip
external_webkit-4ab61e100d25f6998a1b91e1949a0c81ddf00beb.tar.gz
external_webkit-4ab61e100d25f6998a1b91e1949a0c81ddf00beb.tar.bz2
Merge "b/2864818 Prompt SSL cert error dialog to user and proceed or cancel the request. Java side CL: https://android-git.corp.google.com/g/#change,84530"
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp3
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.cpp16
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.h2
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp27
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.h3
-rw-r--r--WebKit/android/WebCoreSupport/WebViewClientError.cpp19
-rw-r--r--WebKit/android/WebCoreSupport/WebViewClientError.h2
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp49
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.h2
9 files changed, 112 insertions, 11 deletions
diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
index a563c6a..4053e56 100644
--- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
@@ -74,6 +74,7 @@
#include "WebHistory.h"
#include "WebIconDatabase.h"
#include "WebFrameView.h"
+#include "WebViewClientError.h"
#include "WebViewCore.h"
#include "autofill/WebAutoFill.h"
#include "android_graphics.h"
@@ -592,7 +593,7 @@ void FrameLoaderClientAndroid::setMainDocumentError(DocumentLoader* docLoader, c
m_manualLoader = NULL;
m_hasSentResponseToPlugin = false;
} else {
- if (!error.isNull() && error.errorCode() >= InternalErrorLast)
+ if (!error.isNull() && error.errorCode() >= InternalErrorLast && error.errorCode() != ERROR_OK)
m_webFrame->reportError(error.errorCode(),
error.localizedDescription(), error.failingURL());
}
diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp
index 468a3cd..cd496df 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequest.cpp
@@ -318,12 +318,12 @@ void WebRequest::OnAuthRequired(URLRequest* request, net::AuthChallengeInfo* aut
m_urlLoader.get(), &WebUrlLoaderClient::authRequired, authInfoPtr, firstTime));
}
-// Called when we received an SSL certificate error. Right now, we only
-// set the appropriate error code. FIXME: the delegate should provide
+// Called when we received an SSL certificate error. The delegate will provide
// the user the options to proceed, cancel, or view certificates.
void WebRequest::OnSSLCertificateError(URLRequest* request, int cert_error, net::X509Certificate* cert)
{
- request->SimulateError(cert_error);
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::reportSslCertError, cert_error, cert));
}
// After calling Start(), the delegate will receive an OnResponseStarted
@@ -370,6 +370,16 @@ void WebRequest::followDeferredRedirect()
m_request->FollowDeferredRedirect();
}
+void WebRequest::proceedSslCertError()
+{
+ m_request->ContinueDespiteLastError();
+}
+
+void WebRequest::cancelSslCertError(int cert_error)
+{
+ m_request->SimulateError(cert_error);
+}
+
void WebRequest::startReading()
{
ASSERT(m_loadState == Response || m_loadState == GotData, "StartReading in state other than RESPONSE and GOTDATA");
diff --git a/WebKit/android/WebCoreSupport/WebRequest.h b/WebKit/android/WebCoreSupport/WebRequest.h
index c78546c..c3c5ec0 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.h
+++ b/WebKit/android/WebCoreSupport/WebRequest.h
@@ -80,6 +80,8 @@ public:
void setAuth(const string16& username, const string16& password);
void cancelAuth();
void followDeferredRedirect();
+ void proceedSslCertError();
+ void cancelSslCertError(int cert_error);
const std::string& getUrl() const;
const std::string& getUserAgent() const;
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
index 50defc2..0d7981a 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
@@ -224,6 +224,25 @@ void WebUrlLoaderClient::cancelAuth()
thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::cancelAuth));
}
+void WebUrlLoaderClient::proceedSslCertError()
+{
+ base::Thread* thread = ioThread();
+ if (!thread) {
+ return;
+ }
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::proceedSslCertError));
+}
+
+void WebUrlLoaderClient::cancelSslCertError(int cert_error)
+{
+ base::Thread* thread = ioThread();
+ if (!thread) {
+ return;
+ }
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::cancelSslCertError, cert_error));
+}
+
+
void WebUrlLoaderClient::finish()
{
m_finished = true;
@@ -349,4 +368,12 @@ void WebUrlLoaderClient::authRequired(scoped_refptr<net::AuthChallengeInfo> auth
m_webFrame->didReceiveAuthenticationChallenge(this, host, realm, firstTime);
}
+void WebUrlLoaderClient::reportSslCertError(int cert_error, net::X509Certificate* cert)
+{
+ if (!isActive()) return;
+ std::vector<std::string> chain_bytes;
+ cert->GetChainDEREncodedBytes(&chain_bytes);
+ m_webFrame->reportSslCertError(this, cert_error, chain_bytes[0]);
+}
+
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
index d69bea6..e5a4d8f 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
@@ -72,6 +72,8 @@ public:
void pauseLoad(bool pause) {} // Android method, does nothing for now
void setAuth(const std::string& username, const std::string& password);
void cancelAuth();
+ void proceedSslCertError();
+ void cancelSslCertError(int cert_error);
typedef void CallbackFunction(void*);
@@ -88,6 +90,7 @@ public:
void didFail(PassOwnPtr<WebResponse>);
void willSendRequest(PassOwnPtr<WebResponse>);
void authRequired(scoped_refptr<net::AuthChallengeInfo>, bool firstTime);
+ void reportSslCertError(int cert_error, net::X509Certificate* cert);
// Handle to the chrome IO thread
static base::Thread* ioThread();
diff --git a/WebKit/android/WebCoreSupport/WebViewClientError.cpp b/WebKit/android/WebCoreSupport/WebViewClientError.cpp
index 9744efb..59542da 100644
--- a/WebKit/android/WebCoreSupport/WebViewClientError.cpp
+++ b/WebKit/android/WebCoreSupport/WebViewClientError.cpp
@@ -101,6 +101,17 @@ WebViewClientError ToWebViewClientError(net::Error error) {
case ERR_SSL_SNAP_START_NPN_MISPREDICTION:
case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED:
case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY:
+ return ERROR_FAILED_SSL_HANDSHAKE;
+
+ case ERR_PROXY_AUTH_UNSUPPORTED:
+ case ERR_PROXY_AUTH_REQUESTED:
+ case ERR_PROXY_CONNECTION_FAILED:
+ case ERR_UNEXPECTED_PROXY_AUTH:
+ return ERROR_PROXY_AUTHENTICATION;
+
+ /* The certificate errors are handled by their own dialog
+ * and don't need to be reported to the framework again.
+ */
case ERR_CERT_COMMON_NAME_INVALID:
case ERR_CERT_DATE_INVALID:
case ERR_CERT_AUTHORITY_INVALID:
@@ -111,13 +122,7 @@ WebViewClientError ToWebViewClientError(net::Error error) {
case ERR_CERT_INVALID:
case ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
case ERR_CERT_NOT_IN_DNS:
- return ERROR_FAILED_SSL_HANDSHAKE;
-
- case ERR_PROXY_AUTH_UNSUPPORTED:
- case ERR_PROXY_AUTH_REQUESTED:
- case ERR_PROXY_CONNECTION_FAILED:
- case ERR_UNEXPECTED_PROXY_AUTH:
- return ERROR_PROXY_AUTHENTICATION;
+ return ERROR_OK;
default:
return ERROR_UNKNOWN;
diff --git a/WebKit/android/WebCoreSupport/WebViewClientError.h b/WebKit/android/WebCoreSupport/WebViewClientError.h
index 847fb01..d274dc7 100644
--- a/WebKit/android/WebCoreSupport/WebViewClientError.h
+++ b/WebKit/android/WebCoreSupport/WebViewClientError.h
@@ -32,6 +32,8 @@ namespace android {
// This enum must be kept in sync with WebViewClient.java
enum WebViewClientError {
+ /** Success */
+ ERROR_OK = 0,
/** Generic error */
ERROR_UNKNOWN = -1,
/** Server or proxy hostname lookup failed */
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index 5fa5dfb..4fac42d 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -215,6 +215,7 @@ struct WebFrame::JavaBrowserFrame
jmethodID mGetFileSize;
jmethodID mGetFile;
jmethodID mDidReceiveAuthenticationChallenge;
+ jmethodID mReportSslCertError;
jmethodID mDownloadStart;
AutoJObject frame(JNIEnv* env) {
return getRealObject(env, mObj);
@@ -281,6 +282,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
mJavaFrame->mGetFile = env->GetMethodID(clazz, "getFile", "(Ljava/lang/String;[BII)I");
mJavaFrame->mDidReceiveAuthenticationChallenge = env->GetMethodID(clazz, "didReceiveAuthenticationChallenge",
"(ILjava/lang/String;Ljava/lang/String;Z)V");
+ mJavaFrame->mReportSslCertError = env->GetMethodID(clazz, "reportSslCertError", "(II[B)V");
mJavaFrame->mDownloadStart = env->GetMethodID(clazz, "downloadStart",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;J)V");
env->DeleteLocalRef(clazz);
@@ -308,6 +310,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
LOG_ASSERT(mJavaFrame->mGetFileSize, "Could not find method getFileSize");
LOG_ASSERT(mJavaFrame->mGetFile, "Could not find method getFile");
LOG_ASSERT(mJavaFrame->mDidReceiveAuthenticationChallenge, "Could not find method didReceiveAuthenticationChallenge");
+ LOG_ASSERT(mJavaFrame->mReportSslCertError, "Could not find method reportSslCertError");
LOG_ASSERT(mJavaFrame->mDownloadStart, "Could not find method downloadStart");
mUserAgent = WTF::String();
@@ -863,6 +866,26 @@ WebFrame::didReceiveAuthenticationChallenge(WebUrlLoaderClient* client, const st
}
void
+WebFrame::reportSslCertError(WebUrlLoaderClient* client, int cert_error, const std::string& cert)
+{
+#ifdef ANDROID_INSTRUMENT
+ TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
+#endif
+ JNIEnv* env = getJNIEnv();
+ int jHandle = reinterpret_cast<int>(client);
+
+ int len = cert.length();
+ jbyteArray jCert = env->NewByteArray(len);
+ jbyte* bytes = env->GetByteArrayElements(jCert, NULL);
+ cert.copy(reinterpret_cast<char*>(bytes), len);
+
+ env->CallVoidMethod(mJavaFrame->frame(env).get(),
+ mJavaFrame->mReportSslCertError, jHandle, cert_error, jCert);
+ env->DeleteLocalRef(jCert);
+ checkException(env);
+}
+
+void
WebFrame::downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength)
{
#ifdef ANDROID_INSTRUMENT
@@ -1876,6 +1899,18 @@ static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle)
client->cancelAuth();
}
+static void SslCertErrorProceed(JNIEnv *env, jobject obj, int handle)
+{
+ WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
+ client->proceedSslCertError();
+}
+
+static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_error)
+{
+ WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
+ client->cancelSslCertError(cert_error);
+}
+
#else
static void AuthenticationProceed(JNIEnv *env, jobject obj, int handle, jstring jUsername, jstring jPassword)
@@ -1888,6 +1923,16 @@ static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle)
LOGW("Chromium authentication API called, but libchromium is not available");
}
+static void SslCertErrorProceed(JNIEnv *env, jobject obj, int handle)
+{
+ LOGW("Chromium SSL API called, but libchromium is not available");
+}
+
+static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_error)
+{
+ LOGW("Chromium SSL API called, but libchromium is not available");
+}
+
#endif // USE(CHROME_NETWORK_STACK)
// ----------------------------------------------------------------------------
@@ -1950,6 +1995,10 @@ static JNINativeMethod gBrowserFrameNativeMethods[] = {
(void*) AuthenticationProceed },
{ "nativeAuthenticationCancel", "(I)V",
(void*) AuthenticationCancel },
+ { "nativeSslCertErrorProceed", "(I)V",
+ (void*) SslCertErrorProceed },
+ { "nativeSslCertErrorCancel", "(II)V",
+ (void*) SslCertErrorCancel },
};
int registerWebFrame(JNIEnv* env)
diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h
index 4575460..41037d9 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.h
+++ b/WebKit/android/jni/WebCoreFrameBridge.h
@@ -115,6 +115,8 @@ class WebFrame : public WebCoreRefObject {
void didReceiveAuthenticationChallenge(WebUrlLoaderClient*, const std::string& host, const std::string& realm, bool useCachedCredentials);
+ void reportSslCertError(WebUrlLoaderClient* client, int cert_error, const std::string& cert);
+
void downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength);
void maybeSavePassword(WebCore::Frame* frame, const WebCore::ResourceRequest& request);