Chromium Code Reviews| Index: content/browser/loader/buffered_resource_handler.h |
| diff --git a/content/browser/loader/buffered_resource_handler.h b/content/browser/loader/buffered_resource_handler.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3107aa390a76d8084a278ae3d4a3c7c5492527c4 |
| --- /dev/null |
| +++ b/content/browser/loader/buffered_resource_handler.h |
| @@ -0,0 +1,140 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef CONTENT_BROWSER_LOADER_BUFFERED_RESOURCE_HANDLER_H_ |
| +#define CONTENT_BROWSER_LOADER_BUFFERED_RESOURCE_HANDLER_H_ |
| + |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/macros.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "content/browser/loader/layered_resource_handler.h" |
| +#include "content/common/content_export.h" |
| +#include "content/public/browser/resource_controller.h" |
| + |
| +namespace net { |
| +class URLRequest; |
| +} |
| + |
| +namespace content { |
| +class ResourceDispatcherHostImpl; |
| + |
| +// ResourceHandler that, if necessary, buffers a response body without passing |
| +// it to the next ResourceHandler until asked to do so. |
| +// |
| +// Uses the buffer provided by the original event handler for buffering, and |
| +// continues to reuses it until it's done buffering. As a result, the buffer |
| +// returned by the next ResourceHandler must have a capacity of at least |
| +// net::kMaxBytesToBuffer * 2. |
| +class CONTENT_EXPORT BufferedResourceHandler : public LayeredResourceHandler, |
|
mmenke
2016/05/26 17:30:22
What's the motivation for separating this out, and
mmenke
2016/05/26 20:01:41
My reason for asking is that I really don't want t
clamy
2016/05/30 15:08:17
As I explained in the review message, I split into
|
| + public ResourceController { |
| + public: |
| + BufferedResourceHandler(std::unique_ptr<ResourceHandler> next_handler, |
| + net::URLRequest* request, |
| + int max_bytes_to_buffer); |
| + ~BufferedResourceHandler() override; |
| + |
| + protected: |
| + ResourceResponse* response() const { return response_.get(); } |
| + int bytes_read() const { return bytes_read_; } |
| + net::IOBuffer* read_buffer() const { return read_buffer_.get(); } |
| + |
| + // Called in OnResponseStarted and OnReadCompleted to see if the |
| + // BufferedResourceHandler can go from buffering to replaying the buffered |
| + // data. |
| + virtual bool CanStartReplayInResponseStarted(); |
| + virtual bool CanStartReplayInReadCompleted(); |
| + |
| + |
| + // Called when starting to replay the buffered data to the downstream |
| + // ResourceHandlers. If the return value is false, the request will be |
| + // canceled. If |defer| is set to true, the replay attempt will stop until |
| + // ProcessReplay is called (WillStartReplay will be called again by |
| + // ProcessReplay). |
| + virtual bool WillStartReplay(bool* defer); |
| + |
| + // Replays the buffered data to the downstream ResourceHandlers. This should |
| + // only ba called directly when the previous replay attempt was paused by |
| + // WillStartReplay. |
| + bool ProcessReplay(bool* defer); |
| + |
| + // LayeredResourceHandler implementation: |
| + void InstallNewLeafHandler( |
| + std::unique_ptr<ResourceHandler> new_handler, |
| + const std::string& payload_for_old_handler) override; |
| + |
| + private: |
| + enum State { |
| + // Starting state of the BufferedResourceHandler. In this state, it is |
| + // acting as a blind pass-through ResourceHandler. |
| + STATE_STARTING, |
| + |
| + // In this state, the BufferedResourceHandler is buffering the response |
| + // data in read_buffer_. |
| + STATE_BUFFERING, |
| + |
| + // In this state, the request is paused and the BufferedResourceHandler is |
| + // waiting to start the replay of the response to the downstream |
| + // ResourceHandlers. |
| + STATE_PROCESSING, |
| + |
| + // In this state, the BufferedResourceHandler is replaying the buffered |
| + // OnResponseStarted event to the downstream ResourceHandlers. |
| + STATE_REPLAYING_RESPONSE_RECEIVED, |
| + |
| + // In this state, the BufferedResourceHandler is replaying the buffered |
| + // OnResponseStarted event to the new leaf handler, if there is one. |
| + STATE_REPLAYING_RESPONSE_RECEIVED_NEW_HANDLER, |
| + |
| + // In this state, the BufferedResourceHandler is just a blind pass-through |
| + // ResourceHandler. |
| + STATE_STREAMING, |
| + }; |
| + |
| + // ResourceHandler implementation: |
| + void SetController(ResourceController* controller) override; |
| + bool OnResponseStarted(ResourceResponse* response, bool* defer) override; |
| + bool OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| + int* buf_size, |
| + int min_size) override; |
| + bool OnReadCompleted(int bytes_read, bool* defer) override; |
| + void OnResponseCompleted(const net::URLRequestStatus& status, |
| + const std::string& security_info, |
| + bool* defer) override; |
| + |
| + // ResourceController implementation: |
| + void Resume() override; |
| + void Cancel() override; |
| + void CancelAndIgnore() override; |
| + void CancelWithError(int error_code) override; |
| + |
| + bool MaybeStartReplay(bool* defer); |
| + bool ReplayResponseReceived(bool* defer); |
| + bool ReplayResponseReceivedNewHandler(bool* defer); |
| + bool ReplayReadCompleted(bool* defer); |
| + |
| + State state_; |
| + |
| + const int max_bytes_to_buffer_; |
| + |
| + // Used to buffer the reponse received until replay. |
| + scoped_refptr<ResourceResponse> response_; |
| + scoped_refptr<net::IOBuffer> read_buffer_; |
| + int read_buffer_size_; |
| + int bytes_read_; |
| + |
| + // Used to store a new leaf ResourceHandler until the actual one can be |
| + // replaced during the replay of the reponse. |
| + std::unique_ptr<ResourceHandler> new_leaf_handler_; |
| + std::string payload_for_old_handler_; |
| + |
| + base::WeakPtrFactory<BufferedResourceHandler> weak_ptr_factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(BufferedResourceHandler); |
| +}; |
| + |
| +} // namespace content |
| + |
| +#endif // CONTENT_BROWSER_LOADER_BUFFERED_RESOURCE_HANDLER_H_ |