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_ |