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