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

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

Issue 2668603003: Make ResourceHandler::OnWillRead able to complete asynchronously. (Closed)
Patch Set: One bot doesn't like 256 day timers. :( Created 3 years, 10 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
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 "content/browser/loader/mime_sniffing_resource_handler.h" 5 #include "content/browser/loader/mime_sniffing_resource_handler.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 : LayeredResourceHandler(request, std::move(next_handler)), 118 : LayeredResourceHandler(request, std::move(next_handler)),
119 state_(STATE_STARTING), 119 state_(STATE_STARTING),
120 host_(host), 120 host_(host),
121 #if BUILDFLAG(ENABLE_PLUGINS) 121 #if BUILDFLAG(ENABLE_PLUGINS)
122 plugin_service_(plugin_service), 122 plugin_service_(plugin_service),
123 #endif 123 #endif
124 must_download_(false), 124 must_download_(false),
125 must_download_is_set_(false), 125 must_download_is_set_(false),
126 read_buffer_size_(0), 126 read_buffer_size_(0),
127 bytes_read_(0), 127 bytes_read_(0),
128 parent_read_buffer_(nullptr),
129 parent_read_buffer_size_(nullptr),
128 intercepting_handler_(intercepting_handler), 130 intercepting_handler_(intercepting_handler),
129 request_context_type_(request_context_type), 131 request_context_type_(request_context_type),
130 in_state_loop_(false), 132 in_state_loop_(false),
131 advance_state_(false), 133 advance_state_(false),
132 weak_ptr_factory_(this) { 134 weak_ptr_factory_(this) {
133 } 135 }
134 136
135 MimeSniffingResourceHandler::~MimeSniffingResourceHandler() {} 137 MimeSniffingResourceHandler::~MimeSniffingResourceHandler() {}
136 138
137 void MimeSniffingResourceHandler::OnWillStart( 139 void MimeSniffingResourceHandler::OnWillStart(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 if (response_->head.mime_type == "application/rss+xml" || 210 if (response_->head.mime_type == "application/rss+xml" ||
209 response_->head.mime_type == "application/atom+xml") { 211 response_->head.mime_type == "application/atom+xml") {
210 response_->head.mime_type.assign("text/plain"); 212 response_->head.mime_type.assign("text/plain");
211 } 213 }
212 } 214 }
213 215
214 HoldController(std::move(controller)); 216 HoldController(std::move(controller));
215 AdvanceState(); 217 AdvanceState();
216 } 218 }
217 219
218 bool MimeSniffingResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, 220 void MimeSniffingResourceHandler::OnWillRead(
219 int* buf_size) { 221 scoped_refptr<net::IOBuffer>* buf,
220 if (state_ == STATE_STREAMING) 222 int* buf_size,
221 return next_handler_->OnWillRead(buf, buf_size); 223 std::unique_ptr<ResourceController> controller) {
224 DCHECK(buf);
225 DCHECK(buf_size);
226 DCHECK(!parent_read_buffer_);
227 DCHECK(!parent_read_buffer_size_);
228
229 if (state_ == STATE_STREAMING) {
230 next_handler_->OnWillRead(buf, buf_size, std::move(controller));
231 return;
232 }
233
234 DCHECK_EQ(State::STATE_BUFFERING, state_);
222 235
223 if (read_buffer_.get()) { 236 if (read_buffer_.get()) {
224 CHECK_LT(bytes_read_, read_buffer_size_); 237 CHECK_LT(bytes_read_, read_buffer_size_);
225 *buf = new DependentIOBuffer(read_buffer_.get(), bytes_read_); 238 *buf = new DependentIOBuffer(read_buffer_.get(), bytes_read_);
226 *buf_size = read_buffer_size_ - bytes_read_; 239 *buf_size = read_buffer_size_ - bytes_read_;
227 } else { 240 controller->Resume();
228 if (!next_handler_->OnWillRead(buf, buf_size)) 241 return;
229 return false; 242 }
230 243
231 read_buffer_ = *buf; 244 DCHECK(!read_buffer_size_);
232 read_buffer_size_ = *buf_size; 245
233 DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2); 246 parent_read_buffer_ = buf;
234 } 247 parent_read_buffer_size_ = buf_size;
235 return true; 248
249 HoldController(std::move(controller));
250
251 // Have to go through AdvanceState here so that if OnWillRead completes
252 // synchronously, won't post a task.
253 state_ = State::STATE_CALLING_ON_WILL_READ;
254 AdvanceState();
236 } 255 }
237 256
238 void MimeSniffingResourceHandler::OnReadCompleted( 257 void MimeSniffingResourceHandler::OnReadCompleted(
239 int bytes_read, 258 int bytes_read,
240 std::unique_ptr<ResourceController> controller) { 259 std::unique_ptr<ResourceController> controller) {
241 DCHECK(!has_controller()); 260 DCHECK(!has_controller());
242 261
243 if (state_ == STATE_STREAMING) { 262 if (state_ == STATE_STREAMING) {
244 next_handler_->OnReadCompleted(bytes_read, std::move(controller)); 263 next_handler_->OnReadCompleted(bytes_read, std::move(controller));
245 return; 264 return;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 328
310 base::AutoReset<bool> auto_in_state_loop(&in_state_loop_, true); 329 base::AutoReset<bool> auto_in_state_loop(&in_state_loop_, true);
311 advance_state_ = true; 330 advance_state_ = true;
312 while (advance_state_) { 331 while (advance_state_) {
313 advance_state_ = false; 332 advance_state_ = false;
314 333
315 switch (state_) { 334 switch (state_) {
316 case STATE_BUFFERING: 335 case STATE_BUFFERING:
317 MaybeIntercept(); 336 MaybeIntercept();
318 break; 337 break;
338 case STATE_CALLING_ON_WILL_READ:
339 CallOnWillRead();
340 break;
341 case STATE_WAITING_FOR_BUFFER:
342 BufferReceived();
343 break;
319 case STATE_INTERCEPTION_CHECK_DONE: 344 case STATE_INTERCEPTION_CHECK_DONE:
320 ReplayResponseReceived(); 345 ReplayResponseReceived();
321 break; 346 break;
322 case STATE_REPLAYING_RESPONSE_RECEIVED: 347 case STATE_REPLAYING_RESPONSE_RECEIVED:
323 ReplayReadCompleted(); 348 ReplayReadCompleted();
324 break; 349 break;
325 case STATE_STARTING: 350 case STATE_STARTING:
326 case STATE_STREAMING: 351 case STATE_STREAMING:
327 in_state_loop_ = false;
328 Resume(); 352 Resume();
329 return; 353 return;
330 default: 354 default:
331 NOTREACHED(); 355 NOTREACHED();
332 break; 356 break;
333 } 357 }
334 } 358 }
335 359
336 DCHECK(in_state_loop_); 360 DCHECK(in_state_loop_);
337 in_state_loop_ = false; 361 in_state_loop_ = false;
338 } 362 }
339 363
340 void MimeSniffingResourceHandler::MaybeIntercept() { 364 void MimeSniffingResourceHandler::MaybeIntercept() {
341 DCHECK_EQ(STATE_BUFFERING, state_); 365 DCHECK_EQ(STATE_BUFFERING, state_);
342 // If a request that can be intercepted failed the check for interception 366 // If a request that can be intercepted failed the check for interception
343 // step, it should be canceled. 367 // step, it should be canceled.
344 if (!MaybeStartInterception()) 368 if (!MaybeStartInterception())
345 return; 369 return;
346 370
347 state_ = STATE_INTERCEPTION_CHECK_DONE; 371 state_ = STATE_INTERCEPTION_CHECK_DONE;
348 ResumeInternal(); 372 ResumeInternal();
349 } 373 }
350 374
375 void MimeSniffingResourceHandler::CallOnWillRead() {
376 DCHECK_EQ(STATE_CALLING_ON_WILL_READ, state_);
377
378 state_ = STATE_WAITING_FOR_BUFFER;
379 next_handler_->OnWillRead(&read_buffer_, &read_buffer_size_,
380 base::MakeUnique<Controller>(this));
381 }
382
383 void MimeSniffingResourceHandler::BufferReceived() {
384 DCHECK_EQ(STATE_WAITING_FOR_BUFFER, state_);
385
386 DCHECK(read_buffer_);
387 DCHECK(parent_read_buffer_);
388 DCHECK(parent_read_buffer_size_);
389 DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2);
390
391 *parent_read_buffer_ = read_buffer_;
Charlie Harrison 2017/02/16 21:25:04 I think you should std::move() here to condense th
mmenke 2017/03/08 19:16:07 That wouldn't be correct - we need the buffer poin
Charlie Harrison 2017/03/08 21:12:46 You're completely right, apologies.
392 *parent_read_buffer_size_ = read_buffer_size_;
393
394 parent_read_buffer_ = nullptr;
395 parent_read_buffer_size_ = nullptr;
396
397 state_ = State::STATE_BUFFERING;
398 Resume();
399 }
400
351 void MimeSniffingResourceHandler::ReplayResponseReceived() { 401 void MimeSniffingResourceHandler::ReplayResponseReceived() {
352 DCHECK_EQ(STATE_INTERCEPTION_CHECK_DONE, state_); 402 DCHECK_EQ(STATE_INTERCEPTION_CHECK_DONE, state_);
353 state_ = STATE_REPLAYING_RESPONSE_RECEIVED; 403 state_ = STATE_REPLAYING_RESPONSE_RECEIVED;
354 next_handler_->OnResponseStarted(response_.get(), 404 next_handler_->OnResponseStarted(response_.get(),
355 base::MakeUnique<Controller>(this)); 405 base::MakeUnique<Controller>(this));
356 } 406 }
357 407
358 void MimeSniffingResourceHandler::ReplayReadCompleted() { 408 void MimeSniffingResourceHandler::ReplayReadCompleted() {
359 DCHECK_EQ(STATE_REPLAYING_RESPONSE_RECEIVED, state_); 409 DCHECK_EQ(STATE_REPLAYING_RESPONSE_RECEIVED, state_);
360 410
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 605
556 void MimeSniffingResourceHandler::OnPluginsLoaded( 606 void MimeSniffingResourceHandler::OnPluginsLoaded(
557 const std::vector<WebPluginInfo>& plugins) { 607 const std::vector<WebPluginInfo>& plugins) {
558 // No longer blocking on the plugins being loaded. 608 // No longer blocking on the plugins being loaded.
559 request()->LogUnblocked(); 609 request()->LogUnblocked();
560 if (state_ == STATE_BUFFERING) 610 if (state_ == STATE_BUFFERING)
561 AdvanceState(); 611 AdvanceState();
562 } 612 }
563 613
564 } // namespace content 614 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698