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

Unified Diff: android_webview/native/android_protocol_handler.cc

Issue 12377051: [android_webview] Don't intercept resource and asset URLRequests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 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: android_webview/native/android_protocol_handler.cc
diff --git a/android_webview/native/android_protocol_handler.cc b/android_webview/native/android_protocol_handler.cc
index 907881bae85822301eb9d1d435e0c8d1e23f7443..7705e8461f30074767a8cbf0356fcf817173af1d 100644
--- a/android_webview/native/android_protocol_handler.cc
+++ b/android_webview/native/android_protocol_handler.cc
@@ -44,6 +44,17 @@ void ResetResourceContext(JavaObjectWeakGlobalRef* ref) {
g_resource_context = ref;
}
+void* kPreviouslyFailedKey = &kPreviouslyFailedKey;
+
+void MarkRequestAsFailed(net::URLRequest* request) {
+ request->SetUserData(kPreviouslyFailedKey,
+ new base::SupportsUserData::Data());
+}
+
+bool HasRequestPreviouslyFailed(net::URLRequest* request) {
+ return request->GetUserData(kPreviouslyFailedKey) != NULL;
+}
+
class AndroidStreamReaderURLRequestJobDelegateImpl
: public AndroidStreamReaderURLRequestJob::Delegate {
public:
@@ -51,7 +62,10 @@ class AndroidStreamReaderURLRequestJobDelegateImpl
virtual scoped_ptr<InputStream> OpenInputStream(
JNIEnv* env,
- net::URLRequest* request) OVERRIDE;
+ const GURL& url) OVERRIDE;
+
+ virtual void OnInputStreamOpenFailed(net::URLRequest* request,
+ bool* restart) OVERRIDE;
virtual bool GetMimeType(JNIEnv* env,
net::URLRequest* request,
@@ -66,19 +80,24 @@ class AndroidStreamReaderURLRequestJobDelegateImpl
virtual ~AndroidStreamReaderURLRequestJobDelegateImpl();
};
-class AssetFileProtocolInterceptor :
- public net::URLRequestJobFactory::ProtocolHandler {
+class AndroidProtocolHandlerBase :
+ public net::URLRequestJobFactory::ProtocolHandler {
public:
- virtual ~AssetFileProtocolInterceptor() OVERRIDE;
- static scoped_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
- scoped_ptr<net::URLRequestJobFactory> base_job_factory);
virtual net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const OVERRIDE;
- private:
- AssetFileProtocolInterceptor();
+ virtual bool CanHandleRequest(const net::URLRequest* request) const = 0;
+};
+
+class AssetFileProtocolHandler : public AndroidProtocolHandlerBase {
+ public:
+ AssetFileProtocolHandler();
+ virtual ~AssetFileProtocolHandler() OVERRIDE;
+ virtual bool CanHandleRequest(const net::URLRequest* request) const OVERRIDE;
+
+ private:
// file:///android_asset/
const std::string asset_prefix_;
// file:///android_res/
@@ -86,21 +105,10 @@ class AssetFileProtocolInterceptor :
};
// Protocol handler for content:// scheme requests.
-class ContentSchemeProtocolHandler :
- public net::URLRequestJobFactory::ProtocolHandler {
+class ContentSchemeProtocolHandler : public AndroidProtocolHandlerBase {
public:
- ContentSchemeProtocolHandler() {}
-
- virtual net::URLRequestJob* MaybeCreateJob(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const OVERRIDE {
- DCHECK(request->url().SchemeIs(android_webview::kContentScheme));
- return new AndroidStreamReaderURLRequestJob(
- request,
- network_delegate,
- scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>(
- new AndroidStreamReaderURLRequestJobDelegateImpl()));
- }
+ ContentSchemeProtocolHandler();
+ virtual bool CanHandleRequest(const net::URLRequest* request) const OVERRIDE;
};
static ScopedJavaLocalRef<jobject> GetResourceContext(JNIEnv* env) {
@@ -114,9 +122,10 @@ static ScopedJavaLocalRef<jobject> GetResourceContext(JNIEnv* env) {
return context;
}
+// AndroidStreamReaderURLRequestJobDelegateImpl -------------------------------
+
AndroidStreamReaderURLRequestJobDelegateImpl::
-AndroidStreamReaderURLRequestJobDelegateImpl() {
-}
+ AndroidStreamReaderURLRequestJobDelegateImpl() {}
AndroidStreamReaderURLRequestJobDelegateImpl::
~AndroidStreamReaderURLRequestJobDelegateImpl() {
@@ -124,18 +133,18 @@ AndroidStreamReaderURLRequestJobDelegateImpl::
scoped_ptr<InputStream>
AndroidStreamReaderURLRequestJobDelegateImpl::OpenInputStream(
- JNIEnv* env, net::URLRequest* request) {
- DCHECK(request);
+ JNIEnv* env, const GURL& url) {
+ DCHECK(url.is_valid());
DCHECK(env);
// Open the input stream.
- ScopedJavaLocalRef<jstring> url =
- ConvertUTF8ToJavaString(env, request->url().spec());
+ ScopedJavaLocalRef<jstring> jurl =
+ ConvertUTF8ToJavaString(env, url.spec());
ScopedJavaLocalRef<jobject> stream =
android_webview::Java_AndroidProtocolHandler_open(
env,
GetResourceContext(env).obj(),
- url.obj());
+ jurl.obj());
// Check and clear pending exceptions.
if (ClearException(env) || stream.is_null()) {
@@ -145,6 +154,14 @@ AndroidStreamReaderURLRequestJobDelegateImpl::OpenInputStream(
return make_scoped_ptr<InputStream>(new InputStreamImpl(stream));
}
+void AndroidStreamReaderURLRequestJobDelegateImpl::OnInputStreamOpenFailed(
+ net::URLRequest* request,
+ bool* restart) {
+ DCHECK(!HasRequestPreviouslyFailed(request));
+ MarkRequestAsFailed(request);
+ *restart = true;
+}
+
bool AndroidStreamReaderURLRequestJobDelegateImpl::GetMimeType(
JNIEnv* env,
net::URLRequest* request,
@@ -181,7 +198,37 @@ bool AndroidStreamReaderURLRequestJobDelegateImpl::GetCharset(
return false;
}
-AssetFileProtocolInterceptor::AssetFileProtocolInterceptor()
+// AndroidProtocolHandlerBase -------------------------------------------------
+
+net::URLRequestJob* AndroidProtocolHandlerBase::MaybeCreateJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const {
+ if (!CanHandleRequest(request)) return NULL;
+
+ // For WebViewClassic compatibility this job can only accept URLs that can be
+ // opened. URLs that cannot be opened should be resolved by the next handler.
+ //
+ // If a request is initially handled here but the job fails due to it being
+ // unable to open the InputStream for that request the request is marked as
+ // previously failed and restarted.
+ // Restarting a request involves creating a new job for that request. This
+ // handler will ignore requests know to have previously failed to 1) prevent
+ // an infinite loop, 2) ensure that the next handler in line gets the
+ // opportunity to create a job for the request.
+ if (HasRequestPreviouslyFailed(request)) return NULL;
+
+ scoped_ptr<AndroidStreamReaderURLRequestJobDelegateImpl> reader_delegate(
+ new AndroidStreamReaderURLRequestJobDelegateImpl());
+
+ return new AndroidStreamReaderURLRequestJob(
+ request,
+ network_delegate,
+ reader_delegate.PassAs<AndroidStreamReaderURLRequestJob::Delegate>());
+}
+
+// AssetFileProtocolHandler ---------------------------------------------------
+
+AssetFileProtocolHandler::AssetFileProtocolHandler()
: asset_prefix_(std::string(chrome::kFileScheme) +
std::string(content::kStandardSchemeSeparator) +
android_webview::kAndroidAssetPath),
@@ -190,36 +237,31 @@ AssetFileProtocolInterceptor::AssetFileProtocolInterceptor()
android_webview::kAndroidResourcePath) {
}
-AssetFileProtocolInterceptor::~AssetFileProtocolInterceptor() {
+AssetFileProtocolHandler::~AssetFileProtocolHandler() {
}
-// static
-scoped_ptr<net::URLRequestJobFactory>
-AssetFileProtocolInterceptor::CreateURLRequestJobFactory(
- scoped_ptr<net::URLRequestJobFactory> base_job_factory) {
- scoped_ptr<net::URLRequestJobFactory> top_job_factory(
- new net::ProtocolInterceptJobFactory(
- base_job_factory.Pass(),
- scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(
- new AssetFileProtocolInterceptor())));
- return top_job_factory.Pass();
-}
-
-net::URLRequestJob* AssetFileProtocolInterceptor::MaybeCreateJob(
- net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
- if (!request->url().SchemeIsFile()) return NULL;
+bool AssetFileProtocolHandler::CanHandleRequest(
+ const net::URLRequest* request) const {
+ if (!request->url().SchemeIsFile())
+ return false;
const std::string& url = request->url().spec();
if (!StartsWithASCII(url, asset_prefix_, /*case_sensitive=*/ true) &&
- !StartsWithASCII(url, resource_prefix_, /*case_sensitive=*/ true)) {
- return NULL;
+ !StartsWithASCII(url, resource_prefix_, /*case_sensitive=*/ true)) {
+ return false;
}
- return new AndroidStreamReaderURLRequestJob(
- request,
- network_delegate,
- scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>(
- new AndroidStreamReaderURLRequestJobDelegateImpl()));
+ return true;
+}
+
+// ContentSchemeProtocolHandler -----------------------------------------------
+
+ContentSchemeProtocolHandler::ContentSchemeProtocolHandler() {
+}
+
+bool ContentSchemeProtocolHandler::CanHandleRequest(
+ const net::URLRequest* request) const {
+ return request->url().SchemeIs(android_webview::kContentScheme);
}
} // namespace
@@ -231,18 +273,17 @@ bool RegisterAndroidProtocolHandler(JNIEnv* env) {
}
// static
-scoped_ptr<net::URLRequestJobFactory> CreateAndroidRequestJobFactory(
- scoped_ptr<AwURLRequestJobFactory> job_factory) {
- // Register content://. Note that even though a scheme is
- // registered here, it cannot be used by child processes until access to it is
- // granted via ChildProcessSecurityPolicy::GrantScheme(). This is done in
- // AwContentBrowserClient.
- // The job factory takes ownership of the handler.
- bool set_protocol = job_factory->SetProtocolHandler(
- android_webview::kContentScheme, new ContentSchemeProtocolHandler());
- DCHECK(set_protocol);
- return AssetFileProtocolInterceptor::CreateURLRequestJobFactory(
- job_factory.PassAs<net::URLRequestJobFactory>());
+scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+CreateContentSchemeProtocolHandler() {
+ return make_scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(
+ new ContentSchemeProtocolHandler());
+}
+
+// static
+scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+CreateAssetFileProtocolHandler() {
+ return make_scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(
+ new AssetFileProtocolHandler());
}
// Set a context object to be used for resolving resource queries. This can
« no previous file with comments | « android_webview/native/android_protocol_handler.h ('k') | android_webview/native/intercepted_request_data_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698