| Index: content/browser/loader/mime_sniffing_resource_handler.cc
|
| diff --git a/content/browser/loader/mime_sniffing_resource_handler.cc b/content/browser/loader/mime_sniffing_resource_handler.cc
|
| index e90fa81d7ff9e2e72de54c88b614a550323ad892..29d9b12a8ffb2231e46839d91dfb8c244ab141ca 100644
|
| --- a/content/browser/loader/mime_sniffing_resource_handler.cc
|
| +++ b/content/browser/loader/mime_sniffing_resource_handler.cc
|
| @@ -125,6 +125,8 @@ MimeSniffingResourceHandler::MimeSniffingResourceHandler(
|
| must_download_is_set_(false),
|
| read_buffer_size_(0),
|
| bytes_read_(0),
|
| + parent_read_buffer_(nullptr),
|
| + parent_read_buffer_size_(nullptr),
|
| intercepting_handler_(intercepting_handler),
|
| request_context_type_(request_context_type),
|
| in_state_loop_(false),
|
| @@ -215,24 +217,41 @@ void MimeSniffingResourceHandler::OnResponseStarted(
|
| AdvanceState();
|
| }
|
|
|
| -bool MimeSniffingResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
|
| - int* buf_size) {
|
| - if (state_ == STATE_STREAMING)
|
| - return next_handler_->OnWillRead(buf, buf_size);
|
| +void MimeSniffingResourceHandler::OnWillRead(
|
| + scoped_refptr<net::IOBuffer>* buf,
|
| + int* buf_size,
|
| + std::unique_ptr<ResourceController> controller) {
|
| + DCHECK(buf);
|
| + DCHECK(buf_size);
|
| + DCHECK(!parent_read_buffer_);
|
| + DCHECK(!parent_read_buffer_size_);
|
| +
|
| + if (state_ == STATE_STREAMING) {
|
| + next_handler_->OnWillRead(buf, buf_size, std::move(controller));
|
| + return;
|
| + }
|
| +
|
| + DCHECK_EQ(State::STATE_BUFFERING, state_);
|
|
|
| if (read_buffer_.get()) {
|
| CHECK_LT(bytes_read_, read_buffer_size_);
|
| *buf = new DependentIOBuffer(read_buffer_.get(), bytes_read_);
|
| *buf_size = read_buffer_size_ - bytes_read_;
|
| - } else {
|
| - if (!next_handler_->OnWillRead(buf, buf_size))
|
| - return false;
|
| -
|
| - read_buffer_ = *buf;
|
| - read_buffer_size_ = *buf_size;
|
| - DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2);
|
| + controller->Resume();
|
| + return;
|
| }
|
| - return true;
|
| +
|
| + DCHECK(!read_buffer_size_);
|
| +
|
| + parent_read_buffer_ = buf;
|
| + parent_read_buffer_size_ = buf_size;
|
| +
|
| + HoldController(std::move(controller));
|
| +
|
| + // Have to go through AdvanceState here so that if OnWillRead completes
|
| + // synchronously, won't post a task.
|
| + state_ = State::STATE_CALLING_ON_WILL_READ;
|
| + AdvanceState();
|
| }
|
|
|
| void MimeSniffingResourceHandler::OnReadCompleted(
|
| @@ -316,6 +335,12 @@ void MimeSniffingResourceHandler::AdvanceState() {
|
| case STATE_BUFFERING:
|
| MaybeIntercept();
|
| break;
|
| + case STATE_CALLING_ON_WILL_READ:
|
| + CallOnWillRead();
|
| + break;
|
| + case STATE_WAITING_FOR_BUFFER:
|
| + BufferReceived();
|
| + break;
|
| case STATE_INTERCEPTION_CHECK_DONE:
|
| ReplayResponseReceived();
|
| break;
|
| @@ -324,7 +349,6 @@ void MimeSniffingResourceHandler::AdvanceState() {
|
| break;
|
| case STATE_STARTING:
|
| case STATE_STREAMING:
|
| - in_state_loop_ = false;
|
| Resume();
|
| return;
|
| default:
|
| @@ -348,6 +372,32 @@ void MimeSniffingResourceHandler::MaybeIntercept() {
|
| ResumeInternal();
|
| }
|
|
|
| +void MimeSniffingResourceHandler::CallOnWillRead() {
|
| + DCHECK_EQ(STATE_CALLING_ON_WILL_READ, state_);
|
| +
|
| + state_ = STATE_WAITING_FOR_BUFFER;
|
| + next_handler_->OnWillRead(&read_buffer_, &read_buffer_size_,
|
| + base::MakeUnique<Controller>(this));
|
| +}
|
| +
|
| +void MimeSniffingResourceHandler::BufferReceived() {
|
| + DCHECK_EQ(STATE_WAITING_FOR_BUFFER, state_);
|
| +
|
| + DCHECK(read_buffer_);
|
| + DCHECK(parent_read_buffer_);
|
| + DCHECK(parent_read_buffer_size_);
|
| + DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2);
|
| +
|
| + *parent_read_buffer_ = read_buffer_;
|
| + *parent_read_buffer_size_ = read_buffer_size_;
|
| +
|
| + parent_read_buffer_ = nullptr;
|
| + parent_read_buffer_size_ = nullptr;
|
| +
|
| + state_ = State::STATE_BUFFERING;
|
| + Resume();
|
| +}
|
| +
|
| void MimeSniffingResourceHandler::ReplayResponseReceived() {
|
| DCHECK_EQ(STATE_INTERCEPTION_CHECK_DONE, state_);
|
| state_ = STATE_REPLAYING_RESPONSE_RECEIVED;
|
|
|