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