• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/memory/scoped_refptr.h"
16 #include "base/time/time.h"
17 #include "build/buildflag.h"
18 #include "crypto/ec_private_key.h"
19 #include "net/base/completion_once_callback.h"
20 #include "net/base/completion_repeating_callback.h"
21 #include "net/base/net_error_details.h"
22 #include "net/base/net_export.h"
23 #include "net/base/network_anonymization_key.h"
24 #include "net/base/request_priority.h"
25 #include "net/http/http_auth.h"
26 #include "net/http/http_request_headers.h"
27 #include "net/http/http_response_info.h"
28 #include "net/http/http_stream_factory.h"
29 #include "net/http/http_stream_request.h"
30 #include "net/http/http_transaction.h"
31 #include "net/log/net_log_with_source.h"
32 #include "net/net_buildflags.h"
33 #include "net/proxy_resolution/proxy_resolution_service.h"
34 #include "net/socket/connection_attempts.h"
35 #include "net/ssl/ssl_config_service.h"
36 #include "net/websockets/websocket_handshake_stream_base.h"
37 #include "third_party/abseil-cpp/absl/types/optional.h"
38 
39 namespace net {
40 
41 class BidirectionalStreamImpl;
42 class HttpAuthController;
43 class HttpNetworkSession;
44 class HttpStream;
45 class IOBuffer;
46 class ProxyInfo;
47 class SSLPrivateKey;
48 struct HttpRequestInfo;
49 
50 class NET_EXPORT_PRIVATE HttpNetworkTransaction
51     : public HttpTransaction,
52       public HttpStreamRequest::Delegate {
53  public:
54   HttpNetworkTransaction(RequestPriority priority, HttpNetworkSession* session);
55 
56   HttpNetworkTransaction(const HttpNetworkTransaction&) = delete;
57   HttpNetworkTransaction& operator=(const HttpNetworkTransaction&) = delete;
58 
59   ~HttpNetworkTransaction() override;
60 
61   // HttpTransaction methods:
62   int Start(const HttpRequestInfo* request_info,
63             CompletionOnceCallback callback,
64             const NetLogWithSource& net_log) override;
65   int RestartIgnoringLastError(CompletionOnceCallback callback) override;
66   int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert,
67                              scoped_refptr<SSLPrivateKey> client_private_key,
68                              CompletionOnceCallback callback) override;
69   int RestartWithAuth(const AuthCredentials& credentials,
70                       CompletionOnceCallback callback) override;
71   bool IsReadyToRestartForAuth() override;
72 
73   int Read(IOBuffer* buf,
74            int buf_len,
75            CompletionOnceCallback callback) override;
76   void StopCaching() override;
77   int64_t GetTotalReceivedBytes() const override;
78   int64_t GetTotalSentBytes() const override;
79   void DoneReading() override;
80   const HttpResponseInfo* GetResponseInfo() const override;
81   LoadState GetLoadState() const override;
82   void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
83   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
84   bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
85   void PopulateNetErrorDetails(NetErrorDetails* details) const override;
86   void SetPriority(RequestPriority priority) override;
87   void SetWebSocketHandshakeStreamCreateHelper(
88       WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
89   void SetBeforeNetworkStartCallback(
90       BeforeNetworkStartCallback callback) override;
91   void SetConnectedCallback(const ConnectedCallback& callback) override;
92   void SetRequestHeadersCallback(RequestHeadersCallback callback) override;
93   void SetEarlyResponseHeadersCallback(
94       ResponseHeadersCallback callback) override;
95   void SetResponseHeadersCallback(ResponseHeadersCallback callback) override;
96   void SetModifyRequestHeadersCallback(
97       base::RepeatingCallback<void(net::HttpRequestHeaders*)> callback)
98       override;
99   void SetIsSharedDictionaryReadAllowedCallback(
100       base::RepeatingCallback<bool()> callback) override;
101   int ResumeNetworkStart() override;
102   void CloseConnectionOnDestruction() override;
103 
104   // HttpStreamRequest::Delegate methods:
105   void OnStreamReady(const SSLConfig& used_ssl_config,
106                      const ProxyInfo& used_proxy_info,
107                      std::unique_ptr<HttpStream> stream) override;
108   void OnBidirectionalStreamImplReady(
109       const SSLConfig& used_ssl_config,
110       const ProxyInfo& used_proxy_info,
111       std::unique_ptr<BidirectionalStreamImpl> stream) override;
112   void OnWebSocketHandshakeStreamReady(
113       const SSLConfig& used_ssl_config,
114       const ProxyInfo& used_proxy_info,
115       std::unique_ptr<WebSocketHandshakeStreamBase> stream) override;
116   void OnStreamFailed(int status,
117                       const NetErrorDetails& net_error_details,
118                       const SSLConfig& used_ssl_config,
119                       const ProxyInfo& used_proxy_info,
120                       ResolveErrorInfo resolve_error_info) override;
121   void OnCertificateError(int status,
122                           const SSLConfig& used_ssl_config,
123                           const SSLInfo& ssl_info) override;
124   void OnNeedsProxyAuth(const HttpResponseInfo& response_info,
125                         const SSLConfig& used_ssl_config,
126                         const ProxyInfo& used_proxy_info,
127                         HttpAuthController* auth_controller) override;
128   void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
129                          SSLCertRequestInfo* cert_info) override;
130 
131   void OnQuicBroken() override;
132   ConnectionAttempts GetConnectionAttempts() const override;
133 
134  private:
135   FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, ResetStateForRestart);
136   FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
137                            CreateWebSocketHandshakeStream);
138   FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
139                            SetProxyInfoInResponse_Direct);
140   FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
141                            SetProxyInfoInResponse_Proxied);
142   FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
143                            SetProxyInfoInResponse_Empty);
144   FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
145                            SetProxyInfoInResponse_IpProtection);
146   FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateReceived);
147   FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateSent);
148   FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateOverflow);
149   FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, FlowControlStallResume);
150   FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
151                            FlowControlStallResumeAfterSettings);
152   FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
153                            FlowControlNegativeSendWindowSize);
154 
155   enum State {
156     STATE_NOTIFY_BEFORE_CREATE_STREAM,
157     STATE_CREATE_STREAM,
158     STATE_CREATE_STREAM_COMPLETE,
159     STATE_INIT_STREAM,
160     STATE_INIT_STREAM_COMPLETE,
161     STATE_CONNECTED_CALLBACK,
162     STATE_CONNECTED_CALLBACK_COMPLETE,
163     STATE_GENERATE_PROXY_AUTH_TOKEN,
164     STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
165     STATE_GENERATE_SERVER_AUTH_TOKEN,
166     STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE,
167     STATE_INIT_REQUEST_BODY,
168     STATE_INIT_REQUEST_BODY_COMPLETE,
169     STATE_BUILD_REQUEST,
170     STATE_BUILD_REQUEST_COMPLETE,
171     STATE_SEND_REQUEST,
172     STATE_SEND_REQUEST_COMPLETE,
173     STATE_READ_HEADERS,
174     STATE_READ_HEADERS_COMPLETE,
175     STATE_READ_BODY,
176     STATE_READ_BODY_COMPLETE,
177     STATE_DRAIN_BODY_FOR_AUTH_RESTART,
178     STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE,
179     STATE_NONE
180   };
181 
182   bool IsSecureRequest() const;
183 
184   // Returns true if the request is using an HTTP(S) proxy without being
185   // tunneled via the CONNECT method.
186   bool UsingHttpProxyWithoutTunnel() const;
187 
188   void DoCallback(int result);
189   void OnIOComplete(int result);
190 
191   // Runs the state transition loop.
192   int DoLoop(int result);
193 
194   // Each of these methods corresponds to a State value.  Those with an input
195   // argument receive the result from the previous state.  If a method returns
196   // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
197   // next state method as the result arg.
198   int DoNotifyBeforeCreateStream();
199   int DoCreateStream();
200   int DoCreateStreamComplete(int result);
201   int DoInitStream();
202   int DoInitStreamComplete(int result);
203   int DoConnectedCallback();
204   int DoConnectedCallbackComplete(int result);
205   int DoGenerateProxyAuthToken();
206   int DoGenerateProxyAuthTokenComplete(int result);
207   int DoGenerateServerAuthToken();
208   int DoGenerateServerAuthTokenComplete(int result);
209   int DoInitRequestBody();
210   int DoInitRequestBodyComplete(int result);
211   int DoBuildRequest();
212   int DoBuildRequestComplete(int result);
213   int DoSendRequest();
214   int DoSendRequestComplete(int result);
215   int DoReadHeaders();
216   int DoReadHeadersComplete(int result);
217   int DoReadBody();
218   int DoReadBodyComplete(int result);
219   int DoDrainBodyForAuthRestart();
220   int DoDrainBodyForAuthRestartComplete(int result);
221 
222   int BuildRequestHeaders(bool using_http_proxy_without_tunnel);
223 
224 #if BUILDFLAG(ENABLE_REPORTING)
225   // Processes the Report-To header, if one exists. This header configures where
226   // the Reporting API (in //net/reporting) will send reports for the origin.
227   void ProcessReportToHeader();
228 
229   // Processes the NEL header, if one exists. This header configures whether
230   // network errors will be reported to a specified group of endpoints using the
231   // Reporting API.
232   void ProcessNetworkErrorLoggingHeader();
233 
234   // Calls GenerateNetworkErrorLoggingReport() if |rv| represents a NET_ERROR
235   // other than ERR_IO_PENDING.
236   void GenerateNetworkErrorLoggingReportIfError(int rv);
237 
238   // Generates a NEL report about this request.  The NetworkErrorLoggingService
239   // will discard the report if there is no NEL policy registered for this
240   // origin.
241   void GenerateNetworkErrorLoggingReport(int rv);
242 #endif
243 
244   // Writes a log message to help debugging in the field when we block a proxy
245   // response to a CONNECT request.
246   void LogBlockedTunnelResponse(int response_code) const;
247 
248   // Called wherever ERR_HTTP_1_1_REQUIRED or
249   // ERR_PROXY_HTTP_1_1_REQUIRED has to be handled.
250   int HandleHttp11Required(int error);
251 
252   // Called to possibly handle a client authentication error. Sets next_state_
253   // and returns OK if recovering from the error.  Otherwise, the same error
254   // code is returned.
255   int HandleSSLClientAuthError(int error);
256 
257   // Called to possibly recover from the given error.  Sets next_state_ and
258   // returns OK if recovering from the error.  Otherwise, the same error code
259   // is returned.
260   int HandleIOError(int error);
261 
262   // Gets the response headers from the HttpStream.
263   HttpResponseHeaders* GetResponseHeaders() const;
264 
265   // Called when the socket is unexpectedly closed.  Returns true if the request
266   // should be resent in case of a socket reuse/close race.
267   bool ShouldResendRequest() const;
268 
269   // Returns true if there have already been |kMaxRetryAttempts| retries for
270   // HTTP2 or QUIC network errors, and no further retries should be attempted.
271   bool HasExceededMaxRetries() const;
272 
273   // Increments the number of restarts and returns true if the restart may
274   // proceed.
275   bool CheckMaxRestarts();
276 
277   // These values are persisted to logs. Entries should not be renumbered and
278   // numeric values should never be reused.
279   enum class RetryReason {
280     kHttpRequestTimeout = 0,
281     kHttpMisdirectedRequest = 1,
282     kHttp11Required = 2,
283     kSslClientAuthSignatureFailed = 3,
284     kConnectionReset = 4,
285     kConnectionClosed = 5,
286     kConnectionAborted = 6,
287     kSocketNotConnected = 7,
288     kEmptyResponse = 8,
289     kEarlyDataRejected = 9,
290     kWrongVersionOnEarlyData = 10,
291     kHttp2PingFailed = 11,
292     kHttp2ServerRefusedStream = 12,
293     // Entries 13, 14, 15 are removed.
294     kQuicHandshakeFailed = 16,
295     kQuicGoawayRequestCanBeRetried = 17,
296     kQuicProtocolError = 18,
297     kMaxValue = kQuicProtocolError,
298   };
299   static absl::optional<RetryReason> GetRetryReasonForIOError(int error);
300 
301   // Resets the connection and the request headers for resend.  Called when
302   // ShouldResendRequest() is true.
303   void ResetConnectionAndRequestForResend(RetryReason retry_reason);
304 
305   // Sets up the state machine to restart the transaction with auth.
306   void PrepareForAuthRestart(HttpAuth::Target target);
307 
308   // Called when we don't need to drain the response body or have drained it.
309   // Resets |connection_| unless |keep_alive| is true, then calls
310   // ResetStateForRestart.  Sets |next_state_| appropriately.
311   void DidDrainBodyForAuthRestart(bool keep_alive);
312 
313   // Resets the members of the transaction so it can be restarted.
314   void ResetStateForRestart();
315 
316   // Resets the members of the transaction, except |stream_|, which needs
317   // to be maintained for multi-round auth.
318   void ResetStateForAuthRestart();
319 
320   // Caches network error details from the stream if available
321   // and resets the stream.
322   void CacheNetErrorDetailsAndResetStream();
323 
324   // Returns true if we should try to add a Proxy-Authorization header
325   bool ShouldApplyProxyAuth() const;
326 
327   // Returns true if we should try to add an Authorization header.
328   bool ShouldApplyServerAuth() const;
329 
330   // Handles HTTP status code 401 or 407.
331   // HandleAuthChallenge() returns a network error code, or OK on success.
332   // May update |pending_auth_target_| or |response_.auth_challenge|.
333   int HandleAuthChallenge();
334 
335   // Returns true if we have auth credentials for the given target.
336   bool HaveAuth(HttpAuth::Target target) const;
337 
338   // Get the {scheme, host, path, port} for the authentication target
339   GURL AuthURL(HttpAuth::Target target) const;
340 
341   // Returns true if this transaction is for a WebSocket handshake
342   bool ForWebSocketHandshake() const;
343 
344   void CopyConnectionAttemptsFromStreamRequest();
345 
346   // Returns true if response "Content-Encoding" headers respect
347   // "Accept-Encoding".
348   bool ContentEncodingsValid() const;
349 
350   void ResumeAfterConnected(int result);
351 
352   // These values are persisted to logs. Entries should not be renumbered and
353   // numeric values should never be reused.
354   enum class QuicProtocolErrorRetryStatus {
355     kNoRetryExceededMaxRetries = 0,
356     kNoRetryHeaderReceived = 1,
357     kNoRetryNoAlternativeService = 2,
358     kRetryAltServiceBroken = 3,
359     kRetryAltServiceNotBroken = 4,
360     kMaxValue = kRetryAltServiceNotBroken,
361   };
362 
363   void RecordQuicProtocolErrorMetrics(
364       QuicProtocolErrorRetryStatus retry_status);
365 
366   void RecordMetricsIfError(int rv);
367   void RecordMetrics(int rv);
368 
369   static void SetProxyInfoInResponse(const ProxyInfo& proxy_info,
370                                      HttpResponseInfo* response_info);
371 
372   scoped_refptr<HttpAuthController>
373       auth_controllers_[HttpAuth::AUTH_NUM_TARGETS];
374 
375   // Whether this transaction is waiting for proxy auth, server auth, or is
376   // not waiting for any auth at all. |pending_auth_target_| is read and
377   // cleared by RestartWithAuth().
378   HttpAuth::Target pending_auth_target_ = HttpAuth::AUTH_NONE;
379 
380   CompletionRepeatingCallback io_callback_;
381   CompletionOnceCallback callback_;
382 
383   raw_ptr<HttpNetworkSession> session_;
384 
385   NetLogWithSource net_log_;
386 
387   // Reset to null at the start of the Read state machine.
388   raw_ptr<const HttpRequestInfo> request_ = nullptr;
389 
390   // The requested URL.
391   GURL url_;
392   RequestPriority priority_;
393   HttpResponseInfo response_;
394 
395   // Copied from |request_|, as it's needed after the response body has been
396   // read.
397   NetworkAnonymizationKey network_anonymization_key_;
398 
399   // |proxy_info_| is the ProxyInfo used by the HttpStreamRequest.
400   ProxyInfo proxy_info_;
401 
402   std::unique_ptr<HttpStreamRequest> stream_request_;
403   std::unique_ptr<HttpStream> stream_;
404 
405   // True if we've validated the headers that the stream parser has returned.
406   bool headers_valid_ = false;
407 
408   // True if we can send the request over early data.
409   bool can_send_early_data_ = false;
410 
411   // True if the client certificate for the server (rather than the proxy) was
412   // configured in this transaction.
413   bool configured_client_cert_for_server_ = false;
414 
415   // SSL configuration used for the server and proxies, respectively. Note
416   // |server_ssl_config_| may be updated from the HttpStreamFactory, which will
417   // be applied on retry.
418   //
419   // TODO(davidben): Mutating it is weird and relies on HttpStreamFactory
420   // modifications being idempotent. Address this as part of other work to make
421   // sense of SSLConfig (related to https://crbug.com/488043).
422   SSLConfig server_ssl_config_;
423 
424   HttpRequestHeaders request_headers_;
425 #if BUILDFLAG(ENABLE_REPORTING)
426   // Whether a NEL report has already been generated. Reset when restarting.
427   bool network_error_logging_report_generated_ = false;
428   // Cache some fields from |request_| that we'll need to construct a NEL
429   // report about the request.  (NEL report construction happens after we've
430   // cleared the |request_| pointer.)
431   std::string request_method_;
432   std::string request_referrer_;
433   std::string request_user_agent_;
434   int request_reporting_upload_depth_ = 0;
435 #endif
436   base::TimeTicks start_timeticks_;
437 
438   // The size in bytes of the buffer we use to drain the response body that
439   // we want to throw away.  The response body is typically a small error
440   // page just a few hundred bytes long.
441   static const int kDrainBodyBufferSize = 1024;
442 
443   // User buffer and length passed to the Read method.
444   scoped_refptr<IOBuffer> read_buf_;
445   int read_buf_len_ = 0;
446 
447   // Total number of bytes received on all destroyed HttpStreams for this
448   // transaction.
449   int64_t total_received_bytes_ = 0;
450 
451   // Total number of bytes sent on all destroyed HttpStreams for this
452   // transaction.
453   int64_t total_sent_bytes_ = 0;
454 
455   // When the transaction started / finished sending the request, including
456   // the body, if present. |send_start_time_| is set to |base::TimeTicks()|
457   // until |SendRequest()| is called on |stream_|, and reset for auth restarts.
458   base::TimeTicks send_start_time_;
459   base::TimeTicks send_end_time_;
460 
461   // The next state in the state machine.
462   State next_state_ = STATE_NONE;
463 
464   // True when the tunnel is in the process of being established - we can't
465   // read from the socket until the tunnel is done.
466   bool establishing_tunnel_ = false;
467 
468   // Enable pooling to a SpdySession with matching IP and certificate
469   // even if the SpdySessionKey is different.
470   bool enable_ip_based_pooling_ = true;
471 
472   // Enable using alternative services for the request.
473   bool enable_alternative_services_ = true;
474 
475   // When a request is retried because of errors with the alternative service,
476   // this will store the alternative service used.
477   AlternativeService retried_alternative_service_;
478 
479   // The helper object to use to create WebSocketHandshakeStreamBase
480   // objects. Only relevant when establishing a WebSocket connection.
481   raw_ptr<WebSocketHandshakeStreamBase::CreateHelper>
482       websocket_handshake_stream_base_create_helper_ = nullptr;
483 
484   BeforeNetworkStartCallback before_network_start_callback_;
485   ConnectedCallback connected_callback_;
486   RequestHeadersCallback request_headers_callback_;
487   ResponseHeadersCallback early_response_headers_callback_;
488   ResponseHeadersCallback response_headers_callback_;
489 
490   // The callback to modify the request header. They will be called just before
491   // sending the request to the network.
492   base::RepeatingCallback<void(net::HttpRequestHeaders*)>
493       modify_headers_callbacks_;
494 
495   ConnectionAttempts connection_attempts_;
496   IPEndPoint remote_endpoint_;
497   // Network error details for this transaction.
498   NetErrorDetails net_error_details_;
499 
500   // Number of retries made for network errors like ERR_HTTP2_PING_FAILED,
501   // ERR_HTTP2_SERVER_REFUSED_STREAM, ERR_QUIC_HANDSHAKE_FAILED and
502   // ERR_QUIC_PROTOCOL_ERROR. Currently we stop after 3 tries
503   // (including the initial request) and fail the request.
504   // This count excludes retries on reused sockets since a well
505   // behaved server may time those out and thus the number
506   // of times we can retry a request on reused sockets is limited.
507   size_t retry_attempts_ = 0;
508 
509   // Number of times the transaction was restarted via a RestartWith* call.
510   size_t num_restarts_ = 0;
511 
512   bool close_connection_on_destruction_ = false;
513 
514   // Set to true when the server required HTTP/1.1 fallback.
515   bool http_1_1_was_required_ = false;
516 
517   absl::optional<base::TimeDelta> quic_protocol_error_retry_delay_;
518 };
519 
520 }  // namespace net
521 
522 #endif  // NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
523