xref: /aosp_15_r20/external/cronet/net/http/http_transaction_test_util.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 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_TRANSACTION_TEST_UTIL_H_
6 #define NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
7 
8 #include <stdint.h>
9 
10 #include <optional>
11 #include <set>
12 #include <string>
13 #include <vector>
14 
15 #include "base/compiler_specific.h"
16 #include "base/functional/callback.h"
17 #include "base/memory/raw_ptr.h"
18 #include "base/memory/scoped_refptr.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/time/time.h"
21 #include "net/base/completion_once_callback.h"
22 #include "net/base/io_buffer.h"
23 #include "net/base/load_flags.h"
24 #include "net/base/net_error_details.h"
25 #include "net/base/net_errors.h"
26 #include "net/base/request_priority.h"
27 #include "net/base/test_completion_callback.h"
28 #include "net/base/transport_info.h"
29 #include "net/cert/x509_certificate.h"
30 #include "net/disk_cache/disk_cache.h"
31 #include "net/http/http_cache.h"
32 #include "net/http/http_request_info.h"
33 #include "net/http/http_response_headers.h"
34 #include "net/http/http_response_info.h"
35 #include "net/http/http_transaction.h"
36 #include "net/log/net_log_source.h"
37 #include "net/socket/connection_attempts.h"
38 
39 namespace net {
40 
41 class IOBuffer;
42 class SSLPrivateKey;
43 class NetLogWithSource;
44 struct HttpRequestInfo;
45 
46 //-----------------------------------------------------------------------------
47 // mock transaction data
48 
49 // these flags may be combined to form the test_mode field
50 enum {
51   TEST_MODE_NORMAL = 0,
52   TEST_MODE_SYNC_NET_START = 1 << 0,
53   TEST_MODE_SYNC_NET_READ  = 1 << 1,
54   TEST_MODE_SYNC_CACHE_START = 1 << 2,
55   TEST_MODE_SYNC_CACHE_READ  = 1 << 3,
56   TEST_MODE_SYNC_CACHE_WRITE  = 1 << 4,
57   TEST_MODE_SYNC_ALL = (TEST_MODE_SYNC_NET_START | TEST_MODE_SYNC_NET_READ |
58                         TEST_MODE_SYNC_CACHE_START | TEST_MODE_SYNC_CACHE_READ |
59                         TEST_MODE_SYNC_CACHE_WRITE),
60   TEST_MODE_SLOW_READ = 1 << 5
61 };
62 
63 using MockTransactionReadHandler = base::RepeatingCallback<
64     int(int64_t content_length, int64_t offset, IOBuffer* buf, int buf_len)>;
65 
66 using MockTransactionHandler =
67     base::RepeatingCallback<void(const HttpRequestInfo* request,
68                                  std::string* response_status,
69                                  std::string* response_headers,
70                                  std::string* response_data)>;
71 
72 // Default TransportInfo suitable for most MockTransactions.
73 // Describes a direct connection to (127.0.0.1, 80).
74 TransportInfo DefaultTransportInfo();
75 
76 struct MockTransaction {
77   const char* url;
78   const char* method;
79   // If |request_time| is unspecified, the current time will be used.
80   base::Time request_time;
81   const char* request_headers;
82   int load_flags;
83   // Connection info passed to ConnectedCallback(), if any.
84   TransportInfo transport_info = DefaultTransportInfo();
85   const char* status;
86   const char* response_headers;
87   // If |response_time| is unspecified, the current time will be used.
88   base::Time response_time;
89   const char* data;
90   // Any aliases for the requested URL, as read from DNS records. Includes all
91   // known aliases, e.g. from A, AAAA, or HTTPS, not just from the address used
92   // for the connection, in no particular order.
93   std::set<std::string> dns_aliases;
94   std::optional<int64_t> fps_cache_filter;
95   std::optional<int64_t> browser_run_id;
96   int test_mode;
97   MockTransactionHandler handler;
98   MockTransactionReadHandler read_handler;
99   scoped_refptr<X509Certificate> cert;
100   CertStatus cert_status;
101   int ssl_connection_status;
102   // Value returned by MockNetworkTransaction::Start (potentially
103   // asynchronously if |!(test_mode & TEST_MODE_SYNC_NET_START)|.)
104   Error start_return_code;
105   // Value returned by MockNetworkTransaction::Read (potentially
106   // asynchronously if |!(test_mode & TEST_MODE_SYNC_NET_START)|.)
107   Error read_return_code;
108 };
109 
110 extern const MockTransaction kSimpleGET_Transaction;
111 extern const MockTransaction kSimplePOST_Transaction;
112 extern const MockTransaction kTypicalGET_Transaction;
113 extern const MockTransaction kETagGET_Transaction;
114 extern const MockTransaction kRangeGET_Transaction;
115 
116 // returns the mock transaction for the given URL
117 const MockTransaction* FindMockTransaction(const GURL& url);
118 
119 // Register a mock transaction that can be accessed via
120 // FindMockTransaction. There can be only one MockTransaction associated
121 // with a given URL.
122 struct ScopedMockTransaction : MockTransaction {
123   explicit ScopedMockTransaction(const char* url);
124   explicit ScopedMockTransaction(const MockTransaction& t,
125                                  const char* url = nullptr);
126   ~ScopedMockTransaction();
127 };
128 
129 //-----------------------------------------------------------------------------
130 // mock http request
131 
132 class MockHttpRequest : public HttpRequestInfo {
133  public:
134   explicit MockHttpRequest(const MockTransaction& t);
135   std::string CacheKey();
136 };
137 
138 //-----------------------------------------------------------------------------
139 // use this class to test completely consuming a transaction
140 
141 class TestTransactionConsumer {
142  public:
143   TestTransactionConsumer(RequestPriority priority,
144                           HttpTransactionFactory* factory);
145   virtual ~TestTransactionConsumer();
146 
147   void Start(const HttpRequestInfo* request, const NetLogWithSource& net_log);
148 
is_done()149   bool is_done() const { return state_ == State::kDone; }
error()150   int error() const { return error_; }
151 
response_info()152   const HttpResponseInfo* response_info() const {
153     return trans_->GetResponseInfo();
154   }
transaction()155   const HttpTransaction* transaction() const { return trans_.get(); }
content()156   const std::string& content() const { return content_; }
157 
158  private:
159   enum class State { kIdle, kStarting, kReading, kDone };
160 
161   void DidStart(int result);
162   void DidRead(int result);
163   void DidFinish(int result);
164   void Read();
165 
166   void OnIOComplete(int result);
167 
168   State state_ = State::kIdle;
169   std::unique_ptr<HttpTransaction> trans_;
170   std::string content_;
171   scoped_refptr<IOBuffer> read_buf_;
172   int error_ = OK;
173   base::OnceClosure quit_closure_;
174 };
175 
176 //-----------------------------------------------------------------------------
177 // mock network layer
178 
179 class MockNetworkLayer;
180 
181 // This transaction class inspects the available set of mock transactions to
182 // find data for the request URL.  It supports IO operations that complete
183 // synchronously or asynchronously to help exercise different code paths in the
184 // HttpCache implementation.
185 class MockNetworkTransaction
186     : public HttpTransaction,
187       public base::SupportsWeakPtr<MockNetworkTransaction> {
188   typedef WebSocketHandshakeStreamBase::CreateHelper CreateHelper;
189 
190  public:
191   MockNetworkTransaction(RequestPriority priority, MockNetworkLayer* factory);
192   ~MockNetworkTransaction() override;
193 
194   int Start(const HttpRequestInfo* request,
195             CompletionOnceCallback callback,
196             const NetLogWithSource& net_log) override;
197 
198   int RestartIgnoringLastError(CompletionOnceCallback callback) override;
199 
200   int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert,
201                              scoped_refptr<SSLPrivateKey> client_private_key,
202                              CompletionOnceCallback callback) override;
203 
204   int RestartWithAuth(const AuthCredentials& credentials,
205                       CompletionOnceCallback callback) override;
206 
207   bool IsReadyToRestartForAuth() override;
208 
209   int Read(IOBuffer* buf,
210            int buf_len,
211            CompletionOnceCallback callback) override;
212   void PopulateNetErrorDetails(NetErrorDetails* details) const override;
213 
214   void StopCaching() override;
215 
216   int64_t GetTotalReceivedBytes() const override;
217 
218   int64_t GetTotalSentBytes() const override;
219 
220   void DoneReading() override;
221 
222   const HttpResponseInfo* GetResponseInfo() const override;
223 
224   LoadState GetLoadState() const override;
225 
226   void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
227 
228   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
229 
230   bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
231 
232   void SetPriority(RequestPriority priority) override;
233 
234   void SetWebSocketHandshakeStreamCreateHelper(
235       CreateHelper* create_helper) override;
236 
237   void SetBeforeNetworkStartCallback(
238       BeforeNetworkStartCallback callback) override;
239 
240   void SetConnectedCallback(const ConnectedCallback& callback) override;
241 
SetRequestHeadersCallback(RequestHeadersCallback callback)242   void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
SetResponseHeadersCallback(ResponseHeadersCallback)243   void SetResponseHeadersCallback(ResponseHeadersCallback) override {}
SetEarlyResponseHeadersCallback(ResponseHeadersCallback)244   void SetEarlyResponseHeadersCallback(ResponseHeadersCallback) override {}
245 
246   void SetModifyRequestHeadersCallback(
247       base::RepeatingCallback<void(net::HttpRequestHeaders*)> callback)
248       override;
249 
SetIsSharedDictionaryReadAllowedCallback(base::RepeatingCallback<bool ()> callback)250   void SetIsSharedDictionaryReadAllowedCallback(
251       base::RepeatingCallback<bool()> callback) override {}
252 
253   int ResumeNetworkStart() override;
254 
255   ConnectionAttempts GetConnectionAttempts() const override;
256 
257   void CloseConnectionOnDestruction() override;
258   bool IsMdlMatchForMetrics() const override;
259 
websocket_handshake_stream_create_helper()260   CreateHelper* websocket_handshake_stream_create_helper() {
261     return websocket_handshake_stream_create_helper_;
262   }
263 
priority()264   RequestPriority priority() const { return priority_; }
265 
266   // Bogus value that will be returned by GetTotalReceivedBytes() if the
267   // MockNetworkTransaction was started.
268   static const int64_t kTotalReceivedBytes;
269   // Bogus value that will be returned by GetTotalSentBytes() if the
270   // MockNetworkTransaction was started.
271   static const int64_t kTotalSentBytes;
272 
273  private:
274   enum class State {
275     NOTIFY_BEFORE_CREATE_STREAM,
276     CREATE_STREAM,
277     CREATE_STREAM_COMPLETE,
278     CONNECTED_CALLBACK,
279     CONNECTED_CALLBACK_COMPLETE,
280     BUILD_REQUEST,
281     BUILD_REQUEST_COMPLETE,
282     SEND_REQUEST,
283     SEND_REQUEST_COMPLETE,
284     READ_HEADERS,
285     READ_HEADERS_COMPLETE,
286     NONE
287   };
288 
289   int StartInternal(HttpRequestInfo request, CompletionOnceCallback callback);
290   int DoNotifyBeforeCreateStream();
291   int DoCreateStream();
292   int DoCreateStreamComplete(int result);
293   int DoConnectedCallback();
294   int DoConnectedCallbackComplete(int result);
295   int DoBuildRequest();
296   int DoBuildRequestComplete(int result);
297   int DoSendRequest();
298   int DoSendRequestComplete(int result);
299   int DoReadHeaders();
300   int DoReadHeadersComplete(int result);
301 
302   // Runs the state transition loop.
303   int DoLoop(int result);
304 
305   void OnIOComplete(int result);
306 
307   void CallbackLater(CompletionOnceCallback callback, int result);
308   void RunCallback(CompletionOnceCallback callback, int result);
309 
310   raw_ptr<const HttpRequestInfo> original_request_ptr_ = nullptr;
311   HttpRequestInfo current_request_;
312   State next_state_ = State::NONE;
313   NetLogWithSource net_log_;
314 
315   CompletionOnceCallback callback_;
316 
317   HttpResponseInfo response_;
318   std::string data_;
319   int64_t data_cursor_ = 0;
320   int64_t content_length_ = 0;
321   int test_mode_;
322   RequestPriority priority_;
323   raw_ptr<CreateHelper> websocket_handshake_stream_create_helper_ = nullptr;
324   BeforeNetworkStartCallback before_network_start_callback_;
325   ConnectedCallback connected_callback_;
326   base::WeakPtr<MockNetworkLayer> transaction_factory_;
327   int64_t received_bytes_ = 0;
328   int64_t sent_bytes_ = 0;
329 
330   // NetLog ID of the fake / non-existent underlying socket used by the
331   // connection. Requires Start() be passed a NetLogWithSource with a real
332   // NetLog to
333   // be initialized.
334   unsigned int socket_log_id_ = NetLogSource::kInvalidId;
335 
336   bool done_reading_called_ = false;
337   bool reading_ = false;
338 
339   CompletionOnceCallback resume_start_callback_;  // used for pause and restart.
340 
341   base::RepeatingCallback<void(net::HttpRequestHeaders*)>
342       modify_request_headers_callback_;
343 
344   base::WeakPtrFactory<MockNetworkTransaction> weak_factory_{this};
345 };
346 
347 class MockNetworkLayer : public HttpTransactionFactory,
348                          public base::SupportsWeakPtr<MockNetworkLayer> {
349  public:
350   MockNetworkLayer();
351   ~MockNetworkLayer() override;
352 
transaction_count()353   int transaction_count() const { return transaction_count_; }
done_reading_called()354   bool done_reading_called() const { return done_reading_called_; }
stop_caching_called()355   bool stop_caching_called() const { return stop_caching_called_; }
356   void TransactionDoneReading();
357   void TransactionStopCaching();
358 
359   // Resets the transaction count. Can be called after test setup in order to
360   // make test expectations independent of how test setup is performed.
361   void ResetTransactionCount();
362 
363   // Returns the last priority passed to CreateTransaction, or
364   // DEFAULT_PRIORITY if it hasn't been called yet.
last_create_transaction_priority()365   RequestPriority last_create_transaction_priority() const {
366     return last_create_transaction_priority_;
367   }
368 
369   // Returns the last transaction created by
370   // CreateTransaction. Returns a NULL WeakPtr if one has not been
371   // created yet, or the last transaction has been destroyed, or
372   // ClearLastTransaction() has been called and a new transaction
373   // hasn't been created yet.
last_transaction()374   base::WeakPtr<MockNetworkTransaction> last_transaction() {
375     return last_transaction_;
376   }
377 
378   // Makes last_transaction() return NULL until the next transaction
379   // is created.
ClearLastTransaction()380   void ClearLastTransaction() {
381     last_transaction_.reset();
382   }
383 
384   // HttpTransactionFactory:
385   int CreateTransaction(RequestPriority priority,
386                         std::unique_ptr<HttpTransaction>* trans) override;
387   HttpCache* GetCache() override;
388   HttpNetworkSession* GetSession() override;
389 
390   // The caller must guarantee that |clock| will outlive this object.
391   void SetClock(base::Clock* clock);
clock()392   base::Clock* clock() const { return clock_; }
393 
394   // The current time (will use clock_ if it is non NULL).
395   base::Time Now();
396 
397  private:
398   int transaction_count_ = 0;
399   bool done_reading_called_ = false;
400   bool stop_caching_called_ = false;
401   RequestPriority last_create_transaction_priority_ = DEFAULT_PRIORITY;
402 
403   // By default clock_ is NULL but it can be set to a custom clock by test
404   // frameworks using SetClock.
405   raw_ptr<base::Clock> clock_ = nullptr;
406 
407   base::WeakPtr<MockNetworkTransaction> last_transaction_;
408 };
409 
410 //-----------------------------------------------------------------------------
411 // helpers
412 
413 // read the transaction completely
414 int ReadTransaction(HttpTransaction* trans, std::string* result);
415 
416 //-----------------------------------------------------------------------------
417 // connected callback handler
418 
419 // Used for injecting ConnectedCallback instances in HttpTransaction.
420 class ConnectedHandler {
421  public:
422   ConnectedHandler();
423   ~ConnectedHandler();
424 
425   // Instances of this class are copyable and efficiently movable.
426   // WARNING: Do not move an instance to which a callback is bound.
427   ConnectedHandler(const ConnectedHandler&);
428   ConnectedHandler& operator=(const ConnectedHandler&);
429   ConnectedHandler(ConnectedHandler&&);
430   ConnectedHandler& operator=(ConnectedHandler&&);
431 
432   // Returns a callback bound to this->OnConnected().
433   // The returned callback must not outlive this instance.
Callback()434   HttpTransaction::ConnectedCallback Callback() {
435     return base::BindRepeating(&ConnectedHandler::OnConnected,
436                                base::Unretained(this));
437   }
438 
439   // Compatible with HttpTransaction::ConnectedCallback.
440   // Returns the last value passed to set_result(), if any, OK otherwise.
441   int OnConnected(const TransportInfo& info, CompletionOnceCallback callback);
442 
443   // Returns the list of arguments with which OnConnected() was called.
444   // The arguments are listed in the same order as the calls were received.
transports()445   const std::vector<TransportInfo>& transports() const { return transports_; }
446 
447   // Sets the value to be returned by subsequent calls to OnConnected().
set_result(int result)448   void set_result(int result) { result_ = result; }
449 
450   // If true, runs the callback supplied to OnConnected asynchronously with
451   // `result_`. Otherwise, the callback is skipped and `result_` is returned
452   // directly.
set_run_callback(bool run_callback)453   void set_run_callback(bool run_callback) { run_callback_ = run_callback; }
454 
455  private:
456   std::vector<TransportInfo> transports_;
457   int result_ = OK;
458   bool run_callback_ = false;
459 };
460 
461 }  // namespace net
462 
463 #endif  // NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
464