OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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 "content/browser/loader/navigation_url_loader_core.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/location.h" |
| 9 #include "content/browser/frame_host/frame_tree_node.h" |
| 10 #include "content/browser/frame_host/navigation_request_info.h" |
| 11 #include "content/browser/loader/navigation_resource_handler.h" |
| 12 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| 13 #include "content/common/navigation_params.h" |
| 14 #include "content/public/browser/browser_context.h" |
| 15 #include "content/public/browser/browser_thread.h" |
| 16 #include "content/public/browser/stream_handle.h" |
| 17 #include "content/public/common/resource_response.h" |
| 18 #include "net/base/net_errors.h" |
| 19 #include "net/url_request/redirect_info.h" |
| 20 |
| 21 namespace content { |
| 22 |
| 23 NavigationURLLoaderCore::NavigationURLLoaderCore() |
| 24 : delegate_(NULL), |
| 25 resource_handler_(NULL) { |
| 26 } |
| 27 |
| 28 void NavigationURLLoaderCore::StartRequest( |
| 29 BrowserContext* browser_context, |
| 30 int64 frame_tree_node_id, |
| 31 const CommonNavigationParams& common_params, |
| 32 scoped_ptr<NavigationRequestInfo> request_info, |
| 33 ResourceRequestBody* request_body) { |
| 34 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 35 |
| 36 BrowserThread::PostTask( |
| 37 BrowserThread::IO, FROM_HERE, |
| 38 base::Bind(&NavigationURLLoaderCore::StartRequestOnIOThread, this, |
| 39 browser_context->GetResourceContext(), |
| 40 frame_tree_node_id, common_params, base::Passed(&request_info), |
| 41 make_scoped_refptr(request_body))); |
| 42 } |
| 43 |
| 44 void NavigationURLLoaderCore::FollowRedirect() { |
| 45 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 46 |
| 47 BrowserThread::PostTask( |
| 48 BrowserThread::IO, FROM_HERE, |
| 49 base::Bind(&NavigationURLLoaderCore::FollowRedirectOnIOThread, this)); |
| 50 } |
| 51 |
| 52 void NavigationURLLoaderCore::Cancel() { |
| 53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 54 |
| 55 BrowserThread::PostTask( |
| 56 BrowserThread::IO, FROM_HERE, |
| 57 base::Bind(&NavigationURLLoaderCore::CancelOnIOThread, this)); |
| 58 } |
| 59 |
| 60 void NavigationURLLoaderCore::RequestRedirectedOnIOThread( |
| 61 const net::RedirectInfo& redirect_info, |
| 62 ResourceResponse* response) { |
| 63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 64 |
| 65 // Make a copy of the ResourceResponse before it is passed to another thread. |
| 66 // |
| 67 // TODO(davidben): This copy could be avoided if ResourceResponse weren't |
| 68 // reference counted and the loader stack passed unique ownership of the |
| 69 // response. https://crbug.com/416050 |
| 70 BrowserThread::PostTask( |
| 71 BrowserThread::UI, FROM_HERE, |
| 72 base::Bind(&NavigationURLLoaderCore::CallOnRequestRedirected, |
| 73 this, redirect_info, response->DeepCopy())); |
| 74 } |
| 75 |
| 76 void NavigationURLLoaderCore::ResponseStartedOnIOThread( |
| 77 ResourceResponse* response, |
| 78 scoped_ptr<StreamHandle> body) { |
| 79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 80 |
| 81 // Make a copy of the ResourceResponse before it is passed to another thread. |
| 82 // |
| 83 // TODO(davidben): This copy could be avoided if ResourceResponse weren't |
| 84 // reference counted and the loader stack passed unique ownership of the |
| 85 // response. https://crbug.com/416050 |
| 86 BrowserThread::PostTask( |
| 87 BrowserThread::UI, FROM_HERE, |
| 88 base::Bind(&NavigationURLLoaderCore::CallOnResponseStarted, |
| 89 this, response->DeepCopy(), base::Passed(&body))); |
| 90 } |
| 91 |
| 92 void NavigationURLLoaderCore::RequestFailedOnIOThread(int net_error) { |
| 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 94 |
| 95 BrowserThread::PostTask( |
| 96 BrowserThread::UI, FROM_HERE, |
| 97 base::Bind(&NavigationURLLoaderCore::CallOnRequestFailed, |
| 98 this, net_error)); |
| 99 } |
| 100 |
| 101 NavigationURLLoaderCore::~NavigationURLLoaderCore() { |
| 102 // When the core is released by either the delegate or the resource handler, |
| 103 // the corresponding pointers are NULLed. At this point, both should be NULL. |
| 104 DCHECK(!delegate_); |
| 105 DCHECK(!resource_handler_); |
| 106 } |
| 107 |
| 108 void NavigationURLLoaderCore::StartRequestOnIOThread( |
| 109 ResourceContext* resource_context, |
| 110 int64 frame_tree_node_id, |
| 111 const CommonNavigationParams& common_params, |
| 112 scoped_ptr<NavigationRequestInfo> request_info, |
| 113 ResourceRequestBody* request_body) { |
| 114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 115 |
| 116 ResourceDispatcherHostImpl::Get()->BeginNavigationRequest( |
| 117 resource_context, frame_tree_node_id, |
| 118 common_params, *request_info, request_body, |
| 119 this); |
| 120 } |
| 121 |
| 122 void NavigationURLLoaderCore::FollowRedirectOnIOThread() { |
| 123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 124 |
| 125 if (resource_handler_) |
| 126 resource_handler_->FollowRedirect(); |
| 127 } |
| 128 |
| 129 void NavigationURLLoaderCore::CancelOnIOThread() { |
| 130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 131 |
| 132 if (resource_handler_) |
| 133 resource_handler_->Cancel(); |
| 134 } |
| 135 |
| 136 void NavigationURLLoaderCore::CallOnRequestRedirected( |
| 137 const net::RedirectInfo& redirect_info, |
| 138 ResourceResponse* response) { |
| 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 140 |
| 141 if (delegate_) |
| 142 delegate_->OnRequestRedirected(redirect_info, response); |
| 143 } |
| 144 |
| 145 void NavigationURLLoaderCore::CallOnResponseStarted( |
| 146 ResourceResponse* response, |
| 147 scoped_ptr<StreamHandle> body) { |
| 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 149 |
| 150 // If |delegate_| is NULL, OnResponseStarted on the IO thread raced with |
| 151 // Cancel on the UI thread. |body| will be destructed and the request released |
| 152 // at that point. |
| 153 if (delegate_) |
| 154 delegate_->OnResponseStarted(response, body.Pass()); |
| 155 } |
| 156 |
| 157 void NavigationURLLoaderCore::CallOnRequestFailed(int net_error) { |
| 158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 159 |
| 160 if (delegate_) |
| 161 delegate_->OnRequestFailed(net_error); |
| 162 } |
| 163 |
| 164 } // namespace content |
OLD | NEW |