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