1 // Copyright 2023 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_SHARED_DICTIONARY_SHARED_DICTIONARY_NETWORK_TRANSACTION_H_ 6 #define NET_SHARED_DICTIONARY_SHARED_DICTIONARY_NETWORK_TRANSACTION_H_ 7 8 #include <vector> 9 10 #include "base/functional/callback.h" 11 #include "base/memory/raw_ref.h" 12 #include "base/memory/scoped_refptr.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/time/time.h" 15 #include "base/types/expected.h" 16 #include "net/base/completion_once_callback.h" 17 #include "net/base/net_errors.h" 18 #include "net/base/net_export.h" 19 #include "net/http/http_transaction.h" 20 #include "net/shared_dictionary/shared_dictionary_getter.h" 21 #include "net/socket/next_proto.h" 22 23 class GURL; 24 25 namespace net { 26 class SharedDictionary; 27 class SourceStream; 28 struct TransportInfo; 29 30 // A `HttpTransaction` that decodes shared dictionary compression. 31 // If the `LOAD_CAN_USE_SHARED_DICTIONARY` flag is not set in the `request`'s 32 // `load_flags`, this class delegates all function calls to the underlying 33 // transaction. 34 // Otherwise, this class registers a callback with the underlying transaction 35 // that will be called just before the request is sent to the network. When this 36 // callback is called, this class tries to get a registered dictionary from the 37 // `shared_dictionary_manager`. If a matching dictionary is found, and the 38 // "content-encoding" header of the response from the server is "dcb" or "dcz", 39 // this class will decode the response body using a `BrotliSourceStream` or 40 // `ZstdSourceStream` with the dictionary. 41 class NET_EXPORT SharedDictionaryNetworkTransaction : public HttpTransaction { 42 public: 43 SharedDictionaryNetworkTransaction( 44 std::unique_ptr<HttpTransaction> network_transaction, 45 bool enable_shared_zstd); 46 47 SharedDictionaryNetworkTransaction( 48 const SharedDictionaryNetworkTransaction&) = delete; 49 SharedDictionaryNetworkTransaction& operator=( 50 const SharedDictionaryNetworkTransaction&) = delete; 51 52 ~SharedDictionaryNetworkTransaction() override; 53 54 // HttpTransaction methods: 55 int Start(const HttpRequestInfo* request, 56 CompletionOnceCallback callback, 57 const NetLogWithSource& net_log) override; 58 int RestartIgnoringLastError(CompletionOnceCallback callback) override; 59 int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert, 60 scoped_refptr<SSLPrivateKey> client_private_key, 61 CompletionOnceCallback callback) override; 62 int RestartWithAuth(const AuthCredentials& credentials, 63 CompletionOnceCallback callback) override; 64 bool IsReadyToRestartForAuth() override; 65 66 int Read(IOBuffer* buf, 67 int buf_len, 68 CompletionOnceCallback callback) override; 69 void StopCaching() override; 70 int64_t GetTotalReceivedBytes() const override; 71 int64_t GetTotalSentBytes() const override; 72 int64_t GetReceivedBodyBytes() const override; 73 void DoneReading() override; 74 const HttpResponseInfo* GetResponseInfo() const override; 75 LoadState GetLoadState() const override; 76 void SetQuicServerInfo(QuicServerInfo* quic_server_info) override; 77 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; 78 bool GetRemoteEndpoint(IPEndPoint* endpoint) const override; 79 void PopulateNetErrorDetails(NetErrorDetails* details) const override; 80 void SetPriority(RequestPriority priority) override; 81 void SetWebSocketHandshakeStreamCreateHelper( 82 WebSocketHandshakeStreamBase::CreateHelper* create_helper) override; 83 void SetBeforeNetworkStartCallback( 84 BeforeNetworkStartCallback callback) override; 85 void SetConnectedCallback(const ConnectedCallback& callback) override; 86 void SetRequestHeadersCallback(RequestHeadersCallback callback) override; 87 void SetResponseHeadersCallback(ResponseHeadersCallback callback) override; 88 void SetEarlyResponseHeadersCallback( 89 ResponseHeadersCallback callback) override; 90 void SetModifyRequestHeadersCallback( 91 base::RepeatingCallback<void(HttpRequestHeaders*)> callback) override; 92 void SetIsSharedDictionaryReadAllowedCallback( 93 base::RepeatingCallback<bool()> callback) override; 94 int ResumeNetworkStart() override; 95 ConnectionAttempts GetConnectionAttempts() const override; 96 void CloseConnectionOnDestruction() override; 97 bool IsMdlMatchForMetrics() const override; 98 99 private: 100 enum class DictionaryStatus { 101 kNoDictionary, 102 kReading, 103 kFinished, 104 kFailed, 105 }; 106 107 // These values are persisted to logs. Entries should not be renumbered and 108 // numeric values should never be reused. 109 enum class SharedDictionaryEncodingType { 110 kNotUsed = 0, 111 kSharedBrotli = 1, 112 kSharedZstd = 2, 113 kMaxValue = kSharedZstd, 114 }; 115 116 class PendingReadTask { 117 public: 118 PendingReadTask(IOBuffer* buf, 119 int buf_len, 120 CompletionOnceCallback callback); 121 122 PendingReadTask(const PendingReadTask&) = delete; 123 PendingReadTask& operator=(const PendingReadTask&) = delete; 124 125 ~PendingReadTask(); 126 127 scoped_refptr<IOBuffer> buf; 128 int buf_len; 129 CompletionOnceCallback callback; 130 }; 131 132 SharedDictionaryEncodingType ParseSharedDictionaryEncodingType( 133 const HttpResponseHeaders& headers); 134 135 void OnStartCompleted(CompletionOnceCallback callback, int result); 136 137 void ModifyRequestHeaders(const GURL& request_url, 138 HttpRequestHeaders* request_headers); 139 140 void OnReadSharedDictionary(base::Time read_start_time, int result); 141 142 int OnConnected(const TransportInfo& info, CompletionOnceCallback callback); 143 144 const bool enable_shared_zstd_; 145 146 scoped_refptr<SharedDictionary> shared_dictionary_; 147 // The Structured Field sf-binary hash of sha256 of dictionary calculated when 148 // sending a HTTP request. 149 std::string dictionary_hash_base64_; 150 151 DictionaryStatus dictionary_status_ = DictionaryStatus::kNoDictionary; 152 153 SharedDictionaryEncodingType shared_dictionary_encoding_type_ = 154 SharedDictionaryEncodingType::kNotUsed; 155 156 std::unique_ptr<PendingReadTask> pending_read_task_; 157 158 base::RepeatingCallback<bool()> is_shared_dictionary_read_allowed_callback_; 159 160 // The network side transaction. 161 std::unique_ptr<HttpTransaction> network_transaction_; 162 163 std::unique_ptr<SourceStream> shared_compression_stream_; 164 165 // This is set only when a shared dictionary is used for decoding the body. 166 std::unique_ptr<HttpResponseInfo> shared_dictionary_used_response_info_; 167 168 ConnectedCallback connected_callback_; 169 170 bool cert_is_issued_by_known_root_ = false; 171 NextProto negotiated_protocol_ = kProtoUnknown; 172 173 base::RepeatingCallback<scoped_refptr<SharedDictionary>()> 174 shared_dictionary_getter_; 175 176 base::WeakPtrFactory<SharedDictionaryNetworkTransaction> weak_factory_{this}; 177 }; 178 179 } // namespace net 180 181 #endif // NET_SHARED_DICTIONARY_SHARED_DICTIONARY_NETWORK_TRANSACTION_H_ 182