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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
(...skipping 26 matching lines...) Expand all
37 // testing. 37 // testing.
38 JavaObjectWeakGlobalRef* g_resource_context = NULL; 38 JavaObjectWeakGlobalRef* g_resource_context = NULL;
39 39
40 void ResetResourceContext(JavaObjectWeakGlobalRef* ref) { 40 void ResetResourceContext(JavaObjectWeakGlobalRef* ref) {
41 if (g_resource_context) 41 if (g_resource_context)
42 delete g_resource_context; 42 delete g_resource_context;
43 43
44 g_resource_context = ref; 44 g_resource_context = ref;
45 } 45 }
46 46
47 void* kPreviouslyFailedKey = &kPreviouslyFailedKey;
48
49 void MarkRequestAsFailed(net::URLRequest* request) {
50 request->SetUserData(kPreviouslyFailedKey,
51 new base::SupportsUserData::Data());
52 }
53
54 bool HasRequestPreviouslyFailed(net::URLRequest* request) {
55 return request->GetUserData(kPreviouslyFailedKey) != NULL;
56 }
57
47 class AndroidStreamReaderURLRequestJobDelegateImpl 58 class AndroidStreamReaderURLRequestJobDelegateImpl
48 : public AndroidStreamReaderURLRequestJob::Delegate { 59 : public AndroidStreamReaderURLRequestJob::Delegate {
49 public: 60 public:
50 AndroidStreamReaderURLRequestJobDelegateImpl(); 61 AndroidStreamReaderURLRequestJobDelegateImpl();
51 62
52 virtual scoped_ptr<InputStream> OpenInputStream( 63 virtual scoped_ptr<InputStream> OpenInputStream(
53 JNIEnv* env, 64 JNIEnv* env,
54 net::URLRequest* request) OVERRIDE; 65 const GURL& url) OVERRIDE;
66
67 virtual void OnInputStreamOpenFailed(net::URLRequest* request,
68 bool* restart) OVERRIDE;
55 69
56 virtual bool GetMimeType(JNIEnv* env, 70 virtual bool GetMimeType(JNIEnv* env,
57 net::URLRequest* request, 71 net::URLRequest* request,
58 InputStream* stream, 72 InputStream* stream,
59 std::string* mime_type) OVERRIDE; 73 std::string* mime_type) OVERRIDE;
60 74
61 virtual bool GetCharset(JNIEnv* env, 75 virtual bool GetCharset(JNIEnv* env,
62 net::URLRequest* request, 76 net::URLRequest* request,
63 InputStream* stream, 77 InputStream* stream,
64 std::string* charset) OVERRIDE; 78 std::string* charset) OVERRIDE;
65 79
66 virtual ~AndroidStreamReaderURLRequestJobDelegateImpl(); 80 virtual ~AndroidStreamReaderURLRequestJobDelegateImpl();
67 }; 81 };
68 82
69 class AssetFileProtocolInterceptor : 83 class AndroidProtocolHandlerBase :
70 public net::URLRequestJobFactory::ProtocolHandler { 84 public net::URLRequestJobFactory::ProtocolHandler {
71 public: 85 public:
72 virtual ~AssetFileProtocolInterceptor() OVERRIDE;
73 static scoped_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
74 scoped_ptr<net::URLRequestJobFactory> base_job_factory);
75 virtual net::URLRequestJob* MaybeCreateJob( 86 virtual net::URLRequestJob* MaybeCreateJob(
76 net::URLRequest* request, 87 net::URLRequest* request,
77 net::NetworkDelegate* network_delegate) const OVERRIDE; 88 net::NetworkDelegate* network_delegate) const OVERRIDE;
78 89
90 virtual bool CanHandleRequest(const net::URLRequest* request) const = 0;
91 };
92
93 class AssetFileProtocolHandler : public AndroidProtocolHandlerBase {
94 public:
95 AssetFileProtocolHandler();
96
97 virtual ~AssetFileProtocolHandler() OVERRIDE;
98 virtual bool CanHandleRequest(const net::URLRequest* request) const OVERRIDE;
99
79 private: 100 private:
80 AssetFileProtocolInterceptor();
81
82 // file:///android_asset/ 101 // file:///android_asset/
83 const std::string asset_prefix_; 102 const std::string asset_prefix_;
84 // file:///android_res/ 103 // file:///android_res/
85 const std::string resource_prefix_; 104 const std::string resource_prefix_;
86 }; 105 };
87 106
88 // Protocol handler for content:// scheme requests. 107 // Protocol handler for content:// scheme requests.
89 class ContentSchemeProtocolHandler : 108 class ContentSchemeProtocolHandler : public AndroidProtocolHandlerBase {
90 public net::URLRequestJobFactory::ProtocolHandler {
91 public: 109 public:
92 ContentSchemeProtocolHandler() {} 110 ContentSchemeProtocolHandler();
93 111 virtual bool CanHandleRequest(const net::URLRequest* request) const OVERRIDE;
94 virtual net::URLRequestJob* MaybeCreateJob(
95 net::URLRequest* request,
96 net::NetworkDelegate* network_delegate) const OVERRIDE {
97 DCHECK(request->url().SchemeIs(android_webview::kContentScheme));
98 return new AndroidStreamReaderURLRequestJob(
99 request,
100 network_delegate,
101 scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>(
102 new AndroidStreamReaderURLRequestJobDelegateImpl()));
103 }
104 }; 112 };
105 113
106 static ScopedJavaLocalRef<jobject> GetResourceContext(JNIEnv* env) { 114 static ScopedJavaLocalRef<jobject> GetResourceContext(JNIEnv* env) {
107 if (g_resource_context) 115 if (g_resource_context)
108 return g_resource_context->get(env); 116 return g_resource_context->get(env);
109 ScopedJavaLocalRef<jobject> context; 117 ScopedJavaLocalRef<jobject> context;
110 // We have to reset as GetApplicationContext() returns a jobject with a 118 // We have to reset as GetApplicationContext() returns a jobject with a
111 // global ref. The constructor that takes a jobject would expect a local ref 119 // global ref. The constructor that takes a jobject would expect a local ref
112 // and would assert. 120 // and would assert.
113 context.Reset(env, base::android::GetApplicationContext()); 121 context.Reset(env, base::android::GetApplicationContext());
114 return context; 122 return context;
115 } 123 }
116 124
125 // AndroidStreamReaderURLRequestJobDelegateImpl -------------------------------
126
117 AndroidStreamReaderURLRequestJobDelegateImpl:: 127 AndroidStreamReaderURLRequestJobDelegateImpl::
118 AndroidStreamReaderURLRequestJobDelegateImpl() { 128 AndroidStreamReaderURLRequestJobDelegateImpl() {}
119 }
120 129
121 AndroidStreamReaderURLRequestJobDelegateImpl:: 130 AndroidStreamReaderURLRequestJobDelegateImpl::
122 ~AndroidStreamReaderURLRequestJobDelegateImpl() { 131 ~AndroidStreamReaderURLRequestJobDelegateImpl() {
123 } 132 }
124 133
125 scoped_ptr<InputStream> 134 scoped_ptr<InputStream>
126 AndroidStreamReaderURLRequestJobDelegateImpl::OpenInputStream( 135 AndroidStreamReaderURLRequestJobDelegateImpl::OpenInputStream(
127 JNIEnv* env, net::URLRequest* request) { 136 JNIEnv* env, const GURL& url) {
128 DCHECK(request); 137 DCHECK(url.is_valid());
129 DCHECK(env); 138 DCHECK(env);
130 139
131 // Open the input stream. 140 // Open the input stream.
132 ScopedJavaLocalRef<jstring> url = 141 ScopedJavaLocalRef<jstring> jurl =
133 ConvertUTF8ToJavaString(env, request->url().spec()); 142 ConvertUTF8ToJavaString(env, url.spec());
134 ScopedJavaLocalRef<jobject> stream = 143 ScopedJavaLocalRef<jobject> stream =
135 android_webview::Java_AndroidProtocolHandler_open( 144 android_webview::Java_AndroidProtocolHandler_open(
136 env, 145 env,
137 GetResourceContext(env).obj(), 146 GetResourceContext(env).obj(),
138 url.obj()); 147 jurl.obj());
139 148
140 // Check and clear pending exceptions. 149 // Check and clear pending exceptions.
141 if (ClearException(env) || stream.is_null()) { 150 if (ClearException(env) || stream.is_null()) {
142 DLOG(ERROR) << "Unable to open input stream for Android URL"; 151 DLOG(ERROR) << "Unable to open input stream for Android URL";
143 return scoped_ptr<InputStream>(); 152 return scoped_ptr<InputStream>();
144 } 153 }
145 return make_scoped_ptr<InputStream>(new InputStreamImpl(stream)); 154 return make_scoped_ptr<InputStream>(new InputStreamImpl(stream));
146 } 155 }
147 156
157 void AndroidStreamReaderURLRequestJobDelegateImpl::OnInputStreamOpenFailed(
158 net::URLRequest* request,
159 bool* restart) {
160 DCHECK(!HasRequestPreviouslyFailed(request));
161 MarkRequestAsFailed(request);
162 *restart = true;
163 }
164
148 bool AndroidStreamReaderURLRequestJobDelegateImpl::GetMimeType( 165 bool AndroidStreamReaderURLRequestJobDelegateImpl::GetMimeType(
149 JNIEnv* env, 166 JNIEnv* env,
150 net::URLRequest* request, 167 net::URLRequest* request,
151 android_webview::InputStream* stream, 168 android_webview::InputStream* stream,
152 std::string* mime_type) { 169 std::string* mime_type) {
153 DCHECK(env); 170 DCHECK(env);
154 DCHECK(request); 171 DCHECK(request);
155 DCHECK(mime_type); 172 DCHECK(mime_type);
156 173
157 // Query the mime type from the Java side. It is possible for the query to 174 // Query the mime type from the Java side. It is possible for the query to
(...skipping 16 matching lines...) Expand all
174 191
175 bool AndroidStreamReaderURLRequestJobDelegateImpl::GetCharset( 192 bool AndroidStreamReaderURLRequestJobDelegateImpl::GetCharset(
176 JNIEnv* env, 193 JNIEnv* env,
177 net::URLRequest* request, 194 net::URLRequest* request,
178 android_webview::InputStream* stream, 195 android_webview::InputStream* stream,
179 std::string* charset) { 196 std::string* charset) {
180 // TODO: We should probably be getting this from the managed side. 197 // TODO: We should probably be getting this from the managed side.
181 return false; 198 return false;
182 } 199 }
183 200
184 AssetFileProtocolInterceptor::AssetFileProtocolInterceptor() 201 // AndroidProtocolHandlerBase -------------------------------------------------
202
203 net::URLRequestJob* AndroidProtocolHandlerBase::MaybeCreateJob(
204 net::URLRequest* request,
205 net::NetworkDelegate* network_delegate) const {
206 if (!CanHandleRequest(request)) return NULL;
207
208 // For WebViewClassic compatibility this job can only accept URLs that can be
209 // opened. URLs that cannot be opened should be resolved by the next handler.
210 //
211 // If a request is initially handled here but the job fails due to it being
212 // unable to open the InputStream for that request the request is marked as
213 // previously failed and restarted.
214 // Restarting a request involves creating a new job for that request. This
215 // handler will ignore requests know to have previously failed to 1) prevent
216 // an infinite loop, 2) ensure that the next handler in line gets the
217 // opportunity to create a job for the request.
218 if (HasRequestPreviouslyFailed(request)) return NULL;
219
220 scoped_ptr<AndroidStreamReaderURLRequestJobDelegateImpl> reader_delegate(
221 new AndroidStreamReaderURLRequestJobDelegateImpl());
222
223 return new AndroidStreamReaderURLRequestJob(
224 request,
225 network_delegate,
226 reader_delegate.PassAs<AndroidStreamReaderURLRequestJob::Delegate>());
227 }
228
229 // AssetFileProtocolHandler ---------------------------------------------------
230
231 AssetFileProtocolHandler::AssetFileProtocolHandler()
185 : asset_prefix_(std::string(chrome::kFileScheme) + 232 : asset_prefix_(std::string(chrome::kFileScheme) +
186 std::string(content::kStandardSchemeSeparator) + 233 std::string(content::kStandardSchemeSeparator) +
187 android_webview::kAndroidAssetPath), 234 android_webview::kAndroidAssetPath),
188 resource_prefix_(std::string(chrome::kFileScheme) + 235 resource_prefix_(std::string(chrome::kFileScheme) +
189 std::string(content::kStandardSchemeSeparator) + 236 std::string(content::kStandardSchemeSeparator) +
190 android_webview::kAndroidResourcePath) { 237 android_webview::kAndroidResourcePath) {
191 } 238 }
192 239
193 AssetFileProtocolInterceptor::~AssetFileProtocolInterceptor() { 240 AssetFileProtocolHandler::~AssetFileProtocolHandler() {
194 } 241 }
195 242
196 // static 243 bool AssetFileProtocolHandler::CanHandleRequest(
197 scoped_ptr<net::URLRequestJobFactory> 244 const net::URLRequest* request) const {
198 AssetFileProtocolInterceptor::CreateURLRequestJobFactory( 245 if (!request->url().SchemeIsFile())
199 scoped_ptr<net::URLRequestJobFactory> base_job_factory) { 246 return false;
200 scoped_ptr<net::URLRequestJobFactory> top_job_factory(
201 new net::ProtocolInterceptJobFactory(
202 base_job_factory.Pass(),
203 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(
204 new AssetFileProtocolInterceptor())));
205 return top_job_factory.Pass();
206 }
207
208 net::URLRequestJob* AssetFileProtocolInterceptor::MaybeCreateJob(
209 net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
210 if (!request->url().SchemeIsFile()) return NULL;
211 247
212 const std::string& url = request->url().spec(); 248 const std::string& url = request->url().spec();
213 if (!StartsWithASCII(url, asset_prefix_, /*case_sensitive=*/ true) && 249 if (!StartsWithASCII(url, asset_prefix_, /*case_sensitive=*/ true) &&
214 !StartsWithASCII(url, resource_prefix_, /*case_sensitive=*/ true)) { 250 !StartsWithASCII(url, resource_prefix_, /*case_sensitive=*/ true)) {
215 return NULL; 251 return false;
216 } 252 }
217 253
218 return new AndroidStreamReaderURLRequestJob( 254 return true;
219 request, 255 }
220 network_delegate, 256
221 scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>( 257 // ContentSchemeProtocolHandler -----------------------------------------------
222 new AndroidStreamReaderURLRequestJobDelegateImpl())); 258
259 ContentSchemeProtocolHandler::ContentSchemeProtocolHandler() {
260 }
261
262 bool ContentSchemeProtocolHandler::CanHandleRequest(
263 const net::URLRequest* request) const {
264 return request->url().SchemeIs(android_webview::kContentScheme);
223 } 265 }
224 266
225 } // namespace 267 } // namespace
226 268
227 namespace android_webview { 269 namespace android_webview {
228 270
229 bool RegisterAndroidProtocolHandler(JNIEnv* env) { 271 bool RegisterAndroidProtocolHandler(JNIEnv* env) {
230 return RegisterNativesImpl(env); 272 return RegisterNativesImpl(env);
231 } 273 }
232 274
233 // static 275 // static
234 scoped_ptr<net::URLRequestJobFactory> CreateAndroidRequestJobFactory( 276 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
235 scoped_ptr<AwURLRequestJobFactory> job_factory) { 277 CreateContentSchemeProtocolHandler() {
236 // Register content://. Note that even though a scheme is 278 return make_scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(
237 // registered here, it cannot be used by child processes until access to it is 279 new ContentSchemeProtocolHandler());
238 // granted via ChildProcessSecurityPolicy::GrantScheme(). This is done in 280 }
239 // AwContentBrowserClient. 281
240 // The job factory takes ownership of the handler. 282 // static
241 bool set_protocol = job_factory->SetProtocolHandler( 283 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
242 android_webview::kContentScheme, new ContentSchemeProtocolHandler()); 284 CreateAssetFileProtocolHandler() {
243 DCHECK(set_protocol); 285 return make_scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(
244 return AssetFileProtocolInterceptor::CreateURLRequestJobFactory( 286 new AssetFileProtocolHandler());
245 job_factory.PassAs<net::URLRequestJobFactory>());
246 } 287 }
247 288
248 // Set a context object to be used for resolving resource queries. This can 289 // Set a context object to be used for resolving resource queries. This can
249 // be used to override the default application context and redirect all 290 // be used to override the default application context and redirect all
250 // resource queries to a specific context object, e.g., for the purposes of 291 // resource queries to a specific context object, e.g., for the purposes of
251 // testing. 292 // testing.
252 // 293 //
253 // |context| should be a android.content.Context instance or NULL to enable 294 // |context| should be a android.content.Context instance or NULL to enable
254 // the use of the standard application context. 295 // the use of the standard application context.
255 static void SetResourceContextForTesting(JNIEnv* env, jclass /*clazz*/, 296 static void SetResourceContextForTesting(JNIEnv* env, jclass /*clazz*/,
(...skipping 11 matching lines...) Expand all
267 env, android_webview::kAndroidAssetPath).Release(); 308 env, android_webview::kAndroidAssetPath).Release();
268 } 309 }
269 310
270 static jstring GetAndroidResourcePath(JNIEnv* env, jclass /*clazz*/) { 311 static jstring GetAndroidResourcePath(JNIEnv* env, jclass /*clazz*/) {
271 // OK to release, JNI binding. 312 // OK to release, JNI binding.
272 return ConvertUTF8ToJavaString( 313 return ConvertUTF8ToJavaString(
273 env, android_webview::kAndroidResourcePath).Release(); 314 env, android_webview::kAndroidResourcePath).Release();
274 } 315 }
275 316
276 } // namespace android_webview 317 } // namespace android_webview
OLDNEW
« 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