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