| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "android_webview/native/android_protocol_handler.h" | 5 #include "android_webview/native/android_protocol_handler.h" |
| 6 | 6 |
| 7 #include "android_webview/browser/net/android_stream_reader_url_request_job.h" | 7 #include "android_webview/browser/net/android_stream_reader_url_request_job.h" |
| 8 #include "android_webview/browser/net/aw_url_request_job_factory.h" | 8 #include "android_webview/browser/net/aw_url_request_job_factory.h" |
| 9 #include "android_webview/common/url_constants.h" | 9 #include "android_webview/common/url_constants.h" |
| 10 #include "android_webview/native/input_stream_impl.h" | 10 #include "android_webview/native/input_stream_impl.h" |
| 11 #include "base/android/jni_android.h" | 11 #include "base/android/jni_android.h" |
| 12 #include "base/android/jni_string.h" | 12 #include "base/android/jni_string.h" |
| 13 #include "base/android/jni_weak_ref.h" | 13 #include "base/android/jni_weak_ref.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "content/public/common/url_constants.h" | 15 #include "content/public/common/url_constants.h" |
| 16 #include "jni/AndroidProtocolHandler_jni.h" | 16 #include "jni/AndroidProtocolHandler_jni.h" |
| 17 #include "net/base/io_buffer.h" | 17 #include "net/base/io_buffer.h" |
| 18 #include "net/base/mime_util.h" | 18 #include "net/base/mime_util.h" |
| 19 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
| 20 #include "net/base/net_util.h" | 20 #include "net/base/net_util.h" |
| 21 #include "net/http/http_util.h" | 21 #include "net/http/http_util.h" |
| 22 #include "net/url_request/protocol_intercept_job_factory.h" | |
| 23 #include "net/url_request/url_request.h" | 22 #include "net/url_request/url_request.h" |
| 23 #include "net/url_request/url_request_interceptor.h" |
| 24 #include "url/gurl.h" | 24 #include "url/gurl.h" |
| 25 | 25 |
| 26 using android_webview::InputStream; | 26 using android_webview::InputStream; |
| 27 using android_webview::InputStreamImpl; | 27 using android_webview::InputStreamImpl; |
| 28 using base::android::AttachCurrentThread; | 28 using base::android::AttachCurrentThread; |
| 29 using base::android::ClearException; | 29 using base::android::ClearException; |
| 30 using base::android::ConvertUTF8ToJavaString; | 30 using base::android::ConvertUTF8ToJavaString; |
| 31 using base::android::ScopedJavaGlobalRef; | 31 using base::android::ScopedJavaGlobalRef; |
| 32 using base::android::ScopedJavaLocalRef; | 32 using base::android::ScopedJavaLocalRef; |
| 33 | 33 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 std::string* mime_type) OVERRIDE; | 73 std::string* mime_type) OVERRIDE; |
| 74 | 74 |
| 75 virtual bool GetCharset(JNIEnv* env, | 75 virtual bool GetCharset(JNIEnv* env, |
| 76 net::URLRequest* request, | 76 net::URLRequest* request, |
| 77 InputStream* stream, | 77 InputStream* stream, |
| 78 std::string* charset) OVERRIDE; | 78 std::string* charset) OVERRIDE; |
| 79 | 79 |
| 80 virtual ~AndroidStreamReaderURLRequestJobDelegateImpl(); | 80 virtual ~AndroidStreamReaderURLRequestJobDelegateImpl(); |
| 81 }; | 81 }; |
| 82 | 82 |
| 83 class AndroidProtocolHandlerBase : | 83 class AndroidRequestInterceptorBase : public net::URLRequestInterceptor { |
| 84 public net::URLRequestJobFactory::ProtocolHandler { | |
| 85 public: | 84 public: |
| 86 virtual net::URLRequestJob* MaybeCreateJob( | 85 virtual net::URLRequestJob* MaybeInterceptRequest( |
| 87 net::URLRequest* request, | 86 net::URLRequest* request, |
| 88 net::NetworkDelegate* network_delegate) const OVERRIDE; | 87 net::NetworkDelegate* network_delegate) const OVERRIDE; |
| 89 | 88 |
| 90 virtual bool CanHandleRequest(const net::URLRequest* request) const = 0; | 89 virtual bool ShouldHandleRequest(const net::URLRequest* request) const = 0; |
| 91 }; | 90 }; |
| 92 | 91 |
| 93 class AssetFileProtocolHandler : public AndroidProtocolHandlerBase { | 92 class AssetFileRequestInterceptor : public AndroidRequestInterceptorBase { |
| 94 public: | 93 public: |
| 95 AssetFileProtocolHandler(); | 94 AssetFileRequestInterceptor(); |
| 96 | 95 |
| 97 virtual ~AssetFileProtocolHandler() OVERRIDE; | 96 virtual ~AssetFileRequestInterceptor() OVERRIDE; |
| 98 virtual bool CanHandleRequest(const net::URLRequest* request) const OVERRIDE; | 97 virtual bool ShouldHandleRequest( |
| 98 const net::URLRequest* request) const OVERRIDE; |
| 99 | 99 |
| 100 private: | 100 private: |
| 101 // file:///android_asset/ | 101 // file:///android_asset/ |
| 102 const std::string asset_prefix_; | 102 const std::string asset_prefix_; |
| 103 // file:///android_res/ | 103 // file:///android_res/ |
| 104 const std::string resource_prefix_; | 104 const std::string resource_prefix_; |
| 105 }; | 105 }; |
| 106 | 106 |
| 107 // Protocol handler for content:// scheme requests. | 107 // Protocol handler for content:// scheme requests. |
| 108 class ContentSchemeProtocolHandler : public AndroidProtocolHandlerBase { | 108 class ContentSchemeRequestInterceptor : public AndroidRequestInterceptorBase { |
| 109 public: | 109 public: |
| 110 ContentSchemeProtocolHandler(); | 110 ContentSchemeRequestInterceptor(); |
| 111 virtual bool CanHandleRequest(const net::URLRequest* request) const OVERRIDE; | 111 virtual bool ShouldHandleRequest( |
| 112 const net::URLRequest* request) const OVERRIDE; |
| 112 }; | 113 }; |
| 113 | 114 |
| 114 static ScopedJavaLocalRef<jobject> GetResourceContext(JNIEnv* env) { | 115 static ScopedJavaLocalRef<jobject> GetResourceContext(JNIEnv* env) { |
| 115 if (g_resource_context) | 116 if (g_resource_context) |
| 116 return g_resource_context->get(env); | 117 return g_resource_context->get(env); |
| 117 ScopedJavaLocalRef<jobject> context; | 118 ScopedJavaLocalRef<jobject> context; |
| 118 // We have to reset as GetApplicationContext() returns a jobject with a | 119 // We have to reset as GetApplicationContext() returns a jobject with a |
| 119 // global ref. The constructor that takes a jobject would expect a local ref | 120 // global ref. The constructor that takes a jobject would expect a local ref |
| 120 // and would assert. | 121 // and would assert. |
| 121 context.Reset(env, base::android::GetApplicationContext()); | 122 context.Reset(env, base::android::GetApplicationContext()); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 | 191 |
| 191 bool AndroidStreamReaderURLRequestJobDelegateImpl::GetCharset( | 192 bool AndroidStreamReaderURLRequestJobDelegateImpl::GetCharset( |
| 192 JNIEnv* env, | 193 JNIEnv* env, |
| 193 net::URLRequest* request, | 194 net::URLRequest* request, |
| 194 android_webview::InputStream* stream, | 195 android_webview::InputStream* stream, |
| 195 std::string* charset) { | 196 std::string* charset) { |
| 196 // TODO: We should probably be getting this from the managed side. | 197 // TODO: We should probably be getting this from the managed side. |
| 197 return false; | 198 return false; |
| 198 } | 199 } |
| 199 | 200 |
| 200 // AndroidProtocolHandlerBase ------------------------------------------------- | 201 // AndroidRequestInterceptorBase ---------------------------------------------- |
| 201 | 202 |
| 202 net::URLRequestJob* AndroidProtocolHandlerBase::MaybeCreateJob( | 203 net::URLRequestJob* AndroidRequestInterceptorBase::MaybeInterceptRequest( |
| 203 net::URLRequest* request, | 204 net::URLRequest* request, |
| 204 net::NetworkDelegate* network_delegate) const { | 205 net::NetworkDelegate* network_delegate) const { |
| 205 if (!CanHandleRequest(request)) return NULL; | 206 if (!ShouldHandleRequest(request)) |
| 207 return NULL; |
| 206 | 208 |
| 207 // For WebViewClassic compatibility this job can only accept URLs that can be | 209 // For WebViewClassic compatibility this job can only accept URLs that can be |
| 208 // opened. URLs that cannot be opened should be resolved by the next handler. | 210 // opened. URLs that cannot be opened should be resolved by the next handler. |
| 209 // | 211 // |
| 210 // If a request is initially handled here but the job fails due to it being | 212 // If a request is initially handled here but the job fails due to it being |
| 211 // unable to open the InputStream for that request the request is marked as | 213 // unable to open the InputStream for that request the request is marked as |
| 212 // previously failed and restarted. | 214 // previously failed and restarted. |
| 213 // Restarting a request involves creating a new job for that request. This | 215 // Restarting a request involves creating a new job for that request. This |
| 214 // handler will ignore requests know to have previously failed to 1) prevent | 216 // handler will ignore requests know to have previously failed to 1) prevent |
| 215 // an infinite loop, 2) ensure that the next handler in line gets the | 217 // an infinite loop, 2) ensure that the next handler in line gets the |
| 216 // opportunity to create a job for the request. | 218 // opportunity to create a job for the request. |
| 217 if (HasRequestPreviouslyFailed(request)) return NULL; | 219 if (HasRequestPreviouslyFailed(request)) |
| 220 return NULL; |
| 218 | 221 |
| 219 scoped_ptr<AndroidStreamReaderURLRequestJobDelegateImpl> reader_delegate( | 222 scoped_ptr<AndroidStreamReaderURLRequestJobDelegateImpl> reader_delegate( |
| 220 new AndroidStreamReaderURLRequestJobDelegateImpl()); | 223 new AndroidStreamReaderURLRequestJobDelegateImpl()); |
| 221 | 224 |
| 222 return new AndroidStreamReaderURLRequestJob( | 225 return new AndroidStreamReaderURLRequestJob( |
| 223 request, | 226 request, |
| 224 network_delegate, | 227 network_delegate, |
| 225 reader_delegate.PassAs<AndroidStreamReaderURLRequestJob::Delegate>()); | 228 reader_delegate.PassAs<AndroidStreamReaderURLRequestJob::Delegate>()); |
| 226 } | 229 } |
| 227 | 230 |
| 228 // AssetFileProtocolHandler --------------------------------------------------- | 231 // AssetFileRequestInterceptor ------------------------------------------------ |
| 229 | 232 |
| 230 AssetFileProtocolHandler::AssetFileProtocolHandler() | 233 AssetFileRequestInterceptor::AssetFileRequestInterceptor() |
| 231 : asset_prefix_(std::string(content::kFileScheme) + | 234 : asset_prefix_(std::string(content::kFileScheme) + |
| 232 std::string(content::kStandardSchemeSeparator) + | 235 std::string(content::kStandardSchemeSeparator) + |
| 233 android_webview::kAndroidAssetPath), | 236 android_webview::kAndroidAssetPath), |
| 234 resource_prefix_(std::string(content::kFileScheme) + | 237 resource_prefix_(std::string(content::kFileScheme) + |
| 235 std::string(content::kStandardSchemeSeparator) + | 238 std::string(content::kStandardSchemeSeparator) + |
| 236 android_webview::kAndroidResourcePath) { | 239 android_webview::kAndroidResourcePath) { |
| 237 } | 240 } |
| 238 | 241 |
| 239 AssetFileProtocolHandler::~AssetFileProtocolHandler() { | 242 AssetFileRequestInterceptor::~AssetFileRequestInterceptor() { |
| 240 } | 243 } |
| 241 | 244 |
| 242 bool AssetFileProtocolHandler::CanHandleRequest( | 245 bool AssetFileRequestInterceptor::ShouldHandleRequest( |
| 243 const net::URLRequest* request) const { | 246 const net::URLRequest* request) const { |
| 244 if (!request->url().SchemeIsFile()) | 247 if (!request->url().SchemeIsFile()) |
| 245 return false; | 248 return false; |
| 246 | 249 |
| 247 const std::string& url = request->url().spec(); | 250 const std::string& url = request->url().spec(); |
| 248 if (!StartsWithASCII(url, asset_prefix_, /*case_sensitive=*/ true) && | 251 if (!StartsWithASCII(url, asset_prefix_, /*case_sensitive=*/ true) && |
| 249 !StartsWithASCII(url, resource_prefix_, /*case_sensitive=*/ true)) { | 252 !StartsWithASCII(url, resource_prefix_, /*case_sensitive=*/ true)) { |
| 250 return false; | 253 return false; |
| 251 } | 254 } |
| 252 | 255 |
| 253 return true; | 256 return true; |
| 254 } | 257 } |
| 255 | 258 |
| 256 // ContentSchemeProtocolHandler ----------------------------------------------- | 259 // ContentSchemeRequestInterceptor -------------------------------------------- |
| 257 | 260 |
| 258 ContentSchemeProtocolHandler::ContentSchemeProtocolHandler() { | 261 ContentSchemeRequestInterceptor::ContentSchemeRequestInterceptor() { |
| 259 } | 262 } |
| 260 | 263 |
| 261 bool ContentSchemeProtocolHandler::CanHandleRequest( | 264 bool ContentSchemeRequestInterceptor::ShouldHandleRequest( |
| 262 const net::URLRequest* request) const { | 265 const net::URLRequest* request) const { |
| 263 return request->url().SchemeIs(android_webview::kContentScheme); | 266 return request->url().SchemeIs(android_webview::kContentScheme); |
| 264 } | 267 } |
| 265 | 268 |
| 266 } // namespace | 269 } // namespace |
| 267 | 270 |
| 268 namespace android_webview { | 271 namespace android_webview { |
| 269 | 272 |
| 270 bool RegisterAndroidProtocolHandler(JNIEnv* env) { | 273 bool RegisterAndroidProtocolHandler(JNIEnv* env) { |
| 271 return RegisterNativesImpl(env); | 274 return RegisterNativesImpl(env); |
| 272 } | 275 } |
| 273 | 276 |
| 274 // static | 277 // static |
| 275 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> | 278 scoped_ptr<net::URLRequestInterceptor> |
| 276 CreateContentSchemeProtocolHandler() { | 279 CreateContentSchemeRequestInterceptor() { |
| 277 return make_scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>( | 280 return make_scoped_ptr<net::URLRequestInterceptor>( |
| 278 new ContentSchemeProtocolHandler()); | 281 new ContentSchemeRequestInterceptor()); |
| 279 } | 282 } |
| 280 | 283 |
| 281 // static | 284 // static |
| 282 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> | 285 scoped_ptr<net::URLRequestInterceptor> CreateAssetFileRequestInterceptor() { |
| 283 CreateAssetFileProtocolHandler() { | 286 return scoped_ptr<net::URLRequestInterceptor>( |
| 284 return make_scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>( | 287 new AssetFileRequestInterceptor()); |
| 285 new AssetFileProtocolHandler()); | |
| 286 } | 288 } |
| 287 | 289 |
| 288 // Set a context object to be used for resolving resource queries. This can | 290 // Set a context object to be used for resolving resource queries. This can |
| 289 // be used to override the default application context and redirect all | 291 // be used to override the default application context and redirect all |
| 290 // resource queries to a specific context object, e.g., for the purposes of | 292 // resource queries to a specific context object, e.g., for the purposes of |
| 291 // testing. | 293 // testing. |
| 292 // | 294 // |
| 293 // |context| should be a android.content.Context instance or NULL to enable | 295 // |context| should be a android.content.Context instance or NULL to enable |
| 294 // the use of the standard application context. | 296 // the use of the standard application context. |
| 295 static void SetResourceContextForTesting(JNIEnv* env, jclass /*clazz*/, | 297 static void SetResourceContextForTesting(JNIEnv* env, jclass /*clazz*/, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 307 env, android_webview::kAndroidAssetPath).Release(); | 309 env, android_webview::kAndroidAssetPath).Release(); |
| 308 } | 310 } |
| 309 | 311 |
| 310 static jstring GetAndroidResourcePath(JNIEnv* env, jclass /*clazz*/) { | 312 static jstring GetAndroidResourcePath(JNIEnv* env, jclass /*clazz*/) { |
| 311 // OK to release, JNI binding. | 313 // OK to release, JNI binding. |
| 312 return ConvertUTF8ToJavaString( | 314 return ConvertUTF8ToJavaString( |
| 313 env, android_webview::kAndroidResourcePath).Release(); | 315 env, android_webview::kAndroidResourcePath).Release(); |
| 314 } | 316 } |
| 315 | 317 |
| 316 } // namespace android_webview | 318 } // namespace android_webview |
| OLD | NEW |