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