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

Side by Side Diff: content/browser/loader/mojo_async_resource_handler.cc

Issue 2467833002: Implement redirect handling on MojoAsyncResourceHandler (Closed)
Patch Set: rebase Created 4 years, 1 month 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/mojo_async_resource_handler.h" 5 #include "content/browser/loader/mojo_async_resource_handler.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "content/browser/loader/netlog_observer.h" 15 #include "content/browser/loader/netlog_observer.h"
16 #include "content/browser/loader/resource_dispatcher_host_impl.h" 16 #include "content/browser/loader/resource_dispatcher_host_impl.h"
17 #include "content/browser/loader/resource_request_info_impl.h" 17 #include "content/browser/loader/resource_request_info_impl.h"
18 #include "content/common/resource_request_completion_status.h" 18 #include "content/common/resource_request_completion_status.h"
19 #include "content/public/browser/global_request_id.h" 19 #include "content/public/browser/global_request_id.h"
20 #include "content/public/browser/resource_dispatcher_host_delegate.h" 20 #include "content/public/browser/resource_dispatcher_host_delegate.h"
21 #include "content/public/common/resource_response.h" 21 #include "content/public/common/resource_response.h"
22 #include "mojo/public/c/system/data_pipe.h" 22 #include "mojo/public/c/system/data_pipe.h"
23 #include "mojo/public/cpp/bindings/message.h"
23 #include "mojo/public/cpp/system/data_pipe.h" 24 #include "mojo/public/cpp/system/data_pipe.h"
24 #include "net/base/io_buffer.h" 25 #include "net/base/io_buffer.h"
25 #include "net/base/load_flags.h" 26 #include "net/base/load_flags.h"
26 #include "net/base/mime_sniffer.h" 27 #include "net/base/mime_sniffer.h"
27 #include "net/url_request/redirect_info.h" 28 #include "net/url_request/redirect_info.h"
28 29
29 namespace content { 30 namespace content {
30 namespace { 31 namespace {
31 32
32 int g_allocation_size = MojoAsyncResourceHandler::kDefaultAllocationSize; 33 int g_allocation_size = MojoAsyncResourceHandler::kDefaultAllocationSize;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 121
121 MojoAsyncResourceHandler::~MojoAsyncResourceHandler() { 122 MojoAsyncResourceHandler::~MojoAsyncResourceHandler() {
122 if (has_checked_for_sufficient_resources_) 123 if (has_checked_for_sufficient_resources_)
123 rdh_->FinishedWithResourcesForRequest(request()); 124 rdh_->FinishedWithResourcesForRequest(request());
124 } 125 }
125 126
126 bool MojoAsyncResourceHandler::OnRequestRedirected( 127 bool MojoAsyncResourceHandler::OnRequestRedirected(
127 const net::RedirectInfo& redirect_info, 128 const net::RedirectInfo& redirect_info,
128 ResourceResponse* response, 129 ResourceResponse* response,
129 bool* defer) { 130 bool* defer) {
130 // Not implemented. 131 // Unlike OnResponseStarted, OnRequestRedirected will NOT be preceded by
131 return false; 132 // OnWillRead.
133 DCHECK(!shared_writer_);
134
135 *defer = true;
136 request()->LogBlockedBy("MojoAsyncResourceHandler");
137 did_defer_on_redirect_ = true;
138
139 NetLogObserver::PopulateResponseInfo(request(), response);
140 response->head.encoded_data_length = request()->GetTotalReceivedBytes();
141 response->head.request_start = request()->creation_time();
142 response->head.response_start = base::TimeTicks::Now();
143 // TODO(davidben): Is it necessary to pass the new first party URL for
144 // cookies? The only case where it can change is top-level navigation requests
145 // and hopefully those will eventually all be owned by the browser. It's
146 // possible this is still needed while renderer-owned ones exist.
147 url_loader_client_->OnReceiveRedirect(redirect_info, response->head);
148 return true;
132 } 149 }
133 150
134 bool MojoAsyncResourceHandler::OnResponseStarted(ResourceResponse* response, 151 bool MojoAsyncResourceHandler::OnResponseStarted(ResourceResponse* response,
135 bool* defer) { 152 bool* defer) {
136 const ResourceRequestInfoImpl* info = GetRequestInfo(); 153 const ResourceRequestInfoImpl* info = GetRequestInfo();
137 154
138 if (rdh_->delegate()) { 155 if (rdh_->delegate()) {
139 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(), 156 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(),
140 response); 157 response);
141 } 158 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 228
212 if (!bytes_read) 229 if (!bytes_read)
213 return true; 230 return true;
214 231
215 if (is_using_io_buffer_not_from_writer_) { 232 if (is_using_io_buffer_not_from_writer_) {
216 // Couldn't allocate a buffer on the data pipe in OnWillRead. 233 // Couldn't allocate a buffer on the data pipe in OnWillRead.
217 DCHECK_EQ(0u, buffer_bytes_read_); 234 DCHECK_EQ(0u, buffer_bytes_read_);
218 buffer_bytes_read_ = bytes_read; 235 buffer_bytes_read_ = bytes_read;
219 if (!CopyReadDataToDataPipe(defer)) 236 if (!CopyReadDataToDataPipe(defer))
220 return false; 237 return false;
221 if (*defer) 238 if (*defer) {
222 OnDefer(); 239 request()->LogBlockedBy("MojoAsyncResourceHandler");
240 did_defer_on_writing_ = true;
241 }
223 return true; 242 return true;
224 } 243 }
225 244
226 if (EndWrite(bytes_read) != MOJO_RESULT_OK) 245 if (EndWrite(bytes_read) != MOJO_RESULT_OK)
227 return false; 246 return false;
228 // Allocate a buffer for the next OnWillRead call here, because OnWillRead 247 // Allocate a buffer for the next OnWillRead call here, because OnWillRead
229 // doesn't have |defer| parameter. 248 // doesn't have |defer| parameter.
230 if (!AllocateWriterIOBuffer(&buffer_, defer)) 249 if (!AllocateWriterIOBuffer(&buffer_, defer))
231 return false; 250 return false;
232 if (*defer) 251 if (*defer) {
233 OnDefer(); 252 request()->LogBlockedBy("MojoAsyncResourceHandler");
253 did_defer_on_writing_ = true;
254 }
234 return true; 255 return true;
235 } 256 }
236 257
237 void MojoAsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { 258 void MojoAsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) {
238 int64_t total_received_bytes = request()->GetTotalReceivedBytes(); 259 int64_t total_received_bytes = request()->GetTotalReceivedBytes();
239 int64_t bytes_to_report = 260 int64_t bytes_to_report =
240 total_received_bytes - reported_total_received_bytes_; 261 total_received_bytes - reported_total_received_bytes_;
241 reported_total_received_bytes_ = total_received_bytes; 262 reported_total_received_bytes_ = total_received_bytes;
242 DCHECK_LE(0, bytes_to_report); 263 DCHECK_LE(0, bytes_to_report);
243 264
244 url_loader_client_->OnDataDownloaded(bytes_downloaded, bytes_to_report); 265 url_loader_client_->OnDataDownloaded(bytes_downloaded, bytes_to_report);
245 } 266 }
246 267
247 void MojoAsyncResourceHandler::FollowRedirect() { 268 void MojoAsyncResourceHandler::FollowRedirect() {
248 NOTIMPLEMENTED(); 269 if (!request()->status().is_success()) {
270 DVLOG(1) << "FollowRedirect for invalid request";
271 return;
272 }
273 if (!did_defer_on_redirect_) {
274 DVLOG(1) << "Malformed FollowRedirect request";
275 ReportBadMessage("Malformed FollowRedirect request");
276 return;
277 }
278
279 DCHECK(!did_defer_on_writing_);
280 did_defer_on_redirect_ = false;
281 request()->LogUnblocked();
282 controller()->Resume();
249 } 283 }
250 284
251 void MojoAsyncResourceHandler::ResumeForTesting() { 285 void MojoAsyncResourceHandler::OnWritableForTesting() {
252 Resume(); 286 OnWritable(MOJO_RESULT_OK);
253 } 287 }
254 288
255 void MojoAsyncResourceHandler::SetAllocationSizeForTesting(size_t size) { 289 void MojoAsyncResourceHandler::SetAllocationSizeForTesting(size_t size) {
256 g_allocation_size = size; 290 g_allocation_size = size;
257 } 291 }
258 292
259 MojoResult MojoAsyncResourceHandler::BeginWrite(void** data, 293 MojoResult MojoAsyncResourceHandler::BeginWrite(void** data,
260 uint32_t* available) { 294 uint32_t* available) {
261 MojoResult result = mojo::BeginWriteDataRaw( 295 MojoResult result = mojo::BeginWriteDataRaw(
262 shared_writer_->writer(), data, available, MOJO_WRITE_DATA_FLAG_NONE); 296 shared_writer_->writer(), data, available, MOJO_WRITE_DATA_FLAG_NONE);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 if (result == MOJO_RESULT_SHOULD_WAIT) { 378 if (result == MOJO_RESULT_SHOULD_WAIT) {
345 *defer = true; 379 *defer = true;
346 return true; 380 return true;
347 } 381 }
348 if (result != MOJO_RESULT_OK) 382 if (result != MOJO_RESULT_OK)
349 return false; 383 return false;
350 *buf = new WriterIOBuffer(shared_writer_, data, available); 384 *buf = new WriterIOBuffer(shared_writer_, data, available);
351 return true; 385 return true;
352 } 386 }
353 387
354 void MojoAsyncResourceHandler::Resume() { 388 bool MojoAsyncResourceHandler::CheckForSufficientResource() {
355 if (!did_defer_) 389 if (has_checked_for_sufficient_resources_)
390 return true;
391 has_checked_for_sufficient_resources_ = true;
392
393 if (rdh_->HasSufficientResourcesForRequest(request()))
394 return true;
395
396 controller()->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
397 return false;
398 }
399
400 void MojoAsyncResourceHandler::OnWritable(MojoResult result) {
401 if (!did_defer_on_writing_)
356 return; 402 return;
357 did_defer_ = false; 403 DCHECK(!did_defer_on_redirect_);
404 did_defer_on_writing_ = false;
358 405
359 if (is_using_io_buffer_not_from_writer_) { 406 if (is_using_io_buffer_not_from_writer_) {
360 // |buffer_| is set to a net::IOBufferWithSize. Write the buffer contents 407 // |buffer_| is set to a net::IOBufferWithSize. Write the buffer contents
361 // to the data pipe. 408 // to the data pipe.
362 DCHECK_GT(buffer_bytes_read_, 0u); 409 DCHECK_GT(buffer_bytes_read_, 0u);
363 if (!CopyReadDataToDataPipe(&did_defer_)) { 410 if (!CopyReadDataToDataPipe(&did_defer_on_writing_)) {
364 controller()->CancelWithError(net::ERR_FAILED); 411 controller()->CancelWithError(net::ERR_FAILED);
365 return; 412 return;
366 } 413 }
367 } else { 414 } else {
368 // Allocate a buffer for the next OnWillRead call here. 415 // Allocate a buffer for the next OnWillRead call here.
369 if (!AllocateWriterIOBuffer(&buffer_, &did_defer_)) { 416 if (!AllocateWriterIOBuffer(&buffer_, &did_defer_on_writing_)) {
370 controller()->CancelWithError(net::ERR_FAILED); 417 controller()->CancelWithError(net::ERR_FAILED);
371 return; 418 return;
372 } 419 }
373 } 420 }
374 421
375 if (did_defer_) { 422 if (did_defer_on_writing_) {
376 // Continue waiting. 423 // Continue waiting.
377 return; 424 return;
378 } 425 }
379 request()->LogUnblocked(); 426 request()->LogUnblocked();
380 controller()->Resume(); 427 controller()->Resume();
381 } 428 }
382 429
383 void MojoAsyncResourceHandler::OnDefer() {
384 request()->LogBlockedBy("MojoAsyncResourceHandler");
385 did_defer_ = true;
386 }
387
388 bool MojoAsyncResourceHandler::CheckForSufficientResource() {
389 if (has_checked_for_sufficient_resources_)
390 return true;
391 has_checked_for_sufficient_resources_ = true;
392
393 if (rdh_->HasSufficientResourcesForRequest(request()))
394 return true;
395
396 controller()->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
397 return false;
398 }
399
400 void MojoAsyncResourceHandler::OnWritable(MojoResult unused) {
401 Resume();
402 }
403
404 void MojoAsyncResourceHandler::Cancel() { 430 void MojoAsyncResourceHandler::Cancel() {
405 const ResourceRequestInfoImpl* info = GetRequestInfo(); 431 const ResourceRequestInfoImpl* info = GetRequestInfo();
406 ResourceDispatcherHostImpl::Get()->CancelRequestFromRenderer( 432 ResourceDispatcherHostImpl::Get()->CancelRequestFromRenderer(
407 GlobalRequestID(info->GetChildID(), info->GetRequestID())); 433 GlobalRequestID(info->GetChildID(), info->GetRequestID()));
408 } 434 }
409 435
436 void MojoAsyncResourceHandler::ReportBadMessage(const std::string& error) {
437 mojo::ReportBadMessage(error);
438 }
439
410 } // namespace content 440 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/mojo_async_resource_handler.h ('k') | content/browser/loader/mojo_async_resource_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698