OLD | NEW |
---|---|
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 "content/browser/loader/cross_site_resource_handler.h" | 5 #include "content/browser/loader/cross_site_resource_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "content/browser/appcache/appcache_interceptor.h" | 12 #include "content/browser/appcache/appcache_interceptor.h" |
13 #include "content/browser/child_process_security_policy_impl.h" | 13 #include "content/browser/child_process_security_policy_impl.h" |
14 #include "content/browser/cross_site_request_manager.h" | |
15 #include "content/browser/frame_host/cross_site_transferring_request.h" | 14 #include "content/browser/frame_host/cross_site_transferring_request.h" |
16 #include "content/browser/frame_host/render_frame_host_impl.h" | 15 #include "content/browser/frame_host/render_frame_host_impl.h" |
17 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 16 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
18 #include "content/browser/loader/resource_request_info_impl.h" | 17 #include "content/browser/loader/resource_request_info_impl.h" |
18 #include "content/browser/site_instance_impl.h" | |
19 #include "content/browser/transition_request_manager.h" | 19 #include "content/browser/transition_request_manager.h" |
20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
21 #include "content/public/browser/content_browser_client.h" | 21 #include "content/public/browser/content_browser_client.h" |
22 #include "content/public/browser/global_request_id.h" | 22 #include "content/public/browser/global_request_id.h" |
23 #include "content/public/browser/resource_controller.h" | 23 #include "content/public/browser/resource_controller.h" |
24 #include "content/public/browser/site_instance.h" | 24 #include "content/public/browser/site_instance.h" |
25 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
26 #include "content/public/common/resource_response.h" | 26 #include "content/public/common/resource_response.h" |
27 #include "content/public/common/url_constants.h" | 27 #include "content/public/common/url_constants.h" |
28 #include "net/http/http_response_headers.h" | 28 #include "net/http/http_response_headers.h" |
29 #include "net/url_request/url_request.h" | 29 #include "net/url_request/url_request.h" |
30 | 30 |
31 namespace content { | 31 namespace content { |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 bool leak_requests_for_testing_ = false; | 35 bool leak_requests_for_testing_ = false; |
36 | 36 |
37 // The parameters to OnCrossSiteResponseHelper exceed the number of arguments | 37 // The parameters to OnCrossSiteResponseHelper exceed the number of arguments |
38 // base::Bind supports. | 38 // base::Bind supports. |
39 struct CrossSiteResponseParams { | 39 struct CrossSiteResponseParams { |
40 CrossSiteResponseParams( | 40 CrossSiteResponseParams( |
41 int render_frame_id, | 41 int render_frame_id, |
42 const GlobalRequestID& global_request_id, | 42 const GlobalRequestID& global_request_id, |
43 bool is_transfer, | |
44 const std::vector<GURL>& transfer_url_chain, | 43 const std::vector<GURL>& transfer_url_chain, |
45 const Referrer& referrer, | 44 const Referrer& referrer, |
46 PageTransition page_transition, | 45 PageTransition page_transition, |
47 bool should_replace_current_entry) | 46 bool should_replace_current_entry) |
48 : render_frame_id(render_frame_id), | 47 : render_frame_id(render_frame_id), |
49 global_request_id(global_request_id), | 48 global_request_id(global_request_id), |
50 is_transfer(is_transfer), | |
51 transfer_url_chain(transfer_url_chain), | 49 transfer_url_chain(transfer_url_chain), |
52 referrer(referrer), | 50 referrer(referrer), |
53 page_transition(page_transition), | 51 page_transition(page_transition), |
54 should_replace_current_entry(should_replace_current_entry) { | 52 should_replace_current_entry(should_replace_current_entry) { |
55 } | 53 } |
56 | 54 |
57 int render_frame_id; | 55 int render_frame_id; |
58 GlobalRequestID global_request_id; | 56 GlobalRequestID global_request_id; |
59 bool is_transfer; | |
60 std::vector<GURL> transfer_url_chain; | 57 std::vector<GURL> transfer_url_chain; |
61 Referrer referrer; | 58 Referrer referrer; |
62 PageTransition page_transition; | 59 PageTransition page_transition; |
63 bool should_replace_current_entry; | 60 bool should_replace_current_entry; |
64 }; | 61 }; |
65 | 62 |
66 void OnCrossSiteResponseHelper(const CrossSiteResponseParams& params) { | 63 void OnCrossSiteResponseHelper(const CrossSiteResponseParams& params) { |
67 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request; | 64 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request( |
68 if (params.is_transfer) { | 65 new CrossSiteTransferringRequest(params.global_request_id)); |
69 cross_site_transferring_request.reset(new CrossSiteTransferringRequest( | |
70 params.global_request_id)); | |
71 } | |
72 | 66 |
73 RenderFrameHostImpl* rfh = | 67 RenderFrameHostImpl* rfh = |
74 RenderFrameHostImpl::FromID(params.global_request_id.child_id, | 68 RenderFrameHostImpl::FromID(params.global_request_id.child_id, |
75 params.render_frame_id); | 69 params.render_frame_id); |
76 if (rfh) { | 70 if (rfh) { |
77 rfh->OnCrossSiteResponse( | 71 rfh->OnCrossSiteResponse( |
78 params.global_request_id, cross_site_transferring_request.Pass(), | 72 params.global_request_id, cross_site_transferring_request.Pass(), |
79 params.transfer_url_chain, params.referrer, | 73 params.transfer_url_chain, params.referrer, |
80 params.page_transition, params.should_replace_current_entry); | 74 params.page_transition, params.should_replace_current_entry); |
81 } else if (leak_requests_for_testing_ && cross_site_transferring_request) { | 75 } else if (leak_requests_for_testing_ && cross_site_transferring_request) { |
82 // Some unit tests expect requests to be leaked in this case, so they can | 76 // Some unit tests expect requests to be leaked in this case, so they can |
83 // pass them along manually. | 77 // pass them along manually. |
84 cross_site_transferring_request->ReleaseRequest(); | 78 cross_site_transferring_request->ReleaseRequest(); |
85 } | 79 } |
86 } | 80 } |
87 | 81 |
88 void OnDeferredAfterResponseStartedHelper( | 82 void OnDeferredAfterResponseStartedHelper( |
89 const GlobalRequestID& global_request_id, | 83 const GlobalRequestID& global_request_id, |
90 int render_frame_id, | 84 int render_frame_id, |
91 const TransitionLayerData& transition_data) { | 85 const TransitionLayerData& transition_data) { |
92 RenderFrameHostImpl* rfh = | 86 RenderFrameHostImpl* rfh = |
93 RenderFrameHostImpl::FromID(global_request_id.child_id, render_frame_id); | 87 RenderFrameHostImpl::FromID(global_request_id.child_id, render_frame_id); |
94 if (rfh) | 88 if (rfh) |
95 rfh->OnDeferredAfterResponseStarted(global_request_id, transition_data); | 89 rfh->OnDeferredAfterResponseStarted(global_request_id, transition_data); |
96 } | 90 } |
97 | 91 |
92 // Returns whether a transfer is needed by doing a check on the UI thread. | |
98 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) { | 93 bool CheckNavigationPolicyOnUI(GURL url, int process_id, int render_frame_id) { |
94 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)); | |
nasko
2014/08/19 16:45:23
Thanks for adding that!
| |
99 RenderFrameHostImpl* rfh = | 95 RenderFrameHostImpl* rfh = |
100 RenderFrameHostImpl::FromID(process_id, render_frame_id); | 96 RenderFrameHostImpl::FromID(process_id, render_frame_id); |
101 if (!rfh) | 97 if (!rfh) |
102 return false; | 98 return false; |
103 | 99 |
104 // TODO(nasko): This check is very simplistic and is used temporarily only | 100 // TODO(nasko): This check is very simplistic and is used temporarily only |
105 // for --site-per-process. It should be updated to match the check performed | 101 // for --site-per-process. It should be updated to match the check performed |
106 // by RenderFrameHostManager::UpdateStateForNavigate. | 102 // by RenderFrameHostManager::UpdateStateForNavigate. |
107 return !SiteInstance::IsSameWebSite( | 103 return !SiteInstance::IsSameWebSite( |
108 rfh->GetSiteInstance()->GetBrowserContext(), | 104 rfh->GetSiteInstance()->GetBrowserContext(), |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 ResourceResponse* response, | 165 ResourceResponse* response, |
170 bool* defer) { | 166 bool* defer) { |
171 // At this point, we know that the response is safe to send back to the | 167 // At this point, we know that the response is safe to send back to the |
172 // renderer: it is not a download, and it has passed the SSL and safe | 168 // renderer: it is not a download, and it has passed the SSL and safe |
173 // browsing checks. | 169 // browsing checks. |
174 // We should not have already started the transition before now. | 170 // We should not have already started the transition before now. |
175 DCHECK(!in_cross_site_transition_); | 171 DCHECK(!in_cross_site_transition_); |
176 | 172 |
177 ResourceRequestInfoImpl* info = GetRequestInfo(); | 173 ResourceRequestInfoImpl* info = GetRequestInfo(); |
178 | 174 |
179 // We will need to swap processes if either (1) a redirect that requires a | 175 // We only need to pause the response if a transfer to a different process is |
180 // transfer occurred before we got here, or (2) a pending cross-site request | 176 // required. Other cross-process navigations can proceed immediately, since |
181 // was already in progress. Note that a swap may no longer be needed if we | 177 // we run the unload handler at commit time. |
182 // transferred back into the original process due to a redirect. | 178 // Note that a process swap may no longer be necessary if we transferred back |
179 // into the original process due to a redirect. | |
183 bool should_transfer = | 180 bool should_transfer = |
184 GetContentClient()->browser()->ShouldSwapProcessesForRedirect( | 181 GetContentClient()->browser()->ShouldSwapProcessesForRedirect( |
185 info->GetContext(), request()->original_url(), request()->url()); | 182 info->GetContext(), request()->original_url(), request()->url()); |
186 | 183 |
187 // When the --site-per-process flag is passed, we transfer processes for | 184 // When the --site-per-process flag is passed, we transfer processes for |
188 // cross-site navigations. This is skipped if a transfer is already required | 185 // cross-site navigations. This is skipped if a transfer is already required |
189 // or for WebUI processes for now, since pages like the NTP host multiple | 186 // or for WebUI processes for now, since pages like the NTP host multiple |
190 // cross-site WebUI iframes. | 187 // cross-site WebUI iframes. |
191 if (!should_transfer && | 188 if (!should_transfer && |
192 base::CommandLine::ForCurrentProcess()->HasSwitch( | 189 base::CommandLine::ForCurrentProcess()->HasSwitch( |
193 switches::kSitePerProcess) && | 190 switches::kSitePerProcess) && |
194 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | 191 !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( |
195 info->GetChildID())) { | 192 info->GetChildID())) { |
196 return DeferForNavigationPolicyCheck(info, response, defer); | 193 return DeferForNavigationPolicyCheck(info, response, defer); |
197 } | 194 } |
198 | 195 |
199 bool swap_needed = | |
200 should_transfer || | |
201 CrossSiteRequestManager::GetInstance()->HasPendingCrossSiteRequest( | |
202 info->GetChildID(), info->GetRenderFrameID()); | |
203 | |
204 // If this is a download, just pass the response through without doing a | 196 // If this is a download, just pass the response through without doing a |
205 // cross-site check. The renderer will see it is a download and abort the | 197 // cross-site check. The renderer will see it is a download and abort the |
206 // request. | 198 // request. |
207 // | 199 // |
208 // Similarly, HTTP 204 (No Content) responses leave us showing the previous | 200 // Similarly, HTTP 204 (No Content) responses leave us showing the previous |
209 // page. We should allow the navigation to finish without running the unload | 201 // page. We should allow the navigation to finish without running the unload |
210 // handler or swapping in the pending RenderFrameHost. | 202 // handler or swapping in the pending RenderFrameHost. |
211 // | 203 // |
212 // In both cases, any pending RenderFrameHost (if one was created for this | 204 // In both cases, any pending RenderFrameHost (if one was created for this |
213 // navigation) will stick around until the next cross-site navigation, since | 205 // navigation) will stick around until the next cross-site navigation, since |
214 // we are unable to tell when to destroy it. | 206 // we are unable to tell when to destroy it. |
215 // See RenderFrameHostManager::RendererAbortedProvisionalLoad. | 207 // See RenderFrameHostManager::RendererAbortedProvisionalLoad. |
216 // | 208 // |
217 // TODO(davidben): Unify IsDownload() and is_stream(). Several places need to | 209 // TODO(davidben): Unify IsDownload() and is_stream(). Several places need to |
218 // check for both and remembering about streams is error-prone. | 210 // check for both and remembering about streams is error-prone. |
219 if (!swap_needed || info->IsDownload() || info->is_stream() || | 211 if (!should_transfer || info->IsDownload() || info->is_stream() || |
220 (response->head.headers.get() && | 212 (response->head.headers.get() && |
221 response->head.headers->response_code() == 204)) { | 213 response->head.headers->response_code() == 204)) { |
222 return next_handler_->OnResponseStarted(response, defer); | 214 return next_handler_->OnResponseStarted(response, defer); |
223 } | 215 } |
224 | 216 |
225 // Now that we know a swap is needed and we have something to commit, we | 217 // Now that we know a transfer is needed and we have something to commit, we |
226 // pause to let the UI thread run the unload handler of the previous page | 218 // pause to let the UI thread set up the transfer. |
227 // and set up a transfer if needed. | 219 StartCrossSiteTransition(response); |
228 StartCrossSiteTransition(response, should_transfer); | |
229 | 220 |
230 // Defer loading until after the onunload event handler has run. | 221 // Defer loading until after the new renderer process has issued a |
222 // corresponding request. | |
231 *defer = true; | 223 *defer = true; |
232 OnDidDefer(); | 224 OnDidDefer(); |
233 return true; | 225 return true; |
234 } | 226 } |
235 | 227 |
236 bool CrossSiteResourceHandler::OnNavigationTransitionResponseStarted( | 228 bool CrossSiteResourceHandler::OnNavigationTransitionResponseStarted( |
237 ResourceResponse* response, | 229 ResourceResponse* response, |
238 bool* defer, | 230 bool* defer, |
239 const TransitionLayerData& transition_data) { | 231 const TransitionLayerData& transition_data) { |
240 ResourceRequestInfoImpl* info = GetRequestInfo(); | 232 ResourceRequestInfoImpl* info = GetRequestInfo(); |
(...skipping 18 matching lines...) Expand all Loading... | |
259 bool defer = false; | 251 bool defer = false; |
260 if (!OnNormalResponseStarted(response_, &defer)) { | 252 if (!OnNormalResponseStarted(response_, &defer)) { |
261 controller()->Cancel(); | 253 controller()->Cancel(); |
262 } else if (!defer) { | 254 } else if (!defer) { |
263 ResumeIfDeferred(); | 255 ResumeIfDeferred(); |
264 } | 256 } |
265 } | 257 } |
266 | 258 |
267 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) { | 259 void CrossSiteResourceHandler::ResumeOrTransfer(bool is_transfer) { |
268 if (is_transfer) { | 260 if (is_transfer) { |
269 StartCrossSiteTransition(response_, is_transfer); | 261 StartCrossSiteTransition(response_); |
270 } else { | 262 } else { |
271 ResumeResponse(); | 263 ResumeResponse(); |
272 } | 264 } |
273 } | 265 } |
274 | 266 |
275 bool CrossSiteResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 267 bool CrossSiteResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
276 CHECK(!in_cross_site_transition_); | 268 CHECK(!in_cross_site_transition_); |
277 return next_handler_->OnReadCompleted(bytes_read, defer); | 269 return next_handler_->OnReadCompleted(bytes_read, defer); |
278 } | 270 } |
279 | 271 |
280 void CrossSiteResourceHandler::OnResponseCompleted( | 272 void CrossSiteResourceHandler::OnResponseCompleted( |
281 const net::URLRequestStatus& status, | 273 const net::URLRequestStatus& status, |
282 const std::string& security_info, | 274 const std::string& security_info, |
283 bool* defer) { | 275 bool* defer) { |
284 if (!in_cross_site_transition_) { | 276 if (!in_cross_site_transition_) { |
285 ResourceRequestInfoImpl* info = GetRequestInfo(); | 277 // If we're not transferring, then we should pass this through. |
286 // If we've already completed the transition, or we're canceling the | 278 next_handler_->OnResponseCompleted(status, security_info, defer); |
287 // request, or an error occurred with no cross-process navigation in | 279 return; |
288 // progress, then we should just pass this through. | |
289 if (has_started_response_ || | |
290 status.status() != net::URLRequestStatus::FAILED || | |
291 !CrossSiteRequestManager::GetInstance()->HasPendingCrossSiteRequest( | |
292 info->GetChildID(), info->GetRenderFrameID())) { | |
293 next_handler_->OnResponseCompleted(status, security_info, defer); | |
294 return; | |
295 } | |
296 | |
297 // An error occurred. We should wait now for the cross-process transition, | |
298 // so that the error message (e.g., 404) can be displayed to the user. | |
299 // Also continue with the logic below to remember that we completed | |
300 // during the cross-site transition. | |
301 StartCrossSiteTransition(NULL, false); | |
302 } | 280 } |
303 | 281 |
304 // We have to buffer the call until after the transition completes. | 282 // We have to buffer the call until after the transition completes. |
305 completed_during_transition_ = true; | 283 completed_during_transition_ = true; |
306 completed_status_ = status; | 284 completed_status_ = status; |
307 completed_security_info_ = security_info; | 285 completed_security_info_ = security_info; |
308 | 286 |
309 // Defer to tell RDH not to notify the world or clean up the pending request. | 287 // Defer to tell RDH not to notify the world or clean up the pending request. |
310 // We will do so in ResumeResponse. | 288 // We will do so in ResumeResponse. |
311 *defer = true; | 289 *defer = true; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
346 ResumeIfDeferred(); | 324 ResumeIfDeferred(); |
347 } | 325 } |
348 } | 326 } |
349 | 327 |
350 // static | 328 // static |
351 void CrossSiteResourceHandler::SetLeakRequestsForTesting( | 329 void CrossSiteResourceHandler::SetLeakRequestsForTesting( |
352 bool leak_requests_for_testing) { | 330 bool leak_requests_for_testing) { |
353 leak_requests_for_testing_ = leak_requests_for_testing; | 331 leak_requests_for_testing_ = leak_requests_for_testing; |
354 } | 332 } |
355 | 333 |
356 // Prepare to render the cross-site response in a new RenderFrameHost, by | 334 // Prepare to transfer the response to a new RenderFrameHost. |
357 // telling the old RenderFrameHost to run its onunload handler. | |
358 void CrossSiteResourceHandler::StartCrossSiteTransition( | 335 void CrossSiteResourceHandler::StartCrossSiteTransition( |
359 ResourceResponse* response, | 336 ResourceResponse* response) { |
360 bool should_transfer) { | |
361 in_cross_site_transition_ = true; | 337 in_cross_site_transition_ = true; |
362 response_ = response; | 338 response_ = response; |
363 | 339 |
364 // Store this handler on the ExtraRequestInfo, so that RDH can call our | 340 // Store this handler on the ExtraRequestInfo, so that RDH can call our |
365 // ResumeResponse method when we are ready to resume. | 341 // ResumeResponse method when we are ready to resume. |
366 ResourceRequestInfoImpl* info = GetRequestInfo(); | 342 ResourceRequestInfoImpl* info = GetRequestInfo(); |
367 info->set_cross_site_handler(this); | 343 info->set_cross_site_handler(this); |
368 | 344 |
369 GlobalRequestID global_id(info->GetChildID(), info->GetRequestID()); | 345 GlobalRequestID global_id(info->GetChildID(), info->GetRequestID()); |
370 | 346 |
371 // Tell the contents responsible for this request that a cross-site response | 347 // Tell the contents responsible for this request that a cross-site response |
372 // is starting, so that it can tell its old renderer to run its onunload | 348 // is starting, so that it can tell its old renderer to run its onunload |
373 // handler now. We will wait until the unload is finished and (if a transfer | 349 // handler now. We will wait until the unload is finished and (if a transfer |
374 // is needed) for the new renderer's request to arrive. | 350 // is needed) for the new renderer's request to arrive. |
375 // The |transfer_url_chain| contains any redirect URLs that have already | 351 // The |transfer_url_chain| contains any redirect URLs that have already |
376 // occurred, plus the destination URL at the end. | 352 // occurred, plus the destination URL at the end. |
377 std::vector<GURL> transfer_url_chain; | 353 std::vector<GURL> transfer_url_chain; |
378 Referrer referrer; | 354 Referrer referrer; |
379 int render_frame_id = info->GetRenderFrameID(); | 355 int render_frame_id = info->GetRenderFrameID(); |
380 if (should_transfer) { | 356 transfer_url_chain = request()->url_chain(); |
381 transfer_url_chain = request()->url_chain(); | 357 referrer = Referrer(GURL(request()->referrer()), info->GetReferrerPolicy()); |
382 referrer = Referrer(GURL(request()->referrer()), info->GetReferrerPolicy()); | |
383 | 358 |
384 AppCacheInterceptor::PrepareForCrossSiteTransfer( | 359 AppCacheInterceptor::PrepareForCrossSiteTransfer( |
385 request(), global_id.child_id); | 360 request(), global_id.child_id); |
386 ResourceDispatcherHostImpl::Get()->MarkAsTransferredNavigation(global_id); | 361 ResourceDispatcherHostImpl::Get()->MarkAsTransferredNavigation(global_id); |
387 } | 362 |
388 BrowserThread::PostTask( | 363 BrowserThread::PostTask( |
389 BrowserThread::UI, | 364 BrowserThread::UI, |
390 FROM_HERE, | 365 FROM_HERE, |
391 base::Bind( | 366 base::Bind( |
392 &OnCrossSiteResponseHelper, | 367 &OnCrossSiteResponseHelper, |
393 CrossSiteResponseParams(render_frame_id, | 368 CrossSiteResponseParams(render_frame_id, |
394 global_id, | 369 global_id, |
395 should_transfer, | |
396 transfer_url_chain, | 370 transfer_url_chain, |
397 referrer, | 371 referrer, |
398 info->GetPageTransition(), | 372 info->GetPageTransition(), |
399 info->should_replace_current_entry()))); | 373 info->should_replace_current_entry()))); |
400 } | 374 } |
401 | 375 |
402 bool CrossSiteResourceHandler::DeferForNavigationPolicyCheck( | 376 bool CrossSiteResourceHandler::DeferForNavigationPolicyCheck( |
403 ResourceRequestInfoImpl* info, | 377 ResourceRequestInfoImpl* info, |
404 ResourceResponse* response, | 378 ResourceResponse* response, |
405 bool* defer) { | 379 bool* defer) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
438 controller()->Resume(); | 412 controller()->Resume(); |
439 } | 413 } |
440 } | 414 } |
441 | 415 |
442 void CrossSiteResourceHandler::OnDidDefer() { | 416 void CrossSiteResourceHandler::OnDidDefer() { |
443 did_defer_ = true; | 417 did_defer_ = true; |
444 request()->LogBlockedBy("CrossSiteResourceHandler"); | 418 request()->LogBlockedBy("CrossSiteResourceHandler"); |
445 } | 419 } |
446 | 420 |
447 } // namespace content | 421 } // namespace content |
OLD | NEW |