| Index: content/browser/loader/intercepting_resource_handler.cc
 | 
| diff --git a/content/browser/loader/intercepting_resource_handler.cc b/content/browser/loader/intercepting_resource_handler.cc
 | 
| index 77b28b41240600b797627cc0d61001299838b3c8..201e88d343c793885ff1f35b555de290c39297e0 100644
 | 
| --- a/content/browser/loader/intercepting_resource_handler.cc
 | 
| +++ b/content/browser/loader/intercepting_resource_handler.cc
 | 
| @@ -98,62 +98,27 @@ void InterceptingResourceHandler::OnWillRead(
 | 
|      scoped_refptr<net::IOBuffer>* buf,
 | 
|      int* buf_size,
 | 
|      std::unique_ptr<ResourceController> controller) {
 | 
| -  if (state_ == State::PASS_THROUGH) {
 | 
| -    next_handler_->OnWillRead(buf, buf_size, std::move(controller));
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  DCHECK_EQ(State::STARTING, state_);
 | 
| -  DCHECK(!first_read_buffer_);
 | 
| -  DCHECK_EQ(0, first_read_buffer_size_);
 | 
| -  DCHECK(!parent_read_buffer_);
 | 
| -  DCHECK(!parent_read_buffer_size_);
 | 
| -
 | 
| -  parent_read_buffer_ = buf;
 | 
| -  parent_read_buffer_size_ = buf_size;
 | 
| -
 | 
| -  state_ = State::SENDING_ON_WILL_READ_TO_OLD_HANDLER;
 | 
| -  HoldController(std::move(controller));
 | 
| -  DoLoop();
 | 
| +  DCHECK_EQ(state_, State::PASS_THROUGH);
 | 
| +  return next_handler_->OnWillRead(buf, buf_size, std::move(controller));
 | 
|  }
 | 
|  
 | 
|  void InterceptingResourceHandler::OnReadCompleted(
 | 
|      int bytes_read,
 | 
|      std::unique_ptr<ResourceController> controller) {
 | 
|    DCHECK(!has_controller());
 | 
| -
 | 
| +  DCHECK_EQ(state_, State::PASS_THROUGH);
 | 
|    DCHECK_GE(bytes_read, 0);
 | 
| -  if (state_ == State::PASS_THROUGH) {
 | 
| -    if (first_read_buffer_double_) {
 | 
| -      // |first_read_buffer_double_| was allocated and the user wrote data to
 | 
| -      // the buffer, but switching has not been done after all.
 | 
| -      memcpy(first_read_buffer_->data(), first_read_buffer_double_->data(),
 | 
| -             bytes_read);
 | 
| -      first_read_buffer_ = nullptr;
 | 
| -      first_read_buffer_double_ = nullptr;
 | 
| -    }
 | 
| -    next_handler_->OnReadCompleted(bytes_read, std::move(controller));
 | 
| -    return;
 | 
| -  }
 | 
|  
 | 
| -  DCHECK_EQ(State::WAITING_FOR_ON_READ_COMPLETED, state_);
 | 
| -  first_read_buffer_bytes_read_ = bytes_read;
 | 
| -  state_ = State::SENDING_BUFFER_TO_NEW_HANDLER;
 | 
| -  HoldController(std::move(controller));
 | 
| -  DoLoop();
 | 
| +  next_handler_->OnReadCompleted(bytes_read, std::move(controller));
 | 
|  }
 | 
|  
 | 
|  void InterceptingResourceHandler::OnResponseCompleted(
 | 
|      const net::URLRequestStatus& status,
 | 
|      std::unique_ptr<ResourceController> controller) {
 | 
| -  if (state_ == State::PASS_THROUGH) {
 | 
| -    LayeredResourceHandler::OnResponseCompleted(status, std::move(controller));
 | 
| -    return;
 | 
| -  }
 | 
| -  if (!new_handler_) {
 | 
| -    // Therer is only one ResourceHandler in this InterceptingResourceHandler.
 | 
| +  if (!new_handler_)
 | 
|      state_ = State::PASS_THROUGH;
 | 
| -    first_read_buffer_double_ = nullptr;
 | 
| +
 | 
| +  if (state_ == State::PASS_THROUGH) {
 | 
|      next_handler_->OnResponseCompleted(status, std::move(controller));
 | 
|      return;
 | 
|    }
 | 
| @@ -170,7 +135,6 @@ void InterceptingResourceHandler::OnResponseCompleted(
 | 
|    DCHECK(was_resumed);
 | 
|  
 | 
|    state_ = State::PASS_THROUGH;
 | 
| -  first_read_buffer_double_ = nullptr;
 | 
|    next_handler_ = std::move(new_handler_);
 | 
|    next_handler_->OnResponseCompleted(status, std::move(controller));
 | 
|  }
 | 
| @@ -195,32 +159,12 @@ void InterceptingResourceHandler::DoLoop() {
 | 
|  
 | 
|      switch (state_) {
 | 
|        case State::STARTING:
 | 
| -      case State::WAITING_FOR_ON_READ_COMPLETED:
 | 
|        case State::PASS_THROUGH:
 | 
|          NOTREACHED();
 | 
|          break;
 | 
| -      case State::SENDING_ON_WILL_READ_TO_OLD_HANDLER:
 | 
| -        SendOnWillReadToOldHandler();
 | 
| -        break;
 | 
| -      case State::WAITING_FOR_OLD_HANDLERS_BUFFER:
 | 
| -        OnBufferReceived();
 | 
| -        break;
 | 
|        case State::SENDING_ON_WILL_START_TO_NEW_HANDLER:
 | 
|          SendOnResponseStartedToNewHandler();
 | 
|          break;
 | 
| -      case State::SENDING_ON_RESPONSE_STARTED_TO_NEW_HANDLER:
 | 
| -        if (first_read_buffer_double_) {
 | 
| -          // OnWillRead has been called, so copying the data from
 | 
| -          // |first_read_buffer_double_| to |first_read_buffer_| will be needed
 | 
| -          // when OnReadCompleted is called.
 | 
| -          state_ = State::WAITING_FOR_ON_READ_COMPLETED;
 | 
| -        } else {
 | 
| -          // OnWillRead has not been called, so no special handling will be
 | 
| -          // needed from now on.
 | 
| -          state_ = State::PASS_THROUGH;
 | 
| -        }
 | 
| -        ResumeInternal();
 | 
| -        break;
 | 
|        case State::SWAPPING_HANDLERS:
 | 
|          SendOnResponseStartedToOldHandler();
 | 
|          break;
 | 
| @@ -230,12 +174,6 @@ void InterceptingResourceHandler::DoLoop() {
 | 
|        case State::RECEIVING_BUFFER_FROM_OLD_HANDLER:
 | 
|          ReceivedBufferFromOldHandler();
 | 
|          break;
 | 
| -      case State::SENDING_BUFFER_TO_NEW_HANDLER:
 | 
| -        SendFirstReadBufferToNewHandler();
 | 
| -        break;
 | 
| -      case State::SENDING_BUFFER_TO_NEW_HANDLER_WAITING_FOR_BUFFER:
 | 
| -        ReceivedBufferFromNewHandler();
 | 
| -        break;
 | 
|      }
 | 
|    }
 | 
|  }
 | 
| @@ -243,7 +181,6 @@ void InterceptingResourceHandler::DoLoop() {
 | 
|  void InterceptingResourceHandler::ResumeInternal() {
 | 
|    DCHECK(has_controller());
 | 
|    if (state_ == State::STARTING ||
 | 
| -      state_ == State::WAITING_FOR_ON_READ_COMPLETED ||
 | 
|        state_ == State::PASS_THROUGH) {
 | 
|      // Uninteresting Resume: just delegate to the original resource controller.
 | 
|      Resume();
 | 
| @@ -265,36 +202,6 @@ void InterceptingResourceHandler::ResumeInternal() {
 | 
|                              weak_ptr_factory_.GetWeakPtr()));
 | 
|  }
 | 
|  
 | 
| -void InterceptingResourceHandler::SendOnWillReadToOldHandler() {
 | 
| -  DCHECK_EQ(State::SENDING_ON_WILL_READ_TO_OLD_HANDLER, state_);
 | 
| -
 | 
| -  state_ = State::WAITING_FOR_OLD_HANDLERS_BUFFER;
 | 
| -  next_handler_->OnWillRead(&first_read_buffer_, &first_read_buffer_size_,
 | 
| -                            base::MakeUnique<Controller>(this));
 | 
| -}
 | 
| -
 | 
| -void InterceptingResourceHandler::OnBufferReceived() {
 | 
| -  DCHECK_EQ(State::WAITING_FOR_OLD_HANDLERS_BUFFER, state_);
 | 
| -
 | 
| -  // TODO(mmenke):  If this method is just going to allocate a double buffer
 | 
| -  // anyways, can the call to the old handler's OnWillRead be removed? That
 | 
| -  // would mean handling replaying data in the case that |next_handler_|'s
 | 
| -  // buffer is smaller than the double buffer, but SendPayloadToOldHandler
 | 
| -  // already handles that case, anyways, so could share that code with the
 | 
| -  // no-swap path as well. Or better, just have MimeSniffingResourceHandler
 | 
| -  // create and manage the buffer itself.
 | 
| -  first_read_buffer_double_ =
 | 
| -      new net::IOBuffer(static_cast<size_t>(first_read_buffer_size_));
 | 
| -  *parent_read_buffer_ = first_read_buffer_double_;
 | 
| -  *parent_read_buffer_size_ = first_read_buffer_size_;
 | 
| -
 | 
| -  parent_read_buffer_ = nullptr;
 | 
| -  parent_read_buffer_size_ = nullptr;
 | 
| -
 | 
| -  state_ = State::STARTING;
 | 
| -  Resume();
 | 
| -}
 | 
| -
 | 
|  void InterceptingResourceHandler::SendOnResponseStartedToOldHandler() {
 | 
|    state_ = State::SENDING_PAYLOAD_TO_OLD_HANDLER;
 | 
|    next_handler_->OnResponseStarted(response_.get(),
 | 
| @@ -321,6 +228,10 @@ void InterceptingResourceHandler::SendPayloadToOldHandler() {
 | 
|  
 | 
|      next_handler_ = std::move(new_handler_);
 | 
|      state_ = State::SENDING_ON_WILL_START_TO_NEW_HANDLER;
 | 
| +
 | 
| +    // Note that this call may be a lie--the new handler will often have been
 | 
| +    // substituted in after the request has actually started, so the new
 | 
| +    // handler will not have the chance to cancel the request before it starts.
 | 
|      next_handler_->OnWillStart(request()->url(),
 | 
|                                 base::MakeUnique<Controller>(this));
 | 
|      return;
 | 
| @@ -328,37 +239,26 @@ void InterceptingResourceHandler::SendPayloadToOldHandler() {
 | 
|  
 | 
|    state_ = State::RECEIVING_BUFFER_FROM_OLD_HANDLER;
 | 
|  
 | 
| -  scoped_refptr<net::IOBuffer> buffer;
 | 
| -  // If |first_read_buffer_| is non-NULL, it was already received from
 | 
| -  // |next_handler_| via OnWillRead.  Can just use the buffer.
 | 
| -  if (first_read_buffer_) {
 | 
| -    DCHECK_GT(first_read_buffer_size_, 0);
 | 
| -
 | 
| -    ResumeInternal();
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  DCHECK(!first_read_buffer_size_);
 | 
| -  next_handler_->OnWillRead(&first_read_buffer_, &first_read_buffer_size_,
 | 
| +  DCHECK_EQ(read_buffer_size_, 0);
 | 
| +  next_handler_->OnWillRead(&read_buffer_, &read_buffer_size_,
 | 
|                              base::MakeUnique<Controller>(this));
 | 
|  }
 | 
|  
 | 
|  void InterceptingResourceHandler::ReceivedBufferFromOldHandler() {
 | 
|    DCHECK_EQ(State::RECEIVING_BUFFER_FROM_OLD_HANDLER, state_);
 | 
| -  DCHECK(first_read_buffer_);
 | 
| -  DCHECK_GT(first_read_buffer_size_, 0);
 | 
| -
 | 
| -  int bytes_to_copy =
 | 
| -      std::min(first_read_buffer_size_,
 | 
| -               static_cast<int>(payload_for_old_handler_.size() -
 | 
| -                                payload_bytes_written_));
 | 
| -  memcpy(first_read_buffer_->data(),
 | 
| +  DCHECK(read_buffer_);
 | 
| +  DCHECK_GT(read_buffer_size_, 0);
 | 
| +
 | 
| +  int bytes_to_copy = std::min(
 | 
| +      read_buffer_size_, static_cast<int>(payload_for_old_handler_.size() -
 | 
| +                                          payload_bytes_written_));
 | 
| +  memcpy(read_buffer_->data(),
 | 
|           payload_for_old_handler_.data() + payload_bytes_written_,
 | 
|           bytes_to_copy);
 | 
|    payload_bytes_written_ += bytes_to_copy;
 | 
|  
 | 
| -  first_read_buffer_ = nullptr;
 | 
| -  first_read_buffer_size_ = 0;
 | 
| +  read_buffer_ = nullptr;
 | 
| +  read_buffer_size_ = 0;
 | 
|  
 | 
|    state_ = State::SENDING_PAYLOAD_TO_OLD_HANDLER;
 | 
|    next_handler_->OnReadCompleted(bytes_to_copy,
 | 
| @@ -366,49 +266,9 @@ void InterceptingResourceHandler::ReceivedBufferFromOldHandler() {
 | 
|  }
 | 
|  
 | 
|  void InterceptingResourceHandler::SendOnResponseStartedToNewHandler() {
 | 
| -  state_ = State::SENDING_ON_RESPONSE_STARTED_TO_NEW_HANDLER;
 | 
| +  state_ = State::PASS_THROUGH;
 | 
|    next_handler_->OnResponseStarted(response_.get(),
 | 
|                                     base::MakeUnique<Controller>(this));
 | 
|  }
 | 
|  
 | 
| -void InterceptingResourceHandler::SendFirstReadBufferToNewHandler() {
 | 
| -  DCHECK_EQ(state_, State::SENDING_BUFFER_TO_NEW_HANDLER);
 | 
| -  DCHECK(!new_handler_read_buffer_);
 | 
| -  DCHECK(!new_handler_read_buffer_size_);
 | 
| -
 | 
| -  if (first_read_buffer_bytes_written_ == first_read_buffer_bytes_read_) {
 | 
| -    state_ = State::PASS_THROUGH;
 | 
| -    first_read_buffer_double_ = nullptr;
 | 
| -    ResumeInternal();
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  state_ = State::SENDING_BUFFER_TO_NEW_HANDLER_WAITING_FOR_BUFFER;
 | 
| -  next_handler_->OnWillRead(&new_handler_read_buffer_,
 | 
| -                            &new_handler_read_buffer_size_,
 | 
| -                            base::MakeUnique<Controller>(this));
 | 
| -}
 | 
| -
 | 
| -void InterceptingResourceHandler::ReceivedBufferFromNewHandler() {
 | 
| -  DCHECK_EQ(state_, State::SENDING_BUFFER_TO_NEW_HANDLER_WAITING_FOR_BUFFER);
 | 
| -  DCHECK(new_handler_read_buffer_);
 | 
| -  DCHECK(new_handler_read_buffer_size_);
 | 
| -
 | 
| -  int bytes_to_copy =
 | 
| -      std::min(new_handler_read_buffer_size_,
 | 
| -               static_cast<int>(first_read_buffer_bytes_read_ -
 | 
| -                                first_read_buffer_bytes_written_));
 | 
| -  memcpy(new_handler_read_buffer_->data(),
 | 
| -         first_read_buffer_double_->data() + first_read_buffer_bytes_written_,
 | 
| -         bytes_to_copy);
 | 
| -  first_read_buffer_bytes_written_ += bytes_to_copy;
 | 
| -
 | 
| -  new_handler_read_buffer_ = nullptr;
 | 
| -  new_handler_read_buffer_size_ = 0;
 | 
| -
 | 
| -  state_ = State::SENDING_BUFFER_TO_NEW_HANDLER;
 | 
| -  next_handler_->OnReadCompleted(bytes_to_copy,
 | 
| -                                 base::MakeUnique<Controller>(this));
 | 
| -}
 | 
| -
 | 
|  }  // namespace content
 | 
| 
 |