OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #ifndef CONTENT_BROWSER_LOADER_INTERCEPTING_RESOURCE_HANDLER_H_ | 5 #ifndef CONTENT_BROWSER_LOADER_INTERCEPTING_RESOURCE_HANDLER_H_ |
6 #define CONTENT_BROWSER_LOADER_INTERCEPTING_RESOURCE_HANDLER_H_ | 6 #define CONTENT_BROWSER_LOADER_INTERCEPTING_RESOURCE_HANDLER_H_ |
7 | 7 |
8 #include <memory> | 8 #include <memory> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 int* buf_size, | 49 int* buf_size, |
50 std::unique_ptr<ResourceController> controller) override; | 50 std::unique_ptr<ResourceController> controller) override; |
51 void OnReadCompleted(int bytes_read, | 51 void OnReadCompleted(int bytes_read, |
52 std::unique_ptr<ResourceController> controller) override; | 52 std::unique_ptr<ResourceController> controller) override; |
53 void OnResponseCompleted( | 53 void OnResponseCompleted( |
54 const net::URLRequestStatus& status, | 54 const net::URLRequestStatus& status, |
55 std::unique_ptr<ResourceController> controller) override; | 55 std::unique_ptr<ResourceController> controller) override; |
56 | 56 |
57 // Replaces the next handler with |new_handler|, sending | 57 // Replaces the next handler with |new_handler|, sending |
58 // |payload_for_old_handler| to the old handler. Must be called after | 58 // |payload_for_old_handler| to the old handler. Must be called after |
59 // OnWillStart and OnRequestRedirected and before OnResponseStarted. One | 59 // OnWillStart and OnRequestRedirected and before OnResponseStarted. |
60 // OnWillRead call is permitted beforehand. |new_handler|'s OnWillStart and | 60 // OnWillRead may not be called be called before this call. |new_handler|'s |
61 // OnRequestRedirected methods will not be called. | 61 // OnRequestRedirected method will not be called. |new_handler|'s |
| 62 // OnWillStart() method will be called following the call to |
| 63 // InterceptingResourceHandler::OnResponseStarted. |
62 void UseNewHandler(std::unique_ptr<ResourceHandler> new_handler, | 64 void UseNewHandler(std::unique_ptr<ResourceHandler> new_handler, |
63 const std::string& payload_for_old_handler); | 65 const std::string& payload_for_old_handler); |
64 | 66 |
65 // Used in tests. | 67 // Used in tests. |
66 ResourceHandler* new_handler_for_testing() const { | 68 ResourceHandler* new_handler_for_testing() const { |
67 return new_handler_.get(); | 69 return new_handler_.get(); |
68 } | 70 } |
69 | 71 |
70 private: | 72 private: |
71 // ResourceController subclass that calls into the InterceptingResourceHandler | 73 // ResourceController subclass that calls into the InterceptingResourceHandler |
72 // on cancel/resume. | 74 // on cancel/resume. |
73 class Controller; | 75 class Controller; |
74 | 76 |
75 enum class State { | 77 enum class State { |
76 // The InterceptingResourceHandler is waiting for the mime type of the | 78 // The InterceptingResourceHandler is waiting for the mime type of the |
77 // response to be identified, to check if the next handler should be | 79 // response to be identified, to check if the next handler should be |
78 // replaced with an appropriate one. | 80 // replaced with an appropriate one. |
79 STARTING, | 81 STARTING, |
80 | 82 |
81 // The InterceptingResourceHandler is starting the process of swapping | 83 // The InterceptingResourceHandler is starting the process of swapping |
82 // handlers. | 84 // handlers. |
83 SWAPPING_HANDLERS, | 85 SWAPPING_HANDLERS, |
84 | 86 |
85 // States where the InterceptingResourceHandler passes the initial | |
86 // OnWillRead call to the old handler, and then waits for the resulting | |
87 // buffer read buffer. | |
88 SENDING_ON_WILL_READ_TO_OLD_HANDLER, | |
89 WAITING_FOR_OLD_HANDLERS_BUFFER, | |
90 | |
91 // The InterceptingResourceHandler is sending the payload given via | 87 // The InterceptingResourceHandler is sending the payload given via |
92 // UseNewHandler to the old handler. The first state starts retrieving a | 88 // UseNewHandler to the old handler. The first state starts retrieving a |
93 // buffer from the old handler, the second state copies as much of the data | 89 // buffer from the old handler, the second state copies as much of the data |
94 // as possible to the received buffer and passes it to the old handler. | 90 // as possible to the received buffer and passes it to the old handler. |
95 SENDING_PAYLOAD_TO_OLD_HANDLER, | 91 SENDING_PAYLOAD_TO_OLD_HANDLER, |
96 RECEIVING_BUFFER_FROM_OLD_HANDLER, | 92 RECEIVING_BUFFER_FROM_OLD_HANDLER, |
97 | 93 |
98 // The InterceptingResourcHandler is calling the new handler's | 94 // The InterceptingResourcHandler is calling the new handler's |
99 // OnResponseStarted method and waiting for its completion via Resume(). | 95 // OnResponseStarted method and waiting for its completion via Resume(). |
100 // After completion, the InterceptingResourceHandler will transition to | 96 // After completion, the InterceptingResourceHandler will transition to |
101 // SENDING_ON_RESPONSE_STARTED_TO_NEW_HANDLER on success. | 97 // PASS_THROUGH on success. |
102 SENDING_ON_WILL_START_TO_NEW_HANDLER, | 98 SENDING_ON_WILL_START_TO_NEW_HANDLER, |
103 | 99 |
104 // The InterceptingResourcHandler is calling the new handler's | |
105 // OnResponseStarted method and waiting for its completion via Resume(). | |
106 // After completion, the InterceptingResourceHandler will transition to | |
107 // WAITING_FOR_ON_READ_COMPLETED on success. | |
108 SENDING_ON_RESPONSE_STARTED_TO_NEW_HANDLER, | |
109 | |
110 // The InterceptingResourcHandler is waiting for OnReadCompleted to be | |
111 // called. | |
112 WAITING_FOR_ON_READ_COMPLETED, | |
113 | |
114 // The two phases of uploading previously received data stored in | |
115 // |first_read_buffer_double_| to the new handler, which is now stored in | |
116 // |next_handler_|. The first state gets a buffer to write to, and the next | |
117 // copies all the data it can to that buffer. | |
118 SENDING_BUFFER_TO_NEW_HANDLER, | |
119 SENDING_BUFFER_TO_NEW_HANDLER_WAITING_FOR_BUFFER, | |
120 | |
121 // The InterceptingResourceHandler has replaced its next ResourceHandler if | 100 // The InterceptingResourceHandler has replaced its next ResourceHandler if |
122 // needed, and has ensured the buffered read data was properly transmitted | 101 // needed, and has ensured the buffered read data was properly transmitted |
123 // to the new ResourceHandler. The InterceptingResourceHandler now acts as | 102 // to the new ResourceHandler. The InterceptingResourceHandler now acts as |
124 // a pass-through ResourceHandler. | 103 // a pass-through ResourceHandler. |
125 PASS_THROUGH, | 104 PASS_THROUGH, |
126 }; | 105 }; |
127 | 106 |
128 // Runs necessary operations depending on |state_|. | 107 // Runs necessary operations depending on |state_|. |
129 void DoLoop(); | 108 void DoLoop(); |
130 | 109 |
131 void ResumeInternal(); | 110 void ResumeInternal(); |
132 | 111 |
133 void SendOnWillReadToOldHandler(); | 112 void SendOnWillReadToOldHandler(); |
134 void OnBufferReceived(); | 113 void OnBufferReceived(); |
135 void SendOnResponseStartedToOldHandler(); | 114 void SendOnResponseStartedToOldHandler(); |
136 void SendPayloadToOldHandler(); | 115 void SendPayloadToOldHandler(); |
137 void ReceivedBufferFromOldHandler(); | 116 void ReceivedBufferFromOldHandler(); |
138 void SendFirstReadBufferToNewHandler(); | |
139 void SendOnResponseStartedToNewHandler(); | 117 void SendOnResponseStartedToNewHandler(); |
140 void ReceivedBufferFromNewHandler(); | 118 void ReceivedBufferFromNewHandler(); |
141 | 119 |
142 State state_ = State::STARTING; | 120 State state_ = State::STARTING; |
143 | 121 |
144 std::unique_ptr<ResourceHandler> new_handler_; | 122 std::unique_ptr<ResourceHandler> new_handler_; |
145 std::string payload_for_old_handler_; | 123 std::string payload_for_old_handler_; |
146 size_t payload_bytes_written_ = 0; | 124 size_t payload_bytes_written_ = 0; |
147 | 125 |
148 // Result of the first read, that may have to be passed to an alternate | 126 // Buffer pointers used for passing a payload to the old handler. |
149 // ResourceHandler instead of the original ResourceHandler. | 127 scoped_refptr<net::IOBuffer> read_buffer_; |
150 scoped_refptr<net::IOBuffer> first_read_buffer_; | 128 int read_buffer_size_ = 0; |
151 // Instead of |first_read_buffer_|, this handler creates a new IOBuffer with | |
152 // the same size and return it to the client. | |
153 scoped_refptr<net::IOBuffer> first_read_buffer_double_; | |
154 int first_read_buffer_size_ = 0; | |
155 int first_read_buffer_bytes_read_ = 0; | |
156 int first_read_buffer_bytes_written_ = 0; | |
157 | |
158 // Information about the new handler's buffer while copying data from | |
159 // |first_read_buffer_double_| to the new handler's buffer. | |
160 // Note that when these are used, the old handler has been destroyed, and | |
161 // |next_handler_| is now the new one. | |
162 scoped_refptr<net::IOBuffer> new_handler_read_buffer_; | |
163 int new_handler_read_buffer_size_ = 0; | |
164 | |
165 // Pointers to parent-owned read buffer and its size. Only used for first | |
166 // OnWillRead call. | |
167 scoped_refptr<net::IOBuffer>* parent_read_buffer_ = nullptr; | |
168 int* parent_read_buffer_size_ = nullptr; | |
169 | 129 |
170 scoped_refptr<ResourceResponse> response_; | 130 scoped_refptr<ResourceResponse> response_; |
171 | 131 |
172 // Next two values are used to handle synchronous Resume calls without a | 132 // Next two values are used to handle synchronous Resume calls without a |
173 // PostTask. | 133 // PostTask. |
174 | 134 |
175 // True if the code is currently within a DoLoop. | 135 // True if the code is currently within a DoLoop. |
176 bool in_do_loop_ = false; | 136 bool in_do_loop_ = false; |
177 // True if the request was resumed while |in_do_loop_| was true; | 137 // True if the request was resumed while |in_do_loop_| was true; |
178 bool advance_to_next_state_ = false; | 138 bool advance_to_next_state_ = false; |
179 | 139 |
180 base::WeakPtrFactory<InterceptingResourceHandler> weak_ptr_factory_; | 140 base::WeakPtrFactory<InterceptingResourceHandler> weak_ptr_factory_; |
181 | 141 |
182 DISALLOW_COPY_AND_ASSIGN(InterceptingResourceHandler); | 142 DISALLOW_COPY_AND_ASSIGN(InterceptingResourceHandler); |
183 }; | 143 }; |
184 | 144 |
185 } // namespace content | 145 } // namespace content |
186 | 146 |
187 #endif // CONTENT_BROWSER_LOADER_INTERCEPTING_RESOURCE_HANDLER_H_ | 147 #endif // CONTENT_BROWSER_LOADER_INTERCEPTING_RESOURCE_HANDLER_H_ |
OLD | NEW |