• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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