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 3 // found in the LICENSE file. 4 5 #include "android_webview/browser/aw_request_interceptor.h" 6 7 #include "android_webview/browser/aw_contents_io_thread_client.h" 8 #include "android_webview/browser/aw_web_resource_response.h" 9 #include "base/android/jni_string.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/render_view_host.h" 13 #include "content/public/browser/resource_request_info.h" 14 #include "net/url_request/url_request.h" 15 #include "net/url_request/url_request_context.h" 16 #include "net/url_request/url_request_context_getter.h" 17 #include "net/url_request/url_request_job.h" 18 19 using content::BrowserThread; 20 using content::RenderViewHost; 21 using content::ResourceRequestInfo; 22 23 namespace android_webview { 24 25 namespace { 26 27 const void* kRequestAlreadyQueriedDataKey = &kRequestAlreadyQueriedDataKey; 28 29 } // namespace 30 31 AwRequestInterceptor::AwRequestInterceptor() { 32 } 33 34 AwRequestInterceptor::~AwRequestInterceptor() { 35 } 36 37 scoped_ptr<AwWebResourceResponse> 38 AwRequestInterceptor::QueryForAwWebResourceResponse( 39 const GURL& location, 40 net::URLRequest* request) const { 41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 42 int render_process_id, render_frame_id; 43 if (!ResourceRequestInfo::GetRenderFrameForRequest( 44 request, &render_process_id, &render_frame_id)) 45 return scoped_ptr<AwWebResourceResponse>(); 46 47 scoped_ptr<AwContentsIoThreadClient> io_thread_client = 48 AwContentsIoThreadClient::FromID(render_process_id, render_frame_id); 49 50 if (!io_thread_client.get()) 51 return scoped_ptr<AwWebResourceResponse>(); 52 53 return io_thread_client->ShouldInterceptRequest(location, request).Pass(); 54 } 55 56 net::URLRequestJob* AwRequestInterceptor::MaybeInterceptRequest( 57 net::URLRequest* request, 58 net::NetworkDelegate* network_delegate) const { 59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 60 61 // See if we've already found out the aw_web_resource_response for this 62 // request. 63 // This is done not only for efficiency reasons, but also for correctness 64 // as it is possible for the Interceptor chain to be invoked more than once 65 // in which case we don't want to query the embedder multiple times. 66 // Note: The Interceptor chain is not invoked more than once if we create a 67 // URLRequestJob in this method, so this is only caching negative hits. 68 if (request->GetUserData(kRequestAlreadyQueriedDataKey)) 69 return NULL; 70 request->SetUserData(kRequestAlreadyQueriedDataKey, 71 new base::SupportsUserData::Data()); 72 73 scoped_ptr<AwWebResourceResponse> aw_web_resource_response = 74 QueryForAwWebResourceResponse(request->url(), request); 75 76 if (!aw_web_resource_response) 77 return NULL; 78 79 // The newly created job will own the AwWebResourceResponse. 80 return AwWebResourceResponse::CreateJobFor( 81 aw_web_resource_response.Pass(), request, network_delegate); 82 } 83 84 } // namespace android_webview 85