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/websockets/websocket_handshake_stream_base.h" 39 40 namespace net { 41 42 class BidirectionalStreamImpl; 43 class HttpAuthController; 44 class HttpNetworkSession; 45 class HttpStream; 46 class IOBuffer; 47 class ProxyInfo; 48 class SSLPrivateKey; 49 struct HttpRequestInfo; 50 51 class NET_EXPORT_PRIVATE HttpNetworkTransaction 52 : public HttpTransaction, 53 public HttpStreamRequest::Delegate { 54 public: 55 HttpNetworkTransaction(RequestPriority priority, HttpNetworkSession* session); 56 57 HttpNetworkTransaction(const HttpNetworkTransaction&) = delete; 58 HttpNetworkTransaction& operator=(const HttpNetworkTransaction&) = delete; 59 60 ~HttpNetworkTransaction() override; 61 62 // HttpTransaction methods: 63 int Start(const HttpRequestInfo* request_info, 64 CompletionOnceCallback callback, 65 const NetLogWithSource& net_log) override; 66 int RestartIgnoringLastError(CompletionOnceCallback callback) override; 67 int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert, 68 scoped_refptr<SSLPrivateKey> client_private_key, 69 CompletionOnceCallback callback) override; 70 int RestartWithAuth(const AuthCredentials& credentials, 71 CompletionOnceCallback callback) override; 72 bool IsReadyToRestartForAuth() override; 73 74 int Read(IOBuffer* buf, 75 int buf_len, 76 CompletionOnceCallback callback) override; 77 void StopCaching() override; 78 int64_t GetTotalReceivedBytes() const override; 79 int64_t GetTotalSentBytes() const override; 80 void DoneReading() override; 81 const HttpResponseInfo* GetResponseInfo() const override; 82 LoadState GetLoadState() const override; 83 void SetQuicServerInfo(QuicServerInfo* quic_server_info) override; 84 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; 85 bool GetRemoteEndpoint(IPEndPoint* endpoint) const override; 86 void PopulateNetErrorDetails(NetErrorDetails* details) const override; 87 void SetPriority(RequestPriority priority) override; 88 void SetWebSocketHandshakeStreamCreateHelper( 89 WebSocketHandshakeStreamBase::CreateHelper* create_helper) override; 90 void SetBeforeNetworkStartCallback( 91 BeforeNetworkStartCallback callback) override; 92 void SetConnectedCallback(const ConnectedCallback& callback) override; 93 void SetRequestHeadersCallback(RequestHeadersCallback callback) override; 94 void SetEarlyResponseHeadersCallback( 95 ResponseHeadersCallback callback) override; 96 void SetResponseHeadersCallback(ResponseHeadersCallback callback) override; 97 void SetModifyRequestHeadersCallback( 98 base::RepeatingCallback<void(net::HttpRequestHeaders*)> callback) 99 override; 100 void SetIsSharedDictionaryReadAllowedCallback( 101 base::RepeatingCallback<bool()> callback) override; 102 int ResumeNetworkStart() override; 103 void CloseConnectionOnDestruction() override; 104 bool IsMdlMatchForMetrics() const override; 105 106 // HttpStreamRequest::Delegate methods: 107 void OnStreamReady(const ProxyInfo& used_proxy_info, 108 std::unique_ptr<HttpStream> stream) override; 109 void OnBidirectionalStreamImplReady( 110 const ProxyInfo& used_proxy_info, 111 std::unique_ptr<BidirectionalStreamImpl> stream) override; 112 void OnWebSocketHandshakeStreamReady( 113 const ProxyInfo& used_proxy_info, 114 std::unique_ptr<WebSocketHandshakeStreamBase> stream) override; 115 void OnStreamFailed(int status, 116 const NetErrorDetails& net_error_details, 117 const ProxyInfo& used_proxy_info, 118 ResolveErrorInfo resolve_error_info) override; 119 void OnCertificateError(int status, 120 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 ConnectionAttempts GetConnectionAttempts() const override; 128 129 private: 130 FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, ResetStateForRestart); 131 FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, 132 CreateWebSocketHandshakeStream); 133 FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, 134 SetProxyInfoInResponse_Direct); 135 FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, 136 SetProxyInfoInResponse_Proxied); 137 FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, 138 SetProxyInfoInResponse_Empty); 139 FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, 140 SetProxyInfoInResponse_IpProtection); 141 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateReceived); 142 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateSent); 143 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateOverflow); 144 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, FlowControlStallResume); 145 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, 146 FlowControlStallResumeAfterSettings); 147 FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, 148 FlowControlNegativeSendWindowSize); 149 150 enum State { 151 STATE_NOTIFY_BEFORE_CREATE_STREAM, 152 STATE_CREATE_STREAM, 153 STATE_CREATE_STREAM_COMPLETE, 154 STATE_INIT_STREAM, 155 STATE_INIT_STREAM_COMPLETE, 156 STATE_CONNECTED_CALLBACK, 157 STATE_CONNECTED_CALLBACK_COMPLETE, 158 STATE_GENERATE_PROXY_AUTH_TOKEN, 159 STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE, 160 STATE_GENERATE_SERVER_AUTH_TOKEN, 161 STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE, 162 STATE_INIT_REQUEST_BODY, 163 STATE_INIT_REQUEST_BODY_COMPLETE, 164 STATE_BUILD_REQUEST, 165 STATE_BUILD_REQUEST_COMPLETE, 166 STATE_SEND_REQUEST, 167 STATE_SEND_REQUEST_COMPLETE, 168 STATE_READ_HEADERS, 169 STATE_READ_HEADERS_COMPLETE, 170 STATE_READ_BODY, 171 STATE_READ_BODY_COMPLETE, 172 STATE_DRAIN_BODY_FOR_AUTH_RESTART, 173 STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE, 174 STATE_NONE 175 }; 176 177 bool IsSecureRequest() const; 178 179 // Returns true if the request is using an HTTP(S) proxy without being 180 // tunneled via the CONNECT method. 181 bool UsingHttpProxyWithoutTunnel() const; 182 183 void DoCallback(int result); 184 void OnIOComplete(int result); 185 186 // Runs the state transition loop. 187 int DoLoop(int result); 188 189 // Each of these methods corresponds to a State value. Those with an input 190 // argument receive the result from the previous state. If a method returns 191 // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the 192 // next state method as the result arg. 193 int DoNotifyBeforeCreateStream(); 194 int DoCreateStream(); 195 int DoCreateStreamComplete(int result); 196 int DoInitStream(); 197 int DoInitStreamComplete(int result); 198 int DoConnectedCallback(); 199 int DoConnectedCallbackComplete(int result); 200 int DoGenerateProxyAuthToken(); 201 int DoGenerateProxyAuthTokenComplete(int result); 202 int DoGenerateServerAuthToken(); 203 int DoGenerateServerAuthTokenComplete(int result); 204 int DoInitRequestBody(); 205 int DoInitRequestBodyComplete(int result); 206 int DoBuildRequest(); 207 int DoBuildRequestComplete(int result); 208 int DoSendRequest(); 209 int DoSendRequestComplete(int result); 210 int DoReadHeaders(); 211 int DoReadHeadersComplete(int result); 212 int DoReadBody(); 213 int DoReadBodyComplete(int result); 214 int DoDrainBodyForAuthRestart(); 215 int DoDrainBodyForAuthRestartComplete(int result); 216 217 int BuildRequestHeaders(bool using_http_proxy_without_tunnel); 218 219 #if BUILDFLAG(ENABLE_REPORTING) 220 // Processes the Report-To header, if one exists. This header configures where 221 // the Reporting API (in //net/reporting) will send reports for the origin. 222 void ProcessReportToHeader(); 223 224 // Processes the NEL header, if one exists. This header configures whether 225 // network errors will be reported to a specified group of endpoints using the 226 // Reporting API. 227 void ProcessNetworkErrorLoggingHeader(); 228 229 // Calls GenerateNetworkErrorLoggingReport() if |rv| represents a NET_ERROR 230 // other than ERR_IO_PENDING. 231 void GenerateNetworkErrorLoggingReportIfError(int rv); 232 233 // Generates a NEL report about this request. The NetworkErrorLoggingService 234 // will discard the report if there is no NEL policy registered for this 235 // origin. 236 void GenerateNetworkErrorLoggingReport(int rv); 237 #endif 238 239 // Writes a log message to help debugging in the field when we block a proxy 240 // response to a CONNECT request. 241 void LogBlockedTunnelResponse(int response_code) const; 242 243 // Called wherever ERR_HTTP_1_1_REQUIRED or 244 // ERR_PROXY_HTTP_1_1_REQUIRED has to be handled. 245 int HandleHttp11Required(int error); 246 247 // Called to possibly handle a client authentication error. Sets next_state_ 248 // and returns OK if recovering from the error. Otherwise, the same error 249 // code is returned. 250 int HandleSSLClientAuthError(int error); 251 252 // Called to possibly recover from the given error. Sets next_state_ and 253 // returns OK if recovering from the error. Otherwise, the same error code 254 // is returned. 255 int HandleIOError(int error); 256 257 // Gets the response headers from the HttpStream. 258 HttpResponseHeaders* GetResponseHeaders() const; 259 260 // Called when the socket is unexpectedly closed. Returns true if the request 261 // should be resent in case of a socket reuse/close race. 262 bool ShouldResendRequest() const; 263 264 // Returns true if there have already been |kMaxRetryAttempts| retries for 265 // HTTP2 or QUIC network errors, and no further retries should be attempted. 266 bool HasExceededMaxRetries() const; 267 268 // Increments the number of restarts and returns true if the restart may 269 // proceed. 270 bool CheckMaxRestarts(); 271 272 // These values are persisted to logs. Entries should not be renumbered and 273 // numeric values should never be reused. 274 enum class RetryReason { 275 kHttpRequestTimeout = 0, 276 kHttpMisdirectedRequest = 1, 277 kHttp11Required = 2, 278 kSslClientAuthSignatureFailed = 3, 279 kConnectionReset = 4, 280 kConnectionClosed = 5, 281 kConnectionAborted = 6, 282 kSocketNotConnected = 7, 283 kEmptyResponse = 8, 284 kEarlyDataRejected = 9, 285 kWrongVersionOnEarlyData = 10, 286 kHttp2PingFailed = 11, 287 kHttp2ServerRefusedStream = 12, 288 // Entries 13, 14, 15 are removed. 289 kQuicHandshakeFailed = 16, 290 kQuicGoawayRequestCanBeRetried = 17, 291 kQuicProtocolError = 18, 292 kMaxValue = kQuicProtocolError, 293 }; 294 static std::optional<RetryReason> GetRetryReasonForIOError(int error); 295 296 // Resets the connection and the request headers for resend. Called when 297 // ShouldResendRequest() is true. 298 void ResetConnectionAndRequestForResend(RetryReason retry_reason); 299 300 // Sets up the state machine to restart the transaction with auth. 301 void PrepareForAuthRestart(HttpAuth::Target target); 302 303 // Called when we don't need to drain the response body or have drained it. 304 // Resets |connection_| unless |keep_alive| is true, then calls 305 // ResetStateForRestart. Sets |next_state_| appropriately. 306 void DidDrainBodyForAuthRestart(bool keep_alive); 307 308 // Resets the members of the transaction so it can be restarted. 309 void ResetStateForRestart(); 310 311 // Resets the members of the transaction, except |stream_|, which needs 312 // to be maintained for multi-round auth. 313 void ResetStateForAuthRestart(); 314 315 // Caches network error details from the stream if available 316 // and resets the stream. 317 void CacheNetErrorDetailsAndResetStream(); 318 319 // Returns true if we should try to add a Proxy-Authorization header 320 bool ShouldApplyProxyAuth() const; 321 322 // Returns true if we should try to add an Authorization header. 323 bool ShouldApplyServerAuth() const; 324 325 // Handles HTTP status code 401 or 407. 326 // HandleAuthChallenge() returns a network error code, or OK on success. 327 // May update |pending_auth_target_| or |response_.auth_challenge|. 328 int HandleAuthChallenge(); 329 330 // Returns true if we have auth credentials for the given target. 331 bool HaveAuth(HttpAuth::Target target) const; 332 333 // Get the {scheme, host, path, port} for the authentication target 334 GURL AuthURL(HttpAuth::Target target) const; 335 336 // Returns true if this transaction is for a WebSocket handshake 337 bool ForWebSocketHandshake() const; 338 339 void CopyConnectionAttemptsFromStreamRequest(); 340 341 // Returns true if response "Content-Encoding" headers respect 342 // "Accept-Encoding". 343 bool ContentEncodingsValid() const; 344 345 void ResumeAfterConnected(int result); 346 347 // These values are persisted to logs. Entries should not be renumbered and 348 // numeric values should never be reused. 349 enum class QuicProtocolErrorRetryStatus { 350 kNoRetryExceededMaxRetries = 0, 351 kNoRetryHeaderReceived = 1, 352 kNoRetryNoAlternativeService = 2, 353 kRetryAltServiceBroken = 3, 354 kRetryAltServiceNotBroken = 4, 355 kMaxValue = kRetryAltServiceNotBroken, 356 }; 357 358 void RecordQuicProtocolErrorMetrics( 359 QuicProtocolErrorRetryStatus retry_status); 360 361 void RecordMetricsIfError(int rv); 362 void RecordMetrics(int rv); 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 #endif 427 base::TimeTicks start_timeticks_; 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 / finished sending the request, including 447 // the body, if present. |send_start_time_| is set to |base::TimeTicks()| 448 // until |SendRequest()| is called on |stream_|, and reset for auth restarts. 449 base::TimeTicks send_start_time_; 450 base::TimeTicks send_end_time_; 451 452 // The next state in the state machine. 453 State next_state_ = STATE_NONE; 454 455 // True when the tunnel is in the process of being established - we can't 456 // read from the socket until the tunnel is done. 457 bool establishing_tunnel_ = false; 458 459 // Enable pooling to a SpdySession with matching IP and certificate 460 // even if the SpdySessionKey is different. 461 bool enable_ip_based_pooling_ = true; 462 463 // Enable using alternative services for the request. 464 bool enable_alternative_services_ = true; 465 466 // When a request is retried because of errors with the alternative service, 467 // this will store the alternative service used. 468 AlternativeService retried_alternative_service_; 469 470 // The helper object to use to create WebSocketHandshakeStreamBase 471 // objects. Only relevant when establishing a WebSocket connection. 472 raw_ptr<WebSocketHandshakeStreamBase::CreateHelper> 473 websocket_handshake_stream_base_create_helper_ = nullptr; 474 475 BeforeNetworkStartCallback before_network_start_callback_; 476 ConnectedCallback connected_callback_; 477 RequestHeadersCallback request_headers_callback_; 478 ResponseHeadersCallback early_response_headers_callback_; 479 ResponseHeadersCallback response_headers_callback_; 480 481 // The callback to modify the request header. They will be called just before 482 // sending the request to the network. 483 base::RepeatingCallback<void(net::HttpRequestHeaders*)> 484 modify_headers_callbacks_; 485 486 ConnectionAttempts connection_attempts_; 487 IPEndPoint remote_endpoint_; 488 // Network error details for this transaction. 489 NetErrorDetails net_error_details_; 490 491 // Number of retries made for network errors like ERR_HTTP2_PING_FAILED, 492 // ERR_HTTP2_SERVER_REFUSED_STREAM, ERR_QUIC_HANDSHAKE_FAILED and 493 // ERR_QUIC_PROTOCOL_ERROR. Currently we stop after 3 tries 494 // (including the initial request) and fail the request. 495 // This count excludes retries on reused sockets since a well 496 // behaved server may time those out and thus the number 497 // of times we can retry a request on reused sockets is limited. 498 size_t retry_attempts_ = 0; 499 500 // Number of times the transaction was restarted via a RestartWith* call. 501 size_t num_restarts_ = 0; 502 503 bool close_connection_on_destruction_ = false; 504 505 // Set to true when the server required HTTP/1.1 fallback. 506 bool http_1_1_was_required_ = false; 507 508 std::optional<base::TimeDelta> quic_protocol_error_retry_delay_; 509 }; 510 511 } // namespace net 512 513 #endif // NET_HTTP_HTTP_NETWORK_TRANSACTION_H_ 514