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

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

Powered by Google App Engine
This is Rietveld 408576698