chromium/net/http/http_network_transaction.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

#include "net/http/http_network_transaction.h"

#include <set>
#include <utility>
#include <vector>

#include "base/base64url.h"
#include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "net/base/auth.h"
#include "net/base/features.h"
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/load_timing_info.h"
#include "net/base/net_errors.h"
#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/transport_info.h"
#include "net/base/upload_data_stream.h"
#include "net/base/url_util.h"
#include "net/cert/cert_status_flags.h"
#include "net/filter/filter_source_stream.h"
#include "net/http/bidirectional_stream_impl.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_controller.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_basic_stream.h"
#include "net/http/http_chunked_decoder.h"
#include "net/http/http_connection_info.h"
#include "net/http/http_log_util.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_status_code.h"
#include "net/http/http_stream.h"
#include "net/http/http_stream_factory.h"
#include "net/http/http_stream_pool.h"
#include "net/http/http_util.h"
#include "net/http/transport_security_state.h"
#include "net/http/url_security_manager.h"
#include "net/log/net_log_event_type.h"
#include "net/proxy_resolution/proxy_info.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/next_proto.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/spdy/spdy_http_stream.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_session_pool.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_connection_status_flags.h"
#include "net/ssl/ssl_info.h"
#include "net/ssl/ssl_private_key.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/scheme_host_port.h"
#include "url/url_canon.h"

#if BUILDFLAG(ENABLE_REPORTING)
#include "net/network_error_logging/network_error_logging_service.h"
#include "net/reporting/reporting_header_parser.h"
#include "net/reporting/reporting_service.h"
#endif  // BUILDFLAG(ENABLE_REPORTING)

namespace net {

namespace {

// Max number of |retry_attempts| (excluding the initial request) after which
// we give up and show an error page.
const size_t kMaxRetryAttempts =;

// Max number of calls to RestartWith* allowed for a single connection. A single
// HttpNetworkTransaction should not signal very many restartable errors, but it
// may occur due to a bug (e.g. https://crbug.com/823387 or
// https://crbug.com/488043) or simply if the server or proxy requests
// authentication repeatedly. Although these calls are often associated with a
// user prompt, in other scenarios (remembered preferences, extensions,
// multi-leg authentication), they may be triggered automatically. To avoid
// looping forever, bound the number of restarts.
const size_t kMaxRestarts =;

// Returns true when Early Hints are allowed on the given protocol.
bool EarlyHintsAreAllowedOn(HttpConnectionInfo connection_info) {}

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class WebSocketFallbackResult {};

WebSocketFallbackResult CalculateWebSocketFallbackResult(
    int result,
    bool http_1_1_was_required,
    HttpConnectionInfoCoarse connection_info) {}

void RecordWebSocketFallbackResult(int result,
                                   bool http_1_1_was_required,
                                   HttpConnectionInfoCoarse connection_info) {}

const std::string_view NegotiatedProtocolToHistogramSuffix(
    const HttpResponseInfo& response) {}

}  // namespace

const int HttpNetworkTransaction::kDrainBodyBufferSize;

HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority,
                                               HttpNetworkSession* session)
    :{}

HttpNetworkTransaction::~HttpNetworkTransaction() {}

int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
                                  CompletionOnceCallback callback,
                                  const NetLogWithSource& net_log) {}

int HttpNetworkTransaction::RestartIgnoringLastError(
    CompletionOnceCallback callback) {}

int HttpNetworkTransaction::RestartWithCertificate(
    scoped_refptr<X509Certificate> client_cert,
    scoped_refptr<SSLPrivateKey> client_private_key,
    CompletionOnceCallback callback) {}

int HttpNetworkTransaction::RestartWithAuth(const AuthCredentials& credentials,
                                            CompletionOnceCallback callback) {}

void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) {}

void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) {}

bool HttpNetworkTransaction::IsReadyToRestartForAuth() {}

int HttpNetworkTransaction::Read(IOBuffer* buf,
                                 int buf_len,
                                 CompletionOnceCallback callback) {}

void HttpNetworkTransaction::StopCaching() {}

int64_t HttpNetworkTransaction::GetTotalReceivedBytes() const {}

int64_t HttpNetworkTransaction::GetTotalSentBytes() const {}

int64_t HttpNetworkTransaction::GetReceivedBodyBytes() const {}

void HttpNetworkTransaction::DoneReading() {}

const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const {}

LoadState HttpNetworkTransaction::GetLoadState() const {}

void HttpNetworkTransaction::SetQuicServerInfo(
    QuicServerInfo* quic_server_info) {}

bool HttpNetworkTransaction::GetLoadTimingInfo(
    LoadTimingInfo* load_timing_info) const {}

bool HttpNetworkTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {}

void HttpNetworkTransaction::PopulateNetErrorDetails(
    NetErrorDetails* details) const {}

void HttpNetworkTransaction::SetPriority(RequestPriority priority) {}

void HttpNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
    WebSocketHandshakeStreamBase::CreateHelper* create_helper) {}

void HttpNetworkTransaction::SetBeforeNetworkStartCallback(
    BeforeNetworkStartCallback callback) {}

void HttpNetworkTransaction::SetConnectedCallback(
    const ConnectedCallback& callback) {}

void HttpNetworkTransaction::SetRequestHeadersCallback(
    RequestHeadersCallback callback) {}

void HttpNetworkTransaction::SetEarlyResponseHeadersCallback(
    ResponseHeadersCallback callback) {}

void HttpNetworkTransaction::SetResponseHeadersCallback(
    ResponseHeadersCallback callback) {}

void HttpNetworkTransaction::SetModifyRequestHeadersCallback(
    base::RepeatingCallback<void(HttpRequestHeaders*)> callback) {}

void HttpNetworkTransaction::SetIsSharedDictionaryReadAllowedCallback(
    base::RepeatingCallback<bool()> callback) {}

int HttpNetworkTransaction::ResumeNetworkStart() {}

void HttpNetworkTransaction::ResumeAfterConnected(int result) {}

void HttpNetworkTransaction::CloseConnectionOnDestruction() {}

bool HttpNetworkTransaction::IsMdlMatchForMetrics() const {}

void HttpNetworkTransaction::OnStreamReady(const ProxyInfo& used_proxy_info,
                                           std::unique_ptr<HttpStream> stream) {}

void HttpNetworkTransaction::OnBidirectionalStreamImplReady(
    const ProxyInfo& used_proxy_info,
    std::unique_ptr<BidirectionalStreamImpl> stream) {}

void HttpNetworkTransaction::OnWebSocketHandshakeStreamReady(
    const ProxyInfo& used_proxy_info,
    std::unique_ptr<WebSocketHandshakeStreamBase> stream) {}

void HttpNetworkTransaction::OnStreamFailed(
    int result,
    const NetErrorDetails& net_error_details,
    const ProxyInfo& used_proxy_info,
    ResolveErrorInfo resolve_error_info) {}

void HttpNetworkTransaction::OnCertificateError(int result,
                                                const SSLInfo& ssl_info) {}

void HttpNetworkTransaction::OnNeedsProxyAuth(
    const HttpResponseInfo& proxy_response,
    const ProxyInfo& used_proxy_info,
    HttpAuthController* auth_controller) {}

void HttpNetworkTransaction::OnNeedsClientAuth(SSLCertRequestInfo* cert_info) {}

void HttpNetworkTransaction::OnQuicBroken() {}

void HttpNetworkTransaction::OnSwitchesToHttpStreamPool(
    HttpStreamKey stream_key,
    const AlternativeServiceInfo& alternative_service_info,
    quic::ParsedQuicVersion quic_version) {}

ConnectionAttempts HttpNetworkTransaction::GetConnectionAttempts() const {}

bool HttpNetworkTransaction::IsSecureRequest() const {}

bool HttpNetworkTransaction::UsingHttpProxyWithoutTunnel() const {}

void HttpNetworkTransaction::DoCallback(int rv) {}

void HttpNetworkTransaction::OnIOComplete(int result) {}

int HttpNetworkTransaction::DoLoop(int result) {}

int HttpNetworkTransaction::DoNotifyBeforeCreateStream() {}

int HttpNetworkTransaction::DoCreateStream() {}

int HttpNetworkTransaction::DoCreateStreamComplete(int result) {}

int HttpNetworkTransaction::DoInitStream() {}

int HttpNetworkTransaction::DoInitStreamComplete(int result) {}

int HttpNetworkTransaction::DoConnectedCallback() {}

int HttpNetworkTransaction::DoConnectedCallbackComplete(int result) {}

int HttpNetworkTransaction::DoGenerateProxyAuthToken() {}

int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) {}

int HttpNetworkTransaction::DoGenerateServerAuthToken() {}

int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {}

int HttpNetworkTransaction::BuildRequestHeaders(
    bool using_http_proxy_without_tunnel) {}

int HttpNetworkTransaction::DoInitRequestBody() {}

int HttpNetworkTransaction::DoInitRequestBodyComplete(int result) {}

int HttpNetworkTransaction::DoBuildRequest() {}

int HttpNetworkTransaction::DoBuildRequestComplete(int result) {}

int HttpNetworkTransaction::DoSendRequest() {}

int HttpNetworkTransaction::DoSendRequestComplete(int result) {}

int HttpNetworkTransaction::DoReadHeaders() {}

int HttpNetworkTransaction::DoReadHeadersComplete(int result) {}

int HttpNetworkTransaction::DoReadBody() {}

int HttpNetworkTransaction::DoReadBodyComplete(int result) {}

int HttpNetworkTransaction::DoDrainBodyForAuthRestart() {}

// TODO(wtc): This method and the DoReadBodyComplete method are almost
// the same.  Figure out a good way for these two methods to share code.
int HttpNetworkTransaction::DoDrainBodyForAuthRestartComplete(int result) {}

#if BUILDFLAG(ENABLE_REPORTING)
void HttpNetworkTransaction::ProcessReportToHeader() {}

void HttpNetworkTransaction::ProcessNetworkErrorLoggingHeader() {}

void HttpNetworkTransaction::GenerateNetworkErrorLoggingReportIfError(int rv) {}

void HttpNetworkTransaction::GenerateNetworkErrorLoggingReport(int rv) {}
#endif  // BUILDFLAG(ENABLE_REPORTING)

int HttpNetworkTransaction::HandleHttp11Required(int error) {}

int HttpNetworkTransaction::HandleSSLClientAuthError(int error) {}

// static
std::optional<HttpNetworkTransaction::RetryReason>
HttpNetworkTransaction::GetRetryReasonForIOError(int error) {}

// This method determines whether it is safe to resend the request after an
// IO error. It should only be called in response to errors received before
// final set of response headers have been successfully parsed, that the
// transaction may need to be retried on.
// It should not be used in other cases, such as a Connect error.
int HttpNetworkTransaction::HandleIOError(int error) {}

void HttpNetworkTransaction::ResetStateForRestart() {}

void HttpNetworkTransaction::ResetStateForAuthRestart() {}

void HttpNetworkTransaction::CacheNetErrorDetailsAndResetStream() {}

HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const {}

bool HttpNetworkTransaction::ShouldResendRequest() const {}

bool HttpNetworkTransaction::HasExceededMaxRetries() const {}

bool HttpNetworkTransaction::CheckMaxRestarts() {}

void HttpNetworkTransaction::ResetConnectionAndRequestForResend(
    RetryReason retry_reason) {}

bool HttpNetworkTransaction::ShouldApplyProxyAuth() const {}

bool HttpNetworkTransaction::ShouldApplyServerAuth() const {}

int HttpNetworkTransaction::HandleAuthChallenge() {}

bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const {}

GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const {}

bool HttpNetworkTransaction::ForWebSocketHandshake() const {}

void HttpNetworkTransaction::CopyConnectionAttemptsFromStreamRequest() {}

bool HttpNetworkTransaction::ContentEncodingsValid() const {}

// static
void HttpNetworkTransaction::SetProxyInfoInResponse(
    const ProxyInfo& proxy_info,
    HttpResponseInfo* response_info) {}

}  // namespace net