summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-08-23 17:35:30 +0100
committerIain Merrick <husky@google.com>2010-09-20 12:14:03 +0100
commitd4ff0cc91b5eb975d563f355f9f4c7358e0e2c06 (patch)
tree69dda182d1890032def251c6888fcfb97d4d5135 /WebKit
parentf8230805249e7f0956d00204d2e610208efe5ad9 (diff)
downloadexternal_webkit-d4ff0cc91b5eb975d563f355f9f4c7358e0e2c06.zip
external_webkit-d4ff0cc91b5eb975d563f355f9f4c7358e0e2c06.tar.gz
external_webkit-d4ff0cc91b5eb975d563f355f9f4c7358e0e2c06.tar.bz2
HTTP auth for Chromium HTTP stack (C++ side)
On receiving an auth request: - WebRequest (on the IO thread) sends a message to WebUrlLoaderClient - WebUrlLoaderClient (webkit thread) calls WebCoreFrameBridge. - WebCoreFrameBridge makes a JNI call to BrowserFrame.java. Each JNI call has a WebUrlLoaderClient pointer, cast to an int. We use this to recover the context when we're called back, and dispatch a message back to WebRequest. Corresponding Java change: https://android-git.corp.google.com/g/63762 Change-Id: Ieb72f2eaa996a55916c987859f47f6dacf92e06c
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/android/WebCoreSupport/ChromiumIncludes.h2
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.cpp22
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.h4
-rw-r--r--WebKit/android/WebCoreSupport/WebResponse.h2
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp48
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.h13
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp68
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.h4
8 files changed, 157 insertions, 6 deletions
diff --git a/WebKit/android/WebCoreSupport/ChromiumIncludes.h b/WebKit/android/WebCoreSupport/ChromiumIncludes.h
index 1a69ff1..635c4da 100644
--- a/WebKit/android/WebCoreSupport/ChromiumIncludes.h
+++ b/WebKit/android/WebCoreSupport/ChromiumIncludes.h
@@ -50,9 +50,11 @@
#include <base/message_loop_proxy.h>
#include <base/ref_counted.h>
#include <base/string_util.h>
+#include <base/sys_string_conversions.h>
#include <base/thread.h>
#include <base/tuple.h>
#include <chrome/browser/net/sqlite_persistent_cookie_store.h>
+#include <net/base/auth.h>
#include <net/base/cookie_monster.h>
#include <net/base/data_url.h>
#include <net/base/io_buffer.h>
diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp
index 10b0cc7..e440181 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequest.cpp
@@ -295,9 +295,11 @@ void WebRequest::OnReceivedRedirect(URLRequest* newRequest, const GURL& newUrl,
// of On* callbacks.
void WebRequest::OnAuthRequired(URLRequest* request, net::AuthChallengeInfo* authInfo)
{
- // TODO: This is the default action, have to implement getting the
- // username and password from webkit
- request->CancelAuth();
+ ASSERT(m_loadState == Started, "OnAuthRequired called on a WebRequest not in STARTED state (state=%d)", m_loadState);
+
+ LoaderData* ld = new LoaderData(m_urlLoader);
+ ld->authChallengeInfo = authInfo;
+ m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::authRequired, ld);
}
// After calling Start(), the delegate will receive an OnResponseStarted
@@ -323,6 +325,20 @@ void WebRequest::OnResponseStarted(URLRequest* request)
}
}
+void WebRequest::setAuth(const std::wstring& username, const std::wstring& password)
+{
+ ASSERT(m_loadState == Started, "setAuth called on a WebRequest not in STARTED state (state=%d)", m_loadState);
+
+ m_request->SetAuth(username, password);
+}
+
+void WebRequest::cancelAuth()
+{
+ ASSERT(m_loadState == Started, "cancelAuth called on a WebRequest not in STARTED state (state=%d)", m_loadState);
+
+ m_request->CancelAuth();
+}
+
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 c5a101b..987d8ae 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.h
+++ b/WebKit/android/WebCoreSupport/WebRequest.h
@@ -69,6 +69,10 @@ public:
virtual void OnReadCompleted(URLRequest*, int bytesRead);
virtual void OnAuthRequired(URLRequest*, net::AuthChallengeInfo*);
+ // Methods called during a request by the UI code (via WebUrlLoaderClient).
+ void setAuth(const std::wstring& username, const std::wstring& password);
+ void cancelAuth();
+
private:
void startReading();
bool read(int* bytesRead);
diff --git a/WebKit/android/WebCoreSupport/WebResponse.h b/WebKit/android/WebCoreSupport/WebResponse.h
index 8fe65a8..fc90bf1 100644
--- a/WebKit/android/WebCoreSupport/WebResponse.h
+++ b/WebKit/android/WebCoreSupport/WebResponse.h
@@ -37,6 +37,8 @@ class ResourceResponse;
class ResourceError;
}
+class URLRequest;
+
namespace android {
class WebResponse {
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
index 6e1aa76..626b7f4 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
@@ -92,7 +92,8 @@ bool WebUrlLoaderClient::isActive() const
}
WebUrlLoaderClient::WebUrlLoaderClient(WebFrame* webFrame, WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest)
- : m_resourceHandle(resourceHandle)
+ : m_webFrame(webFrame)
+ , m_resourceHandle(resourceHandle)
, m_cancelling(false)
, m_sync(false)
, m_finished(false)
@@ -189,6 +190,26 @@ void WebUrlLoaderClient::cancel()
thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::cancel));
}
+void WebUrlLoaderClient::setAuth(const std::string& username, const std::string& password)
+{
+ base::Thread* thread = ioThread();
+ if (!thread) {
+ return;
+ }
+ std::wstring wUsername = base::SysUTF8ToWide(username);
+ std::wstring wPassword = base::SysUTF8ToWide(password);
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::setAuth, wUsername, wPassword));
+}
+
+void WebUrlLoaderClient::cancelAuth()
+{
+ base::Thread* thread = ioThread();
+ if (!thread) {
+ return;
+ }
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::cancelAuth));
+}
+
void WebUrlLoaderClient::finish()
{
m_finished = true;
@@ -200,7 +221,8 @@ void WebUrlLoaderClient::finish()
}
// This is called from the IO thread, and dispatches the callback to the main thread.
-void WebUrlLoaderClient::maybeCallOnMainThread(CallbackFunction* function, void* context) {
+void WebUrlLoaderClient::maybeCallOnMainThread(CallbackFunction* function, void* context)
+{
if (m_sync) {
AutoLock autoLock(*syncLock());
if (m_queue.empty()) {
@@ -311,4 +333,26 @@ void WebUrlLoaderClient::didFinishLoading(void* data)
loader->finish();
}
+// static - on main thread
+void WebUrlLoaderClient::authRequired(void* data)
+{
+ OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data));
+ WebUrlLoaderClient* loader = loaderData->loader;
+
+ if (!loader->isActive()) {
+ return;
+ }
+
+ std::string host = base::SysWideToUTF8(loaderData->authChallengeInfo->host_and_port);
+ std::string realm = base::SysWideToUTF8(loaderData->authChallengeInfo->realm);
+
+ // TODO: Not clear whose responsibility it is to cache credentials. There's nothing
+ // in AuthChallengeInfo that seems suitable, so for safety we'll tell the UI *not*
+ // to use cached credentials. We may need to track this ourselves (pass "true" on
+ // the first call, then "false" for a second call if the credentials are rejected).
+ bool useCachedCredentials = false;
+
+ loader->m_webFrame->didReceiveAuthenticationChallenge(loader, host, realm, useCachedCredentials);
+}
+
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
index 92c7bb5..23086cd 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
@@ -26,6 +26,8 @@
#ifndef WebUrlLoaderClient_h
#define WebUrlLoaderClient_h
+#if USE(CHROME_NETWORK_STACK)
+
#include "ChromiumIncludes.h"
#include "RefCounted.h"
#include "WebResponse.h"
@@ -33,6 +35,8 @@
#include <string>
#include <deque>
+#include <string>
+#include <vector>
class Lock;
class ConditionVariable;
@@ -43,6 +47,7 @@ class Thread;
namespace net {
class IOBuffer;
+class AuthChallengeInfo;
}
namespace android {
@@ -67,6 +72,8 @@ public:
void cancel();
void downloadFile();
void pauseLoad(bool pause) {} // Android method, does nothing for now
+ void setAuth(const std::string& username, const std::string& password);
+ void cancelAuth();
typedef void CallbackFunction(void*);
@@ -82,12 +89,15 @@ public:
static void didFinishLoading(void*);
static void didFail(void*);
static void willSendRequest(void*);
+ static void authRequired(void*);
// Handle to the chrome IO thread
static base::Thread* ioThread();
private:
void finish();
+
+ WebFrame* m_webFrame;
RefPtr<WebCore::ResourceHandle> m_resourceHandle;
bool m_cancelling;
bool m_sync;
@@ -119,6 +129,7 @@ struct LoaderData {
const int size;
OwnPtr<std::string*> string;
OwnPtr<std::vector<char> > vector;
+ scoped_refptr<net::AuthChallengeInfo> authChallengeInfo;
LoaderData(WebUrlLoaderClient* l) : buffer(0), loader(l), size(0)
{
@@ -145,4 +156,6 @@ struct LoaderData {
} // namespace android
+#endif // USE(CHROME_NETWORK_STACK)
+
#endif
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index c1cb907..1d5eacb 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -83,6 +83,7 @@
#include "WebHistory.h"
#include "WebIconDatabase.h"
#include "WebFrameView.h"
+#include "WebUrlLoaderClient.h"
#include "WebViewCore.h"
#include "android_graphics.h"
#include "jni.h"
@@ -209,6 +210,7 @@ struct WebFrame::JavaBrowserFrame
jmethodID mDensity;
jmethodID mGetFileSize;
jmethodID mGetFile;
+ jmethodID mDidReceiveAuthenticationChallenge;
AutoJObject frame(JNIEnv* env) {
return getRealObject(env, mObj);
}
@@ -268,6 +270,8 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
mJavaFrame->mDensity = env->GetMethodID(clazz, "density","()F");
mJavaFrame->mGetFileSize = env->GetMethodID(clazz, "getFileSize", "(Ljava/lang/String;)I");
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");
LOG_ASSERT(mJavaFrame->mInputStreamForAndroidResource, "Could not find method inputStreamForAndroidResource");
LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource");
@@ -290,6 +294,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
LOG_ASSERT(mJavaFrame->mDensity, "Could not find method density");
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");
mUserAgent = WTF::String();
mUserInitiatedAction = false;
@@ -887,6 +892,24 @@ WebFrame::density() const
return dpi;
}
+void
+WebFrame::didReceiveAuthenticationChallenge(WebUrlLoaderClient* client, const std::string& host, const std::string& realm, bool useCachedCredentials)
+{
+#ifdef ANDROID_INSTRUMENT
+ TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
+#endif
+ JNIEnv* env = getJNIEnv();
+ int jHandle = reinterpret_cast<int>(client);
+ jstring jHost = env->NewStringUTF(host.c_str());
+ jstring jRealm = env->NewStringUTF(realm.c_str());
+
+ env->CallVoidMethod(mJavaFrame->frame(env).get(),
+ mJavaFrame->mDidReceiveAuthenticationChallenge, jHandle, jHost, jRealm, useCachedCredentials);
+ env->DeleteLocalRef(jHost);
+ env->DeleteLocalRef(jRealm);
+ checkException(env);
+}
+
// ----------------------------------------------------------------------------
static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision)
{
@@ -1756,6 +1779,45 @@ static void OrientationChanged(JNIEnv *env, jobject obj, int orientation)
pFrame->sendOrientationChangeEvent(orientation);
}
+static std::string jstringToStdString(JNIEnv* env, jstring jstr) {
+ jsize size = env->GetStringUTFLength(jstr);
+ jboolean isCopy;
+ const char* cstr = env->GetStringUTFChars(jstr, &isCopy);
+ std::string result(cstr, cstr + size);
+ env->ReleaseStringUTFChars(jstr, cstr);
+ return result;
+}
+
+#if USE(CHROME_NETWORK_STACK)
+
+static void AuthenticationProceed(JNIEnv *env, jobject obj, int handle, jstring jUsername, jstring jPassword)
+{
+ WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
+ std::string username = jstringToStdString(env, jUsername);
+ std::string password = jstringToStdString(env, jPassword);
+ client->setAuth(username, password);
+}
+
+static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle)
+{
+ WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle);
+ client->cancelAuth();
+}
+
+#else
+
+static void AuthenticationProceed(JNIEnv *env, jobject obj, int handle, jstring jUsername, jstring jPassword)
+{
+ LOGW("Chromium authentication API called, but libchromium is not available");
+}
+
+static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle)
+{
+ LOGW("Chromium authentication API called, but libchromium is not available");
+}
+
+#endif // USE(CHROME_NETWORK_STACK)
+
// ----------------------------------------------------------------------------
/*
@@ -1811,7 +1873,11 @@ static JNINativeMethod gBrowserFrameNativeMethods[] = {
{ "getFormTextData", "()Ljava/util/HashMap;",
(void*) GetFormTextData },
{ "nativeOrientationChanged", "(I)V",
- (void*) OrientationChanged }
+ (void*) OrientationChanged },
+ { "nativeAuthenticationProceed", "(ILjava/lang/String;Ljava/lang/String;)V",
+ (void*) AuthenticationProceed },
+ { "nativeAuthenticationCancel", "(I)V",
+ (void*) AuthenticationCancel },
};
int register_webframe(JNIEnv* env)
diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h
index 2b323e1..bcbbb47 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.h
+++ b/WebKit/android/jni/WebCoreFrameBridge.h
@@ -33,6 +33,7 @@
#include "PlatformString.h"
#include "WebCoreRefObject.h"
#include <jni.h>
+#include <string>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -48,6 +49,7 @@ namespace WebCore {
namespace android {
class WebViewCore;
+class WebUrlLoaderClient;
// one instance of WebFrame per Page for calling into Java's BrowserFrame
class WebFrame : public WebCoreRefObject {
@@ -109,6 +111,8 @@ class WebFrame : public WebCoreRefObject {
float density() const;
+ void didReceiveAuthenticationChallenge(WebUrlLoaderClient*, const std::string& host, const std::string& realm, bool useCachedCredentials);
+
/**
* When the user initiates an action (via trackball, key-press, or touch),
* we set mUserInitiatedAction to true. If a load happens due to this click,