Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1252)

Side by Side Diff: content/browser/renderer_host/cross_site_resource_handler.cc

Issue 10644011: Revert r143458 (which re-applies r143341 and r142979). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <string> 5 #include <string>
6 6
7 #include "content/browser/renderer_host/cross_site_resource_handler.h" 7 #include "content/browser/renderer_host/cross_site_resource_handler.h"
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "content/browser/renderer_host/render_view_host_delegate.h" 11 #include "content/browser/renderer_host/render_view_host_delegate.h"
12 #include "content/browser/renderer_host/render_view_host_impl.h" 12 #include "content/browser/renderer_host/render_view_host_impl.h"
13 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
14 #include "content/browser/renderer_host/resource_request_info_impl.h" 13 #include "content/browser/renderer_host/resource_request_info_impl.h"
15 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/global_request_id.h" 15 #include "content/public/browser/resource_controller.h"
17 #include "content/public/common/resource_response.h" 16 #include "content/public/common/resource_response.h"
18 #include "net/base/io_buffer.h"
19 #include "net/http/http_response_headers.h" 17 #include "net/http/http_response_headers.h"
20 18
21 namespace content { 19 namespace content {
22 20
23 namespace { 21 namespace {
24 22
25 void OnCrossSiteResponseHelper(int render_process_id, 23 void OnCrossSiteResponseHelper(int render_process_id,
26 int render_view_id, 24 int render_view_id,
27 int request_id) { 25 int request_id) {
28 RenderViewHostImpl* rvh = RenderViewHostImpl::FromID(render_process_id, 26 RenderViewHostImpl* rvh = RenderViewHostImpl::FromID(render_process_id,
29 render_view_id); 27 render_view_id);
30 if (rvh && rvh->GetDelegate()->GetRendererManagementDelegate()) { 28 if (rvh && rvh->GetDelegate()->GetRendererManagementDelegate()) {
31 rvh->GetDelegate()->GetRendererManagementDelegate()->OnCrossSiteResponse( 29 rvh->GetDelegate()->GetRendererManagementDelegate()->OnCrossSiteResponse(
32 render_process_id, request_id); 30 render_process_id, request_id);
33 } 31 }
34 } 32 }
35 33
36 } // namespace 34 } // namespace
37 35
38 CrossSiteResourceHandler::CrossSiteResourceHandler( 36 CrossSiteResourceHandler::CrossSiteResourceHandler(
39 scoped_ptr<ResourceHandler> next_handler, 37 scoped_ptr<ResourceHandler> next_handler,
40 int render_process_host_id, 38 int render_process_host_id,
41 int render_view_id, 39 int render_view_id,
42 ResourceDispatcherHostImpl* rdh) 40 net::URLRequest* request)
43 : LayeredResourceHandler(next_handler.Pass()), 41 : LayeredResourceHandler(next_handler.Pass()),
44 render_process_host_id_(render_process_host_id), 42 render_process_host_id_(render_process_host_id),
45 render_view_id_(render_view_id), 43 render_view_id_(render_view_id),
44 request_(request),
46 has_started_response_(false), 45 has_started_response_(false),
47 in_cross_site_transition_(false), 46 in_cross_site_transition_(false),
48 request_id_(-1), 47 request_id_(-1),
49 completed_during_transition_(false), 48 completed_during_transition_(false),
50 did_defer_(false), 49 did_defer_(false),
51 completed_status_(), 50 completed_status_(),
52 response_(NULL), 51 response_(NULL) {
53 rdh_(rdh) {
54 } 52 }
55 53
56 CrossSiteResourceHandler::~CrossSiteResourceHandler() { 54 CrossSiteResourceHandler::~CrossSiteResourceHandler() {
55 // Cleanup back-pointer stored on the request info.
56 ResourceRequestInfoImpl::ForRequest(request_)->set_cross_site_handler(NULL);
57 } 57 }
58 58
59 bool CrossSiteResourceHandler::OnRequestRedirected( 59 bool CrossSiteResourceHandler::OnRequestRedirected(
60 int request_id, 60 int request_id,
61 const GURL& new_url, 61 const GURL& new_url,
62 ResourceResponse* response, 62 ResourceResponse* response,
63 bool* defer) { 63 bool* defer) {
64 // We should not have started the transition before being redirected. 64 // We should not have started the transition before being redirected.
65 DCHECK(!in_cross_site_transition_); 65 DCHECK(!in_cross_site_transition_);
66 return next_handler_->OnRequestRedirected( 66 return next_handler_->OnRequestRedirected(
67 request_id, new_url, response, defer); 67 request_id, new_url, response, defer);
68 } 68 }
69 69
70 bool CrossSiteResourceHandler::OnResponseStarted( 70 bool CrossSiteResourceHandler::OnResponseStarted(
71 int request_id, 71 int request_id,
72 ResourceResponse* response, 72 ResourceResponse* response,
73 bool* defer) { 73 bool* defer) {
74 // At this point, we know that the response is safe to send back to the 74 // At this point, we know that the response is safe to send back to the
75 // renderer: it is not a download, and it has passed the SSL and safe 75 // renderer: it is not a download, and it has passed the SSL and safe
76 // browsing checks. 76 // browsing checks.
77 // We should not have already started the transition before now. 77 // We should not have already started the transition before now.
78 DCHECK(!in_cross_site_transition_); 78 DCHECK(!in_cross_site_transition_);
79 has_started_response_ = true; 79 has_started_response_ = true;
80 80
81 // Look up the request and associated info. 81 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request_);
82 GlobalRequestID global_id(render_process_host_id_, request_id);
83 net::URLRequest* request = rdh_->GetURLRequest(global_id);
84 if (!request) {
85 DLOG(WARNING) << "Request wasn't found";
86 return false;
87 }
88 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
89 82
90 // If this is a download, just pass the response through without doing a 83 // If this is a download, just pass the response through without doing a
91 // cross-site check. The renderer will see it is a download and abort the 84 // cross-site check. The renderer will see it is a download and abort the
92 // request. 85 // request.
93 // 86 //
94 // Similarly, HTTP 204 (No Content) responses leave us showing the previous 87 // Similarly, HTTP 204 (No Content) responses leave us showing the previous
95 // page. We should allow the navigation to finish without running the unload 88 // page. We should allow the navigation to finish without running the unload
96 // handler or swapping in the pending RenderViewHost. 89 // handler or swapping in the pending RenderViewHost.
97 // 90 //
98 // In both cases, the pending RenderViewHost will stick around until the next 91 // In both cases, the pending RenderViewHost will stick around until the next
99 // cross-site navigation, since we are unable to tell when to destroy it. 92 // cross-site navigation, since we are unable to tell when to destroy it.
100 // See RenderViewHostManager::RendererAbortedProvisionalLoad. 93 // See RenderViewHostManager::RendererAbortedProvisionalLoad.
101 if (info->is_download() || 94 if (info->is_download() ||
102 (response->headers && response->headers->response_code() == 204)) { 95 (response->headers && response->headers->response_code() == 204)) {
103 return next_handler_->OnResponseStarted(request_id, response, defer); 96 return next_handler_->OnResponseStarted(request_id, response, defer);
104 } 97 }
105 98
106 // Tell the renderer to run the onunload event handler, and wait for the 99 // Tell the renderer to run the onunload event handler, and wait for the
107 // reply. 100 // reply.
108 StartCrossSiteTransition(request_id, response, global_id, defer); 101 StartCrossSiteTransition(request_id, response, defer);
109 return true; 102 return true;
110 } 103 }
111 104
112 bool CrossSiteResourceHandler::OnReadCompleted(int request_id, 105 bool CrossSiteResourceHandler::OnReadCompleted(int request_id,
113 int* bytes_read, 106 int* bytes_read,
114 bool* defer) { 107 bool* defer) {
115 if (!in_cross_site_transition_) { 108 if (!in_cross_site_transition_) {
116 return next_handler_->OnReadCompleted(request_id, bytes_read, defer); 109 return next_handler_->OnReadCompleted(request_id, bytes_read, defer);
117 } 110 }
118 return true; 111 return true;
119 } 112 }
120 113
121 bool CrossSiteResourceHandler::OnResponseCompleted( 114 bool CrossSiteResourceHandler::OnResponseCompleted(
122 int request_id, 115 int request_id,
123 const net::URLRequestStatus& status, 116 const net::URLRequestStatus& status,
124 const std::string& security_info) { 117 const std::string& security_info) {
125 if (!in_cross_site_transition_) { 118 if (!in_cross_site_transition_) {
126 if (has_started_response_ || 119 if (has_started_response_ ||
127 status.status() != net::URLRequestStatus::FAILED) { 120 status.status() != net::URLRequestStatus::FAILED) {
128 // We've already completed the transition or we're canceling the request, 121 // We've already completed the transition or we're canceling the request,
129 // so just pass it through. 122 // so just pass it through.
130 return next_handler_->OnResponseCompleted(request_id, status, 123 return next_handler_->OnResponseCompleted(request_id, status,
131 security_info); 124 security_info);
132 } 125 }
133 126
134 // An error occured, we should wait now for the cross-site transition, 127 // An error occured, we should wait now for the cross-site transition,
135 // so that the error message (e.g., 404) can be displayed to the user. 128 // so that the error message (e.g., 404) can be displayed to the user.
136 // Also continue with the logic below to remember that we completed 129 // Also continue with the logic below to remember that we completed
137 // during the cross-site transition. 130 // during the cross-site transition.
138 GlobalRequestID global_id(render_process_host_id_, request_id);
139 bool defer = false; 131 bool defer = false;
140 StartCrossSiteTransition(request_id, NULL, global_id, &defer); 132 StartCrossSiteTransition(request_id, NULL, &defer);
141 DCHECK(!defer); // Since !has_started_response_. 133 DCHECK(!defer); // Since !has_started_response_.
142 } 134 }
143 135
144 // We have to buffer the call until after the transition completes. 136 // We have to buffer the call until after the transition completes.
145 completed_during_transition_ = true; 137 completed_during_transition_ = true;
146 completed_status_ = status; 138 completed_status_ = status;
147 completed_security_info_ = security_info; 139 completed_security_info_ = security_info;
148 140
149 // Return false to tell RDH not to notify the world or clean up the 141 // Return false to tell RDH not to notify the world or clean up the
150 // pending request. We will do so in ResumeResponse. 142 // pending request. We will do so in ResumeResponse.
151 return false; 143 return false;
152 } 144 }
153 145
154 // We can now send the response to the new renderer, which will cause 146 // We can now send the response to the new renderer, which will cause
155 // WebContentsImpl to swap in the new renderer and destroy the old one. 147 // WebContentsImpl to swap in the new renderer and destroy the old one.
156 void CrossSiteResourceHandler::ResumeResponse() { 148 void CrossSiteResourceHandler::ResumeResponse() {
157 DCHECK(request_id_ != -1); 149 DCHECK(request_id_ != -1);
158 DCHECK(in_cross_site_transition_); 150 DCHECK(in_cross_site_transition_);
159 in_cross_site_transition_ = false; 151 in_cross_site_transition_ = false;
160 152
161 // Find the request for this response.
162 GlobalRequestID global_id(render_process_host_id_, request_id_);
163 net::URLRequest* request = rdh_->GetURLRequest(global_id);
164 if (!request) {
165 DLOG(WARNING) << "Resuming a request that wasn't found";
166 return;
167 }
168
169 if (has_started_response_) { 153 if (has_started_response_) {
170 // Send OnResponseStarted to the new renderer. 154 // Send OnResponseStarted to the new renderer.
171 DCHECK(response_); 155 DCHECK(response_);
172 bool defer = false; 156 bool defer = false;
173 if (!next_handler_->OnResponseStarted(request_id_, response_, &defer)) { 157 if (!next_handler_->OnResponseStarted(request_id_, response_, &defer)) {
174 controller()->Cancel(); 158 controller()->Cancel();
175 } else if (!defer) { 159 } else if (!defer) {
176 // Unpause the request to resume reading. Any further reads will be 160 // Unpause the request to resume reading. Any further reads will be
177 // directed toward the new renderer. 161 // directed toward the new renderer.
178 ResumeIfDeferred(); 162 ResumeIfDeferred();
179 } 163 }
180 } 164 }
181 165
182 // Remove ourselves from the ExtraRequestInfo. 166 // Remove ourselves from the ExtraRequestInfo.
183 ResourceRequestInfoImpl* info = 167 ResourceRequestInfoImpl* info =
184 ResourceRequestInfoImpl::ForRequest(request); 168 ResourceRequestInfoImpl::ForRequest(request_);
185 info->set_cross_site_handler(NULL); 169 info->set_cross_site_handler(NULL);
186 170
187 // If the response completed during the transition, notify the next 171 // If the response completed during the transition, notify the next
188 // event handler. 172 // event handler.
189 if (completed_during_transition_) { 173 if (completed_during_transition_) {
190 if (next_handler_->OnResponseCompleted(request_id_, completed_status_, 174 if (next_handler_->OnResponseCompleted(request_id_, completed_status_,
191 completed_security_info_)) { 175 completed_security_info_)) {
192 ResumeIfDeferred(); 176 ResumeIfDeferred();
193 } 177 }
194 } 178 }
195 } 179 }
196 180
197 // Prepare to render the cross-site response in a new RenderViewHost, by 181 // Prepare to render the cross-site response in a new RenderViewHost, by
198 // telling the old RenderViewHost to run its onunload handler. 182 // telling the old RenderViewHost to run its onunload handler.
199 void CrossSiteResourceHandler::StartCrossSiteTransition( 183 void CrossSiteResourceHandler::StartCrossSiteTransition(
200 int request_id, 184 int request_id,
201 ResourceResponse* response, 185 ResourceResponse* response,
202 const GlobalRequestID& global_id,
203 bool* defer) { 186 bool* defer) {
204 in_cross_site_transition_ = true; 187 in_cross_site_transition_ = true;
205 request_id_ = request_id; 188 request_id_ = request_id;
206 response_ = response; 189 response_ = response;
207 190
208 // Store this handler on the ExtraRequestInfo, so that RDH can call our 191 // Store this handler on the ExtraRequestInfo, so that RDH can call our
209 // ResumeResponse method when the close ACK is received. 192 // ResumeResponse method when the close ACK is received.
210 net::URLRequest* request = rdh_->GetURLRequest(global_id);
211 if (!request) {
212 DLOG(WARNING) << "Cross site response for a request that wasn't found";
213 return;
214 }
215 ResourceRequestInfoImpl* info = 193 ResourceRequestInfoImpl* info =
216 ResourceRequestInfoImpl::ForRequest(request); 194 ResourceRequestInfoImpl::ForRequest(request_);
217 info->set_cross_site_handler(this); 195 info->set_cross_site_handler(this);
218 196
219 if (has_started_response_) { 197 if (has_started_response_) {
220 // Defer the request until the old renderer is finished and the new 198 // Defer the request until the old renderer is finished and the new
221 // renderer is ready. 199 // renderer is ready.
222 did_defer_ = *defer = true; 200 did_defer_ = *defer = true;
223 } 201 }
224 // If our OnResponseStarted wasn't called, then we're being called by 202 // If our OnResponseStarted wasn't called, then we're being called by
225 // OnResponseCompleted after a failure. We don't need to pause, because 203 // OnResponseCompleted after a failure. We don't need to pause, because
226 // there will be no reads. 204 // there will be no reads.
(...skipping 15 matching lines...) Expand all
242 } 220 }
243 221
244 void CrossSiteResourceHandler::ResumeIfDeferred() { 222 void CrossSiteResourceHandler::ResumeIfDeferred() {
245 if (did_defer_) { 223 if (did_defer_) {
246 did_defer_ = false; 224 did_defer_ = false;
247 controller()->Resume(); 225 controller()->Resume();
248 } 226 }
249 } 227 }
250 228
251 } // namespace content 229 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698