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