OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef NET_HTTP_HTTP_NETWORK_TRANSACTION_H_ | |
6 #define NET_HTTP_HTTP_NETWORK_TRANSACTION_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/gtest_prod_util.h" | |
12 #include "base/memory/ref_counted.h" | |
13 #include "base/memory/scoped_ptr.h" | |
14 #include "base/time/time.h" | |
15 #include "net/base/net_log.h" | |
16 #include "net/base/request_priority.h" | |
17 #include "net/http/http_auth.h" | |
18 #include "net/http/http_request_headers.h" | |
19 #include "net/http/http_response_info.h" | |
20 #include "net/http/http_stream_factory.h" | |
21 #include "net/http/http_transaction.h" | |
22 #include "net/proxy/proxy_service.h" | |
23 #include "net/ssl/ssl_config_service.h" | |
24 #include "net/websockets/websocket_handshake_stream_base.h" | |
25 | |
26 namespace net { | |
27 | |
28 class ClientSocketHandle; | |
29 class HttpAuthController; | |
30 class HttpNetworkSession; | |
31 class HttpStream; | |
32 class HttpStreamRequest; | |
33 class IOBuffer; | |
34 class ProxyInfo; | |
35 class SpdySession; | |
36 struct HttpRequestInfo; | |
37 | |
38 class NET_EXPORT_PRIVATE HttpNetworkTransaction | |
39 : public HttpTransaction, | |
40 public HttpStreamRequest::Delegate { | |
41 public: | |
42 HttpNetworkTransaction(RequestPriority priority, | |
43 HttpNetworkSession* session); | |
44 | |
45 ~HttpNetworkTransaction() override; | |
46 | |
47 // HttpTransaction methods: | |
48 int Start(const HttpRequestInfo* request_info, | |
49 const CompletionCallback& callback, | |
50 const BoundNetLog& net_log) override; | |
51 int RestartIgnoringLastError(const CompletionCallback& callback) override; | |
52 int RestartWithCertificate(X509Certificate* client_cert, | |
53 const CompletionCallback& callback) override; | |
54 int RestartWithAuth(const AuthCredentials& credentials, | |
55 const CompletionCallback& callback) override; | |
56 bool IsReadyToRestartForAuth() override; | |
57 | |
58 int Read(IOBuffer* buf, | |
59 int buf_len, | |
60 const CompletionCallback& callback) override; | |
61 void StopCaching() override; | |
62 bool GetFullRequestHeaders(HttpRequestHeaders* headers) const override; | |
63 int64 GetTotalReceivedBytes() const override; | |
64 void DoneReading() override; | |
65 const HttpResponseInfo* GetResponseInfo() const override; | |
66 LoadState GetLoadState() const override; | |
67 UploadProgress GetUploadProgress() const override; | |
68 void SetQuicServerInfo(QuicServerInfo* quic_server_info) override; | |
69 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; | |
70 void SetPriority(RequestPriority priority) override; | |
71 void SetWebSocketHandshakeStreamCreateHelper( | |
72 WebSocketHandshakeStreamBase::CreateHelper* create_helper) override; | |
73 void SetBeforeNetworkStartCallback( | |
74 const BeforeNetworkStartCallback& callback) override; | |
75 void SetBeforeProxyHeadersSentCallback( | |
76 const BeforeProxyHeadersSentCallback& callback) override; | |
77 int ResumeNetworkStart() override; | |
78 | |
79 // HttpStreamRequest::Delegate methods: | |
80 void OnStreamReady(const SSLConfig& used_ssl_config, | |
81 const ProxyInfo& used_proxy_info, | |
82 HttpStream* stream) override; | |
83 void OnWebSocketHandshakeStreamReady( | |
84 const SSLConfig& used_ssl_config, | |
85 const ProxyInfo& used_proxy_info, | |
86 WebSocketHandshakeStreamBase* stream) override; | |
87 void OnStreamFailed(int status, const SSLConfig& used_ssl_config) override; | |
88 void OnCertificateError(int status, | |
89 const SSLConfig& used_ssl_config, | |
90 const SSLInfo& ssl_info) override; | |
91 void OnNeedsProxyAuth(const HttpResponseInfo& response_info, | |
92 const SSLConfig& used_ssl_config, | |
93 const ProxyInfo& used_proxy_info, | |
94 HttpAuthController* auth_controller) override; | |
95 void OnNeedsClientAuth(const SSLConfig& used_ssl_config, | |
96 SSLCertRequestInfo* cert_info) override; | |
97 void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, | |
98 const SSLConfig& used_ssl_config, | |
99 const ProxyInfo& used_proxy_info, | |
100 HttpStream* stream) override; | |
101 | |
102 private: | |
103 friend class HttpNetworkTransactionSSLTest; | |
104 | |
105 FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, | |
106 ResetStateForRestart); | |
107 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, | |
108 WindowUpdateReceived); | |
109 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, | |
110 WindowUpdateSent); | |
111 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, | |
112 WindowUpdateOverflow); | |
113 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, | |
114 FlowControlStallResume); | |
115 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, | |
116 FlowControlStallResumeAfterSettings); | |
117 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, | |
118 FlowControlNegativeSendWindowSize); | |
119 | |
120 enum State { | |
121 STATE_NOTIFY_BEFORE_CREATE_STREAM, | |
122 STATE_CREATE_STREAM, | |
123 STATE_CREATE_STREAM_COMPLETE, | |
124 STATE_INIT_STREAM, | |
125 STATE_INIT_STREAM_COMPLETE, | |
126 STATE_GENERATE_PROXY_AUTH_TOKEN, | |
127 STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE, | |
128 STATE_GENERATE_SERVER_AUTH_TOKEN, | |
129 STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE, | |
130 STATE_INIT_REQUEST_BODY, | |
131 STATE_INIT_REQUEST_BODY_COMPLETE, | |
132 STATE_BUILD_REQUEST, | |
133 STATE_BUILD_REQUEST_COMPLETE, | |
134 STATE_SEND_REQUEST, | |
135 STATE_SEND_REQUEST_COMPLETE, | |
136 STATE_READ_HEADERS, | |
137 STATE_READ_HEADERS_COMPLETE, | |
138 STATE_READ_BODY, | |
139 STATE_READ_BODY_COMPLETE, | |
140 STATE_DRAIN_BODY_FOR_AUTH_RESTART, | |
141 STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE, | |
142 STATE_NONE | |
143 }; | |
144 | |
145 bool is_https_request() const; | |
146 | |
147 // Returns true if the request is using an HTTP(S) proxy without being | |
148 // tunneled via the CONNECT method. | |
149 bool UsingHttpProxyWithoutTunnel() const; | |
150 | |
151 void DoCallback(int result); | |
152 void OnIOComplete(int result); | |
153 | |
154 // Runs the state transition loop. | |
155 int DoLoop(int result); | |
156 | |
157 // Each of these methods corresponds to a State value. Those with an input | |
158 // argument receive the result from the previous state. If a method returns | |
159 // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the | |
160 // next state method as the result arg. | |
161 int DoNotifyBeforeCreateStream(); | |
162 int DoCreateStream(); | |
163 int DoCreateStreamComplete(int result); | |
164 int DoInitStream(); | |
165 int DoInitStreamComplete(int result); | |
166 int DoGenerateProxyAuthToken(); | |
167 int DoGenerateProxyAuthTokenComplete(int result); | |
168 int DoGenerateServerAuthToken(); | |
169 int DoGenerateServerAuthTokenComplete(int result); | |
170 int DoInitRequestBody(); | |
171 int DoInitRequestBodyComplete(int result); | |
172 int DoBuildRequest(); | |
173 int DoBuildRequestComplete(int result); | |
174 int DoSendRequest(); | |
175 int DoSendRequestComplete(int result); | |
176 int DoReadHeaders(); | |
177 int DoReadHeadersComplete(int result); | |
178 int DoReadBody(); | |
179 int DoReadBodyComplete(int result); | |
180 int DoDrainBodyForAuthRestart(); | |
181 int DoDrainBodyForAuthRestartComplete(int result); | |
182 | |
183 void BuildRequestHeaders(bool using_http_proxy_without_tunnel); | |
184 | |
185 // Writes a log message to help debugging in the field when we block a proxy | |
186 // response to a CONNECT request. | |
187 void LogBlockedTunnelResponse(int response_code) const; | |
188 | |
189 // Called to handle a client certificate request. | |
190 int HandleCertificateRequest(int error); | |
191 | |
192 // Called wherever ERR_HTTP_1_1_REQUIRED or | |
193 // ERR_PROXY_HTTP_1_1_REQUIRED has to be handled. | |
194 int HandleHttp11Required(int error); | |
195 | |
196 // Called to possibly handle a client authentication error. | |
197 void HandleClientAuthError(int error); | |
198 | |
199 // Called to possibly recover from an SSL handshake error. Sets next_state_ | |
200 // and returns OK if recovering from the error. Otherwise, the same error | |
201 // code is returned. | |
202 int HandleSSLHandshakeError(int error); | |
203 | |
204 // Called to possibly recover from the given error. Sets next_state_ and | |
205 // returns OK if recovering from the error. Otherwise, the same error code | |
206 // is returned. | |
207 int HandleIOError(int error); | |
208 | |
209 // Gets the response headers from the HttpStream. | |
210 HttpResponseHeaders* GetResponseHeaders() const; | |
211 | |
212 // Called when the socket is unexpectedly closed. Returns true if the request | |
213 // should be resent in case of a socket reuse/close race. | |
214 bool ShouldResendRequest() const; | |
215 | |
216 // Resets the connection and the request headers for resend. Called when | |
217 // ShouldResendRequest() is true. | |
218 void ResetConnectionAndRequestForResend(); | |
219 | |
220 // Sets up the state machine to restart the transaction with auth. | |
221 void PrepareForAuthRestart(HttpAuth::Target target); | |
222 | |
223 // Called when we don't need to drain the response body or have drained it. | |
224 // Resets |connection_| unless |keep_alive| is true, then calls | |
225 // ResetStateForRestart. Sets |next_state_| appropriately. | |
226 void DidDrainBodyForAuthRestart(bool keep_alive); | |
227 | |
228 // Resets the members of the transaction so it can be restarted. | |
229 void ResetStateForRestart(); | |
230 | |
231 // Resets the members of the transaction, except |stream_|, which needs | |
232 // to be maintained for multi-round auth. | |
233 void ResetStateForAuthRestart(); | |
234 | |
235 // Returns true if we should try to add a Proxy-Authorization header | |
236 bool ShouldApplyProxyAuth() const; | |
237 | |
238 // Returns true if we should try to add an Authorization header. | |
239 bool ShouldApplyServerAuth() const; | |
240 | |
241 // Handles HTTP status code 401 or 407. | |
242 // HandleAuthChallenge() returns a network error code, or OK on success. | |
243 // May update |pending_auth_target_| or |response_.auth_challenge|. | |
244 int HandleAuthChallenge(); | |
245 | |
246 // Returns true if we have auth credentials for the given target. | |
247 bool HaveAuth(HttpAuth::Target target) const; | |
248 | |
249 // Get the {scheme, host, path, port} for the authentication target | |
250 GURL AuthURL(HttpAuth::Target target) const; | |
251 | |
252 // Returns true if this transaction is for a WebSocket handshake | |
253 bool ForWebSocketHandshake() const; | |
254 | |
255 // Debug helper. | |
256 static std::string DescribeState(State state); | |
257 | |
258 void SetStream(HttpStream* stream); | |
259 | |
260 scoped_refptr<HttpAuthController> | |
261 auth_controllers_[HttpAuth::AUTH_NUM_TARGETS]; | |
262 | |
263 // Whether this transaction is waiting for proxy auth, server auth, or is | |
264 // not waiting for any auth at all. |pending_auth_target_| is read and | |
265 // cleared by RestartWithAuth(). | |
266 HttpAuth::Target pending_auth_target_; | |
267 | |
268 CompletionCallback io_callback_; | |
269 CompletionCallback callback_; | |
270 | |
271 HttpNetworkSession* session_; | |
272 | |
273 BoundNetLog net_log_; | |
274 const HttpRequestInfo* request_; | |
275 RequestPriority priority_; | |
276 HttpResponseInfo response_; | |
277 | |
278 // |proxy_info_| is the ProxyInfo used by the HttpStreamRequest. | |
279 ProxyInfo proxy_info_; | |
280 | |
281 scoped_ptr<HttpStreamRequest> stream_request_; | |
282 scoped_ptr<HttpStream> stream_; | |
283 | |
284 // True if we've validated the headers that the stream parser has returned. | |
285 bool headers_valid_; | |
286 | |
287 SSLConfig server_ssl_config_; | |
288 SSLConfig proxy_ssl_config_; | |
289 // fallback_error_code contains the error code that caused the last TLS | |
290 // fallback. If the fallback connection results in | |
291 // ERR_SSL_INAPPROPRIATE_FALLBACK (i.e. the server indicated that the | |
292 // fallback should not have been needed) then we use this value to return the | |
293 // original error that triggered the fallback. | |
294 int fallback_error_code_; | |
295 | |
296 HttpRequestHeaders request_headers_; | |
297 | |
298 // The size in bytes of the buffer we use to drain the response body that | |
299 // we want to throw away. The response body is typically a small error | |
300 // page just a few hundred bytes long. | |
301 static const int kDrainBodyBufferSize = 1024; | |
302 | |
303 // User buffer and length passed to the Read method. | |
304 scoped_refptr<IOBuffer> read_buf_; | |
305 int read_buf_len_; | |
306 | |
307 // Total number of bytes received on streams for this transaction. | |
308 int64 total_received_bytes_; | |
309 | |
310 // When the transaction started / finished sending the request, including | |
311 // the body, if present. | |
312 base::TimeTicks send_start_time_; | |
313 base::TimeTicks send_end_time_; | |
314 | |
315 // The next state in the state machine. | |
316 State next_state_; | |
317 | |
318 // True when the tunnel is in the process of being established - we can't | |
319 // read from the socket until the tunnel is done. | |
320 bool establishing_tunnel_; | |
321 | |
322 // The helper object to use to create WebSocketHandshakeStreamBase | |
323 // objects. Only relevant when establishing a WebSocket connection. | |
324 WebSocketHandshakeStreamBase::CreateHelper* | |
325 websocket_handshake_stream_base_create_helper_; | |
326 | |
327 BeforeNetworkStartCallback before_network_start_callback_; | |
328 BeforeProxyHeadersSentCallback before_proxy_headers_sent_callback_; | |
329 | |
330 DISALLOW_COPY_AND_ASSIGN(HttpNetworkTransaction); | |
331 }; | |
332 | |
333 } // namespace net | |
334 | |
335 #endif // NET_HTTP_HTTP_NETWORK_TRANSACTION_H_ | |
OLD | NEW |