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(url::kFileScheme) + | 234 : asset_prefix_(std::string(url::kFileScheme) + |
232 std::string(content::kStandardSchemeSeparator) + | 235 std::string(content::kStandardSchemeSeparator) + |
233 android_webview::kAndroidAssetPath), | 236 android_webview::kAndroidAssetPath), |
234 resource_prefix_(std::string(url::kFileScheme) + | 237 resource_prefix_(std::string(url::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 |