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

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

Issue 10332130: Use defer out-params instead of ResourceDispatcherHostImpl::PauseRequest(...true) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 ResourceResponse* response, 58 ResourceResponse* response,
59 bool* defer) { 59 bool* defer) {
60 // We should not have started the transition before being redirected. 60 // We should not have started the transition before being redirected.
61 DCHECK(!in_cross_site_transition_); 61 DCHECK(!in_cross_site_transition_);
62 return next_handler_->OnRequestRedirected( 62 return next_handler_->OnRequestRedirected(
63 request_id, new_url, response, defer); 63 request_id, new_url, response, defer);
64 } 64 }
65 65
66 bool CrossSiteResourceHandler::OnResponseStarted( 66 bool CrossSiteResourceHandler::OnResponseStarted(
67 int request_id, 67 int request_id,
68 ResourceResponse* response) { 68 ResourceResponse* response,
69 bool* defer) {
69 // At this point, we know that the response is safe to send back to the 70 // At this point, we know that the response is safe to send back to the
70 // renderer: it is not a download, and it has passed the SSL and safe 71 // renderer: it is not a download, and it has passed the SSL and safe
71 // browsing checks. 72 // browsing checks.
72 // We should not have already started the transition before now. 73 // We should not have already started the transition before now.
73 DCHECK(!in_cross_site_transition_); 74 DCHECK(!in_cross_site_transition_);
74 has_started_response_ = true; 75 has_started_response_ = true;
75 76
76 // Look up the request and associated info. 77 // Look up the request and associated info.
77 GlobalRequestID global_id(render_process_host_id_, request_id); 78 GlobalRequestID global_id(render_process_host_id_, request_id);
78 net::URLRequest* request = rdh_->GetURLRequest(global_id); 79 net::URLRequest* request = rdh_->GetURLRequest(global_id);
79 if (!request) { 80 if (!request) {
80 DLOG(WARNING) << "Request wasn't found"; 81 DLOG(WARNING) << "Request wasn't found";
81 return false; 82 return false;
82 } 83 }
83 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); 84 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
84 85
85 // If this is a download, just pass the response through without doing a 86 // If this is a download, just pass the response through without doing a
86 // cross-site check. The renderer will see it is a download and abort the 87 // cross-site check. The renderer will see it is a download and abort the
87 // request. 88 // request.
88 // 89 //
89 // Similarly, HTTP 204 (No Content) responses leave us showing the previous 90 // Similarly, HTTP 204 (No Content) responses leave us showing the previous
90 // page. We should allow the navigation to finish without running the unload 91 // page. We should allow the navigation to finish without running the unload
91 // handler or swapping in the pending RenderViewHost. 92 // handler or swapping in the pending RenderViewHost.
92 // 93 //
93 // In both cases, the pending RenderViewHost will stick around until the next 94 // In both cases, the pending RenderViewHost will stick around until the next
94 // cross-site navigation, since we are unable to tell when to destroy it. 95 // cross-site navigation, since we are unable to tell when to destroy it.
95 // See RenderViewHostManager::RendererAbortedProvisionalLoad. 96 // See RenderViewHostManager::RendererAbortedProvisionalLoad.
96 if (info->is_download() || 97 if (info->is_download() ||
97 (response->headers && response->headers->response_code() == 204)) { 98 (response->headers && response->headers->response_code() == 204)) {
98 return next_handler_->OnResponseStarted(request_id, response); 99 return next_handler_->OnResponseStarted(request_id, response, defer);
99 } 100 }
100 101
101 // Tell the renderer to run the onunload event handler, and wait for the 102 // Tell the renderer to run the onunload event handler, and wait for the
102 // reply. 103 // reply.
103 StartCrossSiteTransition(request_id, response, global_id); 104 StartCrossSiteTransition(request_id, response, global_id, defer);
104 return true; 105 return true;
105 } 106 }
106 107
107 bool CrossSiteResourceHandler::OnReadCompleted(int request_id, 108 bool CrossSiteResourceHandler::OnReadCompleted(int request_id,
108 int* bytes_read) { 109 int* bytes_read,
110 bool* defer) {
109 if (!in_cross_site_transition_) { 111 if (!in_cross_site_transition_) {
110 return next_handler_->OnReadCompleted(request_id, bytes_read); 112 return next_handler_->OnReadCompleted(request_id, bytes_read, defer);
111 } 113 }
112 return true; 114 return true;
113 } 115 }
114 116
115 bool CrossSiteResourceHandler::OnResponseCompleted( 117 bool CrossSiteResourceHandler::OnResponseCompleted(
116 int request_id, 118 int request_id,
117 const net::URLRequestStatus& status, 119 const net::URLRequestStatus& status,
118 const std::string& security_info) { 120 const std::string& security_info) {
119 if (!in_cross_site_transition_) { 121 if (!in_cross_site_transition_) {
120 if (has_started_response_ || 122 if (has_started_response_ ||
121 status.status() != net::URLRequestStatus::FAILED) { 123 status.status() != net::URLRequestStatus::FAILED) {
122 // We've already completed the transition or we're canceling the request, 124 // We've already completed the transition or we're canceling the request,
123 // so just pass it through. 125 // so just pass it through.
124 return next_handler_->OnResponseCompleted(request_id, status, 126 return next_handler_->OnResponseCompleted(request_id, status,
125 security_info); 127 security_info);
126 } else {
127 // An error occured, we should wait now for the cross-site transition,
128 // so that the error message (e.g., 404) can be displayed to the user.
129 // Also continue with the logic below to remember that we completed
130 // during the cross-site transition.
131 GlobalRequestID global_id(render_process_host_id_, request_id);
132 StartCrossSiteTransition(request_id, NULL, global_id);
133 } 128 }
129
130 // An error occured, we should wait now for the cross-site transition,
131 // so that the error message (e.g., 404) can be displayed to the user.
132 // Also continue with the logic below to remember that we completed
133 // during the cross-site transition.
134 GlobalRequestID global_id(render_process_host_id_, request_id);
135 bool defer = false;
136 StartCrossSiteTransition(request_id, NULL, global_id, &defer);
137 DCHECK(!defer); // Since !has_started_response_.
134 } 138 }
135 139
136 // We have to buffer the call until after the transition completes. 140 // We have to buffer the call until after the transition completes.
137 completed_during_transition_ = true; 141 completed_during_transition_ = true;
138 completed_status_ = status; 142 completed_status_ = status;
139 completed_security_info_ = security_info; 143 completed_security_info_ = security_info;
140 144
141 // Return false to tell RDH not to notify the world or clean up the 145 // Return false to tell RDH not to notify the world or clean up the
142 // pending request. We will do so in ResumeResponse. 146 // pending request. We will do so in ResumeResponse.
143 return false; 147 return false;
(...skipping 10 matching lines...) Expand all
154 GlobalRequestID global_id(render_process_host_id_, request_id_); 158 GlobalRequestID global_id(render_process_host_id_, request_id_);
155 net::URLRequest* request = rdh_->GetURLRequest(global_id); 159 net::URLRequest* request = rdh_->GetURLRequest(global_id);
156 if (!request) { 160 if (!request) {
157 DLOG(WARNING) << "Resuming a request that wasn't found"; 161 DLOG(WARNING) << "Resuming a request that wasn't found";
158 return; 162 return;
159 } 163 }
160 164
161 if (has_started_response_) { 165 if (has_started_response_) {
162 // Send OnResponseStarted to the new renderer. 166 // Send OnResponseStarted to the new renderer.
163 DCHECK(response_); 167 DCHECK(response_);
164 next_handler_->OnResponseStarted(request_id_, response_); 168 bool defer = false;
165 169 if (!next_handler_->OnResponseStarted(request_id_, response_, &defer)) {
166 // Unpause the request to resume reading. Any further reads will be 170 rdh_->CancelRequest(render_process_host_id_, request_id_, false);
167 // directed toward the new renderer. 171 } else if (!defer) {
168 rdh_->PauseRequest(render_process_host_id_, request_id_, false); 172 // Unpause the request to resume reading. Any further reads will be
173 // directed toward the new renderer.
174 rdh_->ResumeDeferredRequest(render_process_host_id_, request_id_);
175 }
169 } 176 }
170 177
171 // Remove ourselves from the ExtraRequestInfo. 178 // Remove ourselves from the ExtraRequestInfo.
172 ResourceRequestInfoImpl* info = 179 ResourceRequestInfoImpl* info =
173 ResourceRequestInfoImpl::ForRequest(request); 180 ResourceRequestInfoImpl::ForRequest(request);
174 info->set_cross_site_handler(NULL); 181 info->set_cross_site_handler(NULL);
175 182
176 // If the response completed during the transition, notify the next 183 // If the response completed during the transition, notify the next
177 // event handler. 184 // event handler.
178 if (completed_during_transition_) { 185 if (completed_during_transition_) {
179 next_handler_->OnResponseCompleted(request_id_, completed_status_, 186 next_handler_->OnResponseCompleted(request_id_, completed_status_,
180 completed_security_info_); 187 completed_security_info_);
188 // TODO(darin): OnResponseCompleted can return false to defer
189 // RemovePendingRequest.
181 rdh_->RemovePendingRequest(render_process_host_id_, request_id_); 190 rdh_->RemovePendingRequest(render_process_host_id_, request_id_);
182 } 191 }
183 } 192 }
184 193
185 CrossSiteResourceHandler::~CrossSiteResourceHandler() {} 194 CrossSiteResourceHandler::~CrossSiteResourceHandler() {}
186 195
187 // Prepare to render the cross-site response in a new RenderViewHost, by 196 // Prepare to render the cross-site response in a new RenderViewHost, by
188 // telling the old RenderViewHost to run its onunload handler. 197 // telling the old RenderViewHost to run its onunload handler.
189 void CrossSiteResourceHandler::StartCrossSiteTransition( 198 void CrossSiteResourceHandler::StartCrossSiteTransition(
190 int request_id, 199 int request_id,
191 ResourceResponse* response, 200 ResourceResponse* response,
192 const GlobalRequestID& global_id) { 201 const GlobalRequestID& global_id,
202 bool* defer) {
193 in_cross_site_transition_ = true; 203 in_cross_site_transition_ = true;
194 request_id_ = request_id; 204 request_id_ = request_id;
195 response_ = response; 205 response_ = response;
196 206
197 // Store this handler on the ExtraRequestInfo, so that RDH can call our 207 // Store this handler on the ExtraRequestInfo, so that RDH can call our
198 // ResumeResponse method when the close ACK is received. 208 // ResumeResponse method when the close ACK is received.
199 net::URLRequest* request = rdh_->GetURLRequest(global_id); 209 net::URLRequest* request = rdh_->GetURLRequest(global_id);
200 if (!request) { 210 if (!request) {
201 DLOG(WARNING) << "Cross site response for a request that wasn't found"; 211 DLOG(WARNING) << "Cross site response for a request that wasn't found";
202 return; 212 return;
203 } 213 }
204 ResourceRequestInfoImpl* info = 214 ResourceRequestInfoImpl* info =
205 ResourceRequestInfoImpl::ForRequest(request); 215 ResourceRequestInfoImpl::ForRequest(request);
206 info->set_cross_site_handler(this); 216 info->set_cross_site_handler(this);
207 217
208 if (has_started_response_) { 218 if (has_started_response_) {
209 // Pause the request until the old renderer is finished and the new 219 // Defer the request until the old renderer is finished and the new
210 // renderer is ready. 220 // renderer is ready.
211 rdh_->PauseRequest(render_process_host_id_, request_id, true); 221 *defer = true;
212 } 222 }
213 // If our OnResponseStarted wasn't called, then we're being called by 223 // If our OnResponseStarted wasn't called, then we're being called by
214 // OnResponseCompleted after a failure. We don't need to pause, because 224 // OnResponseCompleted after a failure. We don't need to pause, because
215 // there will be no reads. 225 // there will be no reads.
216 226
217 // Tell the contents responsible for this request that a cross-site response 227 // Tell the contents responsible for this request that a cross-site response
218 // is starting, so that it can tell its old renderer to run its onunload 228 // is starting, so that it can tell its old renderer to run its onunload
219 // handler now. We will wait to hear the corresponding ClosePage_ACK. 229 // handler now. We will wait to hear the corresponding ClosePage_ACK.
220 BrowserThread::PostTask( 230 BrowserThread::PostTask(
221 BrowserThread::UI, 231 BrowserThread::UI,
222 FROM_HERE, 232 FROM_HERE,
223 base::Bind( 233 base::Bind(
224 &OnCrossSiteResponseHelper, 234 &OnCrossSiteResponseHelper,
225 render_process_host_id_, 235 render_process_host_id_,
226 render_view_id_, 236 render_view_id_,
227 request_id)); 237 request_id));
228 238
229 // TODO(creis): If the above call should fail, then we need to notify the IO 239 // TODO(creis): If the above call should fail, then we need to notify the IO
230 // thread to proceed anyway, using ResourceDispatcherHost::OnClosePageACK. 240 // thread to proceed anyway, using ResourceDispatcherHost::OnClosePageACK.
231 } 241 }
232 242
233 } // namespace content 243 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698