• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 final : public HttpTransaction {
186   typedef WebSocketHandshakeStreamBase::CreateHelper CreateHelper;
187 
188  public:
189   MockNetworkTransaction(RequestPriority priority, MockNetworkLayer* factory);
190   ~MockNetworkTransaction() override;
191 
192   int Start(const HttpRequestInfo* request,
193             CompletionOnceCallback callback,
194             const NetLogWithSource& net_log) override;
195 
196   int RestartIgnoringLastError(CompletionOnceCallback callback) override;
197 
198   int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert,
199                              scoped_refptr<SSLPrivateKey> client_private_key,
200                              CompletionOnceCallback callback) override;
201 
202   int RestartWithAuth(const AuthCredentials& credentials,
203                       CompletionOnceCallback callback) override;
204 
205   bool IsReadyToRestartForAuth() override;
206 
207   int Read(IOBuffer* buf,
208            int buf_len,
209            CompletionOnceCallback callback) override;
210   void PopulateNetErrorDetails(NetErrorDetails* details) const override;
211 
212   void StopCaching() override;
213 
214   int64_t GetTotalReceivedBytes() const override;
215 
216   int64_t GetTotalSentBytes() const override;
217 
218   int64_t GetReceivedBodyBytes() 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(HttpRequestHeaders*)> callback) override;
248 
SetIsSharedDictionaryReadAllowedCallback(base::RepeatingCallback<bool ()> callback)249   void SetIsSharedDictionaryReadAllowedCallback(
250       base::RepeatingCallback<bool()> callback) override {}
251 
252   int ResumeNetworkStart() override;
253 
254   ConnectionAttempts GetConnectionAttempts() const override;
255 
256   void CloseConnectionOnDestruction() override;
257   bool IsMdlMatchForMetrics() const override;
258 
websocket_handshake_stream_create_helper()259   CreateHelper* websocket_handshake_stream_create_helper() {
260     return websocket_handshake_stream_create_helper_;
261   }
262 
priority()263   RequestPriority priority() const { return priority_; }
264 
AsWeakPtr()265   base::WeakPtr<MockNetworkTransaction> AsWeakPtr() {
266     return weak_factory_.GetWeakPtr();
267   }
268 
269   // Bogus value that will be returned by GetTotalReceivedBytes() if the
270   // MockNetworkTransaction was started.
271   static const int64_t kTotalReceivedBytes;
272   // Bogus value that will be returned by GetTotalSentBytes() if the
273   // MockNetworkTransaction was started.
274   static const int64_t kTotalSentBytes;
275   // Bogus value that will be returned by GetReceivedBodyBytes() if the
276   // MockNetworkTransaction was started.
277   static const int64_t kReceivedBodyBytes;
278 
279  private:
280   enum class State {
281     NOTIFY_BEFORE_CREATE_STREAM,
282     CREATE_STREAM,
283     CREATE_STREAM_COMPLETE,
284     CONNECTED_CALLBACK,
285     CONNECTED_CALLBACK_COMPLETE,
286     BUILD_REQUEST,
287     BUILD_REQUEST_COMPLETE,
288     SEND_REQUEST,
289     SEND_REQUEST_COMPLETE,
290     READ_HEADERS,
291     READ_HEADERS_COMPLETE,
292     NONE
293   };
294 
295   int StartInternal(HttpRequestInfo request, CompletionOnceCallback callback);
296   int DoNotifyBeforeCreateStream();
297   int DoCreateStream();
298   int DoCreateStreamComplete(int result);
299   int DoConnectedCallback();
300   int DoConnectedCallbackComplete(int result);
301   int DoBuildRequest();
302   int DoBuildRequestComplete(int result);
303   int DoSendRequest();
304   int DoSendRequestComplete(int result);
305   int DoReadHeaders();
306   int DoReadHeadersComplete(int result);
307 
308   // Runs the state transition loop.
309   int DoLoop(int result);
310 
311   void OnIOComplete(int result);
312 
313   void CallbackLater(CompletionOnceCallback callback, int result);
314   void RunCallback(CompletionOnceCallback callback, int result);
315 
316   raw_ptr<const HttpRequestInfo> original_request_ptr_ = nullptr;
317   HttpRequestInfo current_request_;
318   State next_state_ = State::NONE;
319   NetLogWithSource net_log_;
320 
321   CompletionOnceCallback callback_;
322 
323   HttpResponseInfo response_;
324   std::string data_;
325   int64_t data_cursor_ = 0;
326   int64_t content_length_ = 0;
327   int test_mode_;
328   RequestPriority priority_;
329   raw_ptr<CreateHelper> websocket_handshake_stream_create_helper_ = nullptr;
330   BeforeNetworkStartCallback before_network_start_callback_;
331   ConnectedCallback connected_callback_;
332   base::WeakPtr<MockNetworkLayer> transaction_factory_;
333   int64_t received_bytes_ = 0;
334   int64_t sent_bytes_ = 0;
335   int64_t received_body_bytes_ = 0;
336 
337   // NetLog ID of the fake / non-existent underlying socket used by the
338   // connection. Requires Start() be passed a NetLogWithSource with a real
339   // NetLog to
340   // be initialized.
341   unsigned int socket_log_id_ = NetLogSource::kInvalidId;
342 
343   bool done_reading_called_ = false;
344   bool reading_ = false;
345 
346   CompletionOnceCallback resume_start_callback_;  // used for pause and restart.
347 
348   base::RepeatingCallback<void(HttpRequestHeaders*)>
349       modify_request_headers_callback_;
350 
351   base::WeakPtrFactory<MockNetworkTransaction> weak_factory_{this};
352 };
353 
354 class MockNetworkLayer final : public HttpTransactionFactory {
355  public:
356   MockNetworkLayer();
357   ~MockNetworkLayer() override;
358 
transaction_count()359   int transaction_count() const { return transaction_count_; }
done_reading_called()360   bool done_reading_called() const { return done_reading_called_; }
stop_caching_called()361   bool stop_caching_called() const { return stop_caching_called_; }
362   void TransactionDoneReading();
363   void TransactionStopCaching();
364 
365   // Resets the transaction count. Can be called after test setup in order to
366   // make test expectations independent of how test setup is performed.
367   void ResetTransactionCount();
368 
369   // Returns the last priority passed to CreateTransaction, or
370   // DEFAULT_PRIORITY if it hasn't been called yet.
last_create_transaction_priority()371   RequestPriority last_create_transaction_priority() const {
372     return last_create_transaction_priority_;
373   }
374 
375   // Returns the last transaction created by
376   // CreateTransaction. Returns a NULL WeakPtr if one has not been
377   // created yet, or the last transaction has been destroyed, or
378   // ClearLastTransaction() has been called and a new transaction
379   // hasn't been created yet.
last_transaction()380   base::WeakPtr<MockNetworkTransaction> last_transaction() {
381     return last_transaction_;
382   }
383 
384   // Makes last_transaction() return NULL until the next transaction
385   // is created.
ClearLastTransaction()386   void ClearLastTransaction() {
387     last_transaction_.reset();
388   }
389 
390   // HttpTransactionFactory:
391   int CreateTransaction(RequestPriority priority,
392                         std::unique_ptr<HttpTransaction>* trans) override;
393   HttpCache* GetCache() override;
394   HttpNetworkSession* GetSession() override;
395 
396   // The caller must guarantee that |clock| will outlive this object.
397   void SetClock(base::Clock* clock);
clock()398   base::Clock* clock() const { return clock_; }
399 
400   // The current time (will use clock_ if it is non NULL).
401   base::Time Now();
402 
AsWeakPtr()403   base::WeakPtr<MockNetworkLayer> AsWeakPtr() {
404     return weak_factory_.GetWeakPtr();
405   }
406 
407  private:
408   int transaction_count_ = 0;
409   bool done_reading_called_ = false;
410   bool stop_caching_called_ = false;
411   RequestPriority last_create_transaction_priority_ = DEFAULT_PRIORITY;
412 
413   // By default clock_ is NULL but it can be set to a custom clock by test
414   // frameworks using SetClock.
415   raw_ptr<base::Clock> clock_ = nullptr;
416 
417   base::WeakPtr<MockNetworkTransaction> last_transaction_;
418 
419   base::WeakPtrFactory<MockNetworkLayer> weak_factory_{this};
420 };
421 
422 //-----------------------------------------------------------------------------
423 // helpers
424 
425 // read the transaction completely
426 int ReadTransaction(HttpTransaction* trans, std::string* result);
427 
428 //-----------------------------------------------------------------------------
429 // connected callback handler
430 
431 // Used for injecting ConnectedCallback instances in HttpTransaction.
432 class ConnectedHandler {
433  public:
434   ConnectedHandler();
435   ~ConnectedHandler();
436 
437   // Instances of this class are copyable and efficiently movable.
438   // WARNING: Do not move an instance to which a callback is bound.
439   ConnectedHandler(const ConnectedHandler&);
440   ConnectedHandler& operator=(const ConnectedHandler&);
441   ConnectedHandler(ConnectedHandler&&);
442   ConnectedHandler& operator=(ConnectedHandler&&);
443 
444   // Returns a callback bound to this->OnConnected().
445   // The returned callback must not outlive this instance.
Callback()446   HttpTransaction::ConnectedCallback Callback() {
447     return base::BindRepeating(&ConnectedHandler::OnConnected,
448                                base::Unretained(this));
449   }
450 
451   // Compatible with HttpTransaction::ConnectedCallback.
452   // Returns the last value passed to set_result(), if any, OK otherwise.
453   int OnConnected(const TransportInfo& info, CompletionOnceCallback callback);
454 
455   // Returns the list of arguments with which OnConnected() was called.
456   // The arguments are listed in the same order as the calls were received.
transports()457   const std::vector<TransportInfo>& transports() const { return transports_; }
458 
459   // Sets the value to be returned by subsequent calls to OnConnected().
set_result(int result)460   void set_result(int result) { result_ = result; }
461 
462   // If true, runs the callback supplied to OnConnected asynchronously with
463   // `result_`. Otherwise, the callback is skipped and `result_` is returned
464   // directly.
set_run_callback(bool run_callback)465   void set_run_callback(bool run_callback) { run_callback_ = run_callback; }
466 
467  private:
468   std::vector<TransportInfo> transports_;
469   int result_ = OK;
470   bool run_callback_ = false;
471 };
472 
473 }  // namespace net
474 
475 #endif  // NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
476