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/intercepted_request_data.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 19using content::BrowserThread; 20using content::RenderViewHost; 21using content::ResourceRequestInfo; 22 23namespace android_webview { 24 25namespace { 26 27const void* kRequestAlreadyQueriedDataKey = &kRequestAlreadyQueriedDataKey; 28 29} // namespace 30 31AwRequestInterceptor::AwRequestInterceptor() { 32} 33 34AwRequestInterceptor::~AwRequestInterceptor() { 35} 36 37scoped_ptr<InterceptedRequestData> 38AwRequestInterceptor::QueryForInterceptedRequestData( 39 const GURL& location, 40 net::URLRequest* request) const { 41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 42 int render_process_id, render_view_id; 43 if (!ResourceRequestInfo::GetRenderViewForRequest( 44 request, &render_process_id, &render_view_id)) 45 return scoped_ptr<InterceptedRequestData>(); 46 47 scoped_ptr<AwContentsIoThreadClient> io_thread_client = 48 AwContentsIoThreadClient::FromID(render_process_id, render_view_id); 49 50 if (!io_thread_client.get()) 51 return scoped_ptr<InterceptedRequestData>(); 52 53 return io_thread_client->ShouldInterceptRequest(location, request).Pass(); 54} 55 56net::URLRequestJob* AwRequestInterceptor::MaybeCreateJob( 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 intercepted_request_data 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<InterceptedRequestData> intercepted_request_data = 74 QueryForInterceptedRequestData(request->url(), request); 75 76 if (!intercepted_request_data) 77 return NULL; 78 79 // The newly created job will own the InterceptedRequestData. 80 return InterceptedRequestData::CreateJobFor( 81 intercepted_request_data.Pass(), request, network_delegate); 82} 83 84} // namespace android_webview 85