Home | History | Annotate | Download | only in browser
      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