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