#ifndef NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
#define NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
#include <stdint.h>
#include <memory>
#include <string>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "build/buildflag.h"
#include "crypto/ec_private_key.h"
#include "net/base/completion_once_callback.h"
#include "net/base/completion_repeating_callback.h"
#include "net/base/net_error_details.h"
#include "net/base/net_export.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/request_priority.h"
#include "net/http/http_auth.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_stream_factory.h"
#include "net/http/http_stream_request.h"
#include "net/http/http_transaction.h"
#include "net/log/net_log_with_source.h"
#include "net/net_buildflags.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/connection_attempts.h"
#include "net/ssl/ssl_config_service.h"
#include "net/websockets/websocket_handshake_stream_base.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace net {
class BidirectionalStreamImpl;
class HttpAuthController;
class HttpNetworkSession;
class HttpStream;
class IOBuffer;
class ProxyInfo;
class SSLPrivateKey;
struct HttpRequestInfo;
class NET_EXPORT_PRIVATE HttpNetworkTransaction
: public HttpTransaction,
public HttpStreamRequest::Delegate {
public:
HttpNetworkTransaction(RequestPriority priority,
HttpNetworkSession* session);
HttpNetworkTransaction(const HttpNetworkTransaction&) = delete;
HttpNetworkTransaction& operator=(const HttpNetworkTransaction&) = delete;
~HttpNetworkTransaction() override;
int Start(const HttpRequestInfo* request_info,
CompletionOnceCallback callback,
const NetLogWithSource& net_log) override;
#ifdef OHOS_EX_HTTP_DNS_FALLBACK
int RestartWithSecureDnsOnly(CompletionOnceCallback callback) override;
#endif
int RestartIgnoringLastError(CompletionOnceCallback callback) override;
int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert,
scoped_refptr<SSLPrivateKey> client_private_key,
CompletionOnceCallback callback) override;
int RestartWithAuth(const AuthCredentials& credentials,
CompletionOnceCallback callback) override;
bool IsReadyToRestartForAuth() override;
int Read(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
void StopCaching() override;
int64_t GetTotalReceivedBytes() const override;
int64_t GetTotalSentBytes() const override;
void DoneReading() override;
const HttpResponseInfo* GetResponseInfo() const override;
LoadState GetLoadState() const override;
void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
void PopulateNetErrorDetails(NetErrorDetails* details) const override;
void SetPriority(RequestPriority priority) override;
void SetWebSocketHandshakeStreamCreateHelper(
WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
void SetBeforeNetworkStartCallback(
BeforeNetworkStartCallback callback) override;
void SetConnectedCallback(const ConnectedCallback& callback) override;
void SetRequestHeadersCallback(RequestHeadersCallback callback) override;
void SetEarlyResponseHeadersCallback(
ResponseHeadersCallback callback) override;
void SetResponseHeadersCallback(ResponseHeadersCallback callback) override;
int ResumeNetworkStart() override;
void CloseConnectionOnDestruction() override;
void OnStreamReady(const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
std::unique_ptr<HttpStream> stream) override;
void OnBidirectionalStreamImplReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
std::unique_ptr<BidirectionalStreamImpl> stream) override;
void OnWebSocketHandshakeStreamReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
std::unique_ptr<WebSocketHandshakeStreamBase> stream) override;
void OnStreamFailed(int status,
const NetErrorDetails& net_error_details,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
ResolveErrorInfo resolve_error_info) override;
void OnCertificateError(int status,
const SSLConfig& used_ssl_config,
const SSLInfo& ssl_info) override;
void OnNeedsProxyAuth(const HttpResponseInfo& response_info,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
HttpAuthController* auth_controller) override;
void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
SSLCertRequestInfo* cert_info) override;
void OnQuicBroken() override;
ConnectionAttempts GetConnectionAttempts() const override;
private:
FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, ResetStateForRestart);
FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
CreateWebSocketHandshakeStream);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateReceived);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateSent);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateOverflow);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, FlowControlStallResume);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
FlowControlStallResumeAfterSettings);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
FlowControlNegativeSendWindowSize);
enum State {
STATE_NOTIFY_BEFORE_CREATE_STREAM,
STATE_CREATE_STREAM,
STATE_CREATE_STREAM_COMPLETE,
#ifdef OHOS_EX_HTTP_DNS_FALLBACK
STATE_CREATE_FALLBACK_STREAM_WITH_SECURE_DNS_ONLY,
STATE_CREATE_FALLBACK_STREAM_WITH_SECURE_DNS_ONLY_COMPLETE,
#endif
STATE_INIT_STREAM,
STATE_INIT_STREAM_COMPLETE,
STATE_CONNECTED_CALLBACK,
STATE_CONNECTED_CALLBACK_COMPLETE,
STATE_GENERATE_PROXY_AUTH_TOKEN,
STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
STATE_GENERATE_SERVER_AUTH_TOKEN,
STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE,
STATE_INIT_REQUEST_BODY,
STATE_INIT_REQUEST_BODY_COMPLETE,
STATE_BUILD_REQUEST,
STATE_BUILD_REQUEST_COMPLETE,
STATE_SEND_REQUEST,
STATE_SEND_REQUEST_COMPLETE,
STATE_READ_HEADERS,
STATE_READ_HEADERS_COMPLETE,
STATE_READ_BODY,
STATE_READ_BODY_COMPLETE,
STATE_DRAIN_BODY_FOR_AUTH_RESTART,
STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE,
STATE_NONE
};
bool IsSecureRequest() const;
bool UsingHttpProxyWithoutTunnel() const;
void DoCallback(int result);
void OnIOComplete(int result);
int DoLoop(int result);
int DoNotifyBeforeCreateStream();
int DoCreateStream();
int DoCreateStreamComplete(int result);
#ifdef OHOS_EX_HTTP_DNS_FALLBACK
int DoCreateFallbackStreamWithSecureDnsOnly();
int DoCreateFallbackStreamWithSecureDnsOnlyComplete(int result);
#endif
int DoInitStream();
int DoInitStreamComplete(int result);
int DoConnectedCallback();
int DoConnectedCallbackComplete(int result);
int DoGenerateProxyAuthToken();
int DoGenerateProxyAuthTokenComplete(int result);
int DoGenerateServerAuthToken();
int DoGenerateServerAuthTokenComplete(int result);
int DoInitRequestBody();
int DoInitRequestBodyComplete(int result);
int DoBuildRequest();
int DoBuildRequestComplete(int result);
int DoSendRequest();
int DoSendRequestComplete(int result);
int DoReadHeaders();
int DoReadHeadersComplete(int result);
int DoReadBody();
int DoReadBodyComplete(int result);
int DoDrainBodyForAuthRestart();
int DoDrainBodyForAuthRestartComplete(int result);
int BuildRequestHeaders(bool using_http_proxy_without_tunnel);
#if BUILDFLAG(ENABLE_REPORTING)
void ProcessReportToHeader();
void ProcessNetworkErrorLoggingHeader();
void GenerateNetworkErrorLoggingReportIfError(int rv);
void GenerateNetworkErrorLoggingReport(int rv);
#endif
void LogBlockedTunnelResponse(int response_code) const;
int HandleHttp11Required(int error);
int HandleSSLClientAuthError(int error);
int HandleIOError(int error);
HttpResponseHeaders* GetResponseHeaders() const;
bool ShouldResendRequest() const;
bool HasExceededMaxRetries() const;
bool CheckMaxRestarts();
enum class RetryReason {
kHttpRequestTimeout = 0,
kHttpMisdirectedRequest = 1,
kHttp11Required = 2,
kSslClientAuthSignatureFailed = 3,
kConnectionReset = 4,
kConnectionClosed = 5,
kConnectionAborted = 6,
kSocketNotConnected = 7,
kEmptyResponse = 8,
kEarlyDataRejected = 9,
kWrongVersionOnEarlyData = 10,
kHttp2PingFailed = 11,
kHttp2ServerRefusedStream = 12,
kHttp2PushedStreamNotAvailable = 13,
kHttp2ClaimedPushedStreamResetByServer = 14,
kHttp2PushedResponseDoesNotMatch = 15,
kQuicHandshakeFailed = 16,
kQuicGoawayRequestCanBeRetried = 17,
kQuicProtocolError = 18,
kMaxValue = kQuicProtocolError,
};
static absl::optional<RetryReason> GetRetryReasonForIOError(int error);
void ResetConnectionAndRequestForResend(RetryReason retry_reason);
void PrepareForAuthRestart(HttpAuth::Target target);
void DidDrainBodyForAuthRestart(bool keep_alive);
void ResetStateForRestart();
void ResetStateForAuthRestart();
void CacheNetErrorDetailsAndResetStream();
bool ShouldApplyProxyAuth() const;
bool ShouldApplyServerAuth() const;
int HandleAuthChallenge();
bool HaveAuth(HttpAuth::Target target) const;
GURL AuthURL(HttpAuth::Target target) const;
bool ForWebSocketHandshake() const;
void CopyConnectionAttemptsFromStreamRequest();
bool ContentEncodingsValid() const;
void ResumeAfterConnected(int result);
enum class QuicProtocolErrorRetryStatus {
kNoRetryExceededMaxRetries = 0,
kNoRetryHeaderReceived = 1,
kNoRetryNoAlternativeService = 2,
kRetryAltServiceBroken = 3,
kRetryAltServiceNotBroken = 4,
kMaxValue = kRetryAltServiceNotBroken,
};
void RecordQuicProtocolErrorMetrics(
QuicProtocolErrorRetryStatus retry_status);
void RecordMetricsIfError(int rv);
void RecordMetrics(int rv);
scoped_refptr<HttpAuthController>
auth_controllers_[HttpAuth::AUTH_NUM_TARGETS];
HttpAuth::Target pending_auth_target_ = HttpAuth::AUTH_NONE;
CompletionRepeatingCallback io_callback_;
CompletionOnceCallback callback_;
raw_ptr<HttpNetworkSession> session_;
NetLogWithSource net_log_;
raw_ptr<const HttpRequestInfo> request_ = nullptr;
GURL url_;
RequestPriority priority_;
HttpResponseInfo response_;
NetworkAnonymizationKey network_anonymization_key_;
ProxyInfo proxy_info_;
std::unique_ptr<HttpStreamRequest> stream_request_;
std::unique_ptr<HttpStream> stream_;
bool headers_valid_ = false;
bool can_send_early_data_ = false;
bool configured_client_cert_for_server_ = false;
SSLConfig server_ssl_config_;
SSLConfig proxy_ssl_config_;
HttpRequestHeaders request_headers_;
#if BUILDFLAG(ENABLE_REPORTING)
bool network_error_logging_report_generated_ = false;
std::string request_method_;
std::string request_referrer_;
std::string request_user_agent_;
int request_reporting_upload_depth_ = 0;
#endif
base::TimeTicks start_timeticks_;
static const int kDrainBodyBufferSize = 1024;
scoped_refptr<IOBuffer> read_buf_;
int read_buf_len_ = 0;
int64_t total_received_bytes_ = 0;
int64_t total_sent_bytes_ = 0;
base::TimeTicks send_start_time_;
base::TimeTicks send_end_time_;
State next_state_ = STATE_NONE;
bool establishing_tunnel_ = false;
bool enable_ip_based_pooling_ = true;
bool enable_alternative_services_ = true;
AlternativeService retried_alternative_service_;
raw_ptr<WebSocketHandshakeStreamBase::CreateHelper>
websocket_handshake_stream_base_create_helper_ = nullptr;
BeforeNetworkStartCallback before_network_start_callback_;
ConnectedCallback connected_callback_;
RequestHeadersCallback request_headers_callback_;
ResponseHeadersCallback early_response_headers_callback_;
ResponseHeadersCallback response_headers_callback_;
ConnectionAttempts connection_attempts_;
IPEndPoint remote_endpoint_;
NetErrorDetails net_error_details_;
size_t retry_attempts_ = 0;
size_t num_restarts_ = 0;
bool close_connection_on_destruction_ = false;
#ifdef OHOS_EX_HTTP_DNS_FALLBACK
bool stream_created_ = false;
#endif
absl::optional<base::TimeDelta> quic_protocol_error_retry_delay_;
};
}
#endif