1 // Copyright 2012 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_URL_REQUEST_URL_REQUEST_TEST_UTIL_H_ 6 #define NET_URL_REQUEST_URL_REQUEST_TEST_UTIL_H_ 7 8 #include <stdint.h> 9 #include <stdlib.h> 10 11 #include <map> 12 #include <memory> 13 #include <optional> 14 #include <string> 15 #include <utility> 16 #include <vector> 17 18 #include "base/compiler_specific.h" 19 #include "base/memory/raw_ptr.h" 20 #include "base/memory/scoped_refptr.h" 21 #include "base/path_service.h" 22 #include "base/strings/string_util.h" 23 #include "base/strings/utf_string_conversions.h" 24 #include "base/task/single_thread_task_runner.h" 25 #include "net/base/io_buffer.h" 26 #include "net/base/load_timing_info.h" 27 #include "net/base/net_errors.h" 28 #include "net/base/network_delegate_impl.h" 29 #include "net/base/request_priority.h" 30 #include "net/base/transport_info.h" 31 #include "net/cert/cert_verifier.h" 32 #include "net/cookies/cookie_inclusion_status.h" 33 #include "net/cookies/cookie_monster.h" 34 #include "net/cookies/cookie_setting_override.h" 35 #include "net/disk_cache/disk_cache.h" 36 #include "net/first_party_sets/first_party_set_metadata.h" 37 #include "net/http/http_auth_handler_factory.h" 38 #include "net/http/http_cache.h" 39 #include "net/http/http_network_layer.h" 40 #include "net/http/http_network_session.h" 41 #include "net/http/http_request_headers.h" 42 #include "net/ssl/ssl_config_service_defaults.h" 43 #include "net/test/embedded_test_server/default_handlers.h" 44 #include "net/test/embedded_test_server/embedded_test_server.h" 45 #include "net/test/embedded_test_server/embedded_test_server_connection_listener.h" 46 #include "net/url_request/redirect_info.h" 47 #include "net/url_request/url_request.h" 48 #include "net/url_request/url_request_context.h" 49 #include "net/url_request/url_request_context_getter.h" 50 #include "net/url_request/url_request_interceptor.h" 51 #include "url/url_util.h" 52 53 namespace net { 54 55 class URLRequestContextBuilder; 56 57 //----------------------------------------------------------------------------- 58 59 // Creates a URLRequestContextBuilder with some members configured for the 60 // testing purpose. 61 std::unique_ptr<URLRequestContextBuilder> CreateTestURLRequestContextBuilder(); 62 63 //----------------------------------------------------------------------------- 64 // Used to return a dummy context, which lives on the message loop 65 // given in the constructor. 66 class TestURLRequestContextGetter : public URLRequestContextGetter { 67 public: 68 // |network_task_runner| must not be NULL. 69 explicit TestURLRequestContextGetter( 70 const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner); 71 72 // Use to pass a pre-initialized |context|. 73 TestURLRequestContextGetter( 74 const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner, 75 std::unique_ptr<URLRequestContext> context); 76 77 // URLRequestContextGetter implementation. 78 URLRequestContext* GetURLRequestContext() override; 79 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() 80 const override; 81 82 // see NotifyContextShuttingDown() in the base class. 83 void NotifyContextShuttingDown(); 84 85 protected: 86 ~TestURLRequestContextGetter() override; 87 88 private: 89 const scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; 90 std::unique_ptr<URLRequestContext> context_; 91 bool is_shut_down_ = false; 92 }; 93 94 //----------------------------------------------------------------------------- 95 96 class TestDelegate : public URLRequest::Delegate { 97 public: 98 TestDelegate(); 99 ~TestDelegate() override; 100 101 // Helpers to create a RunLoop, set |on_<event>| from it, then Run() it. 102 void RunUntilComplete(); 103 void RunUntilRedirect(); 104 // Enables quitting the message loop in response to auth requests, as opposed 105 // to returning credentials or cancelling the request. 106 void RunUntilAuthRequired(); 107 108 // Sets the closure to be run on completion, for tests which need more fine- 109 // grained control than RunUntilComplete(). set_on_complete(base::OnceClosure on_complete)110 void set_on_complete(base::OnceClosure on_complete) { 111 on_complete_ = std::move(on_complete); 112 } 113 114 // Sets the result returned by subsequent calls to OnConnected(). set_on_connected_result(int result)115 void set_on_connected_result(int result) { on_connected_result_ = result; } 116 set_cancel_in_received_redirect(bool val)117 void set_cancel_in_received_redirect(bool val) { cancel_in_rr_ = val; } set_cancel_in_response_started(bool val)118 void set_cancel_in_response_started(bool val) { cancel_in_rs_ = val; } set_cancel_in_received_data(bool val)119 void set_cancel_in_received_data(bool val) { cancel_in_rd_ = val; } set_cancel_in_received_data_pending(bool val)120 void set_cancel_in_received_data_pending(bool val) { 121 cancel_in_rd_pending_ = val; 122 } 123 set_allow_certificate_errors(bool val)124 void set_allow_certificate_errors(bool val) { 125 allow_certificate_errors_ = val; 126 } set_credentials(const AuthCredentials & credentials)127 void set_credentials(const AuthCredentials& credentials) { 128 credentials_ = credentials; 129 } 130 131 // If true, the delegate will asynchronously run the callback passed in from 132 // URLRequest with `on_connected_result_` set_on_connected_run_callback(bool run_callback)133 void set_on_connected_run_callback(bool run_callback) { 134 on_connected_run_callback_ = run_callback; 135 } 136 137 // Returns the list of arguments with which OnConnected() was called. 138 // The arguments are listed in the same order as the calls were received. transports()139 const std::vector<TransportInfo>& transports() const { return transports_; } 140 141 // query state data_received()142 const std::string& data_received() const { return data_received_; } bytes_received()143 int bytes_received() const { return static_cast<int>(data_received_.size()); } response_started_count()144 int response_started_count() const { return response_started_count_; } received_bytes_count()145 int received_bytes_count() const { return received_bytes_count_; } received_redirect_count()146 int received_redirect_count() const { return received_redirect_count_; } received_data_before_response()147 bool received_data_before_response() const { 148 return received_data_before_response_; 149 } redirect_info()150 RedirectInfo redirect_info() { return redirect_info_; } request_failed()151 bool request_failed() const { return request_failed_; } have_certificate_errors()152 bool have_certificate_errors() const { return have_certificate_errors_; } certificate_errors_are_fatal()153 bool certificate_errors_are_fatal() const { 154 return certificate_errors_are_fatal_; 155 } certificate_net_error()156 int certificate_net_error() const { return certificate_net_error_; } auth_required_called()157 bool auth_required_called() const { return auth_required_; } response_completed()158 bool response_completed() const { return response_completed_; } request_status()159 int request_status() const { return request_status_; } 160 161 // URLRequest::Delegate: 162 int OnConnected(URLRequest* request, 163 const TransportInfo& info, 164 CompletionOnceCallback callback) override; 165 void OnReceivedRedirect(URLRequest* request, 166 const RedirectInfo& redirect_info, 167 bool* defer_redirect) override; 168 void OnAuthRequired(URLRequest* request, 169 const AuthChallengeInfo& auth_info) override; 170 // NOTE: |fatal| causes |certificate_errors_are_fatal_| to be set to true. 171 // (Unit tests use this as a post-condition.) But for policy, this method 172 // consults |allow_certificate_errors_|. 173 void OnSSLCertificateError(URLRequest* request, 174 int net_error, 175 const SSLInfo& ssl_info, 176 bool fatal) override; 177 void OnResponseStarted(URLRequest* request, int net_error) override; 178 void OnReadCompleted(URLRequest* request, int bytes_read) override; 179 180 private: 181 static const int kBufferSize = 4096; 182 183 virtual void OnResponseCompleted(URLRequest* request); 184 185 // options for controlling behavior 186 int on_connected_result_ = OK; 187 bool cancel_in_rr_ = false; 188 bool cancel_in_rs_ = false; 189 bool cancel_in_rd_ = false; 190 bool cancel_in_rd_pending_ = false; 191 bool allow_certificate_errors_ = false; 192 AuthCredentials credentials_; 193 194 // Used to register RunLoop quit closures, to implement the Until*() closures. 195 base::OnceClosure on_complete_; 196 base::OnceClosure on_redirect_; 197 base::OnceClosure on_auth_required_; 198 199 // tracks status of callbacks 200 std::vector<TransportInfo> transports_; 201 int response_started_count_ = 0; 202 int received_bytes_count_ = 0; 203 int received_redirect_count_ = 0; 204 bool received_data_before_response_ = false; 205 bool request_failed_ = false; 206 bool have_certificate_errors_ = false; 207 bool certificate_errors_are_fatal_ = false; 208 int certificate_net_error_ = 0; 209 bool auth_required_ = false; 210 std::string data_received_; 211 bool response_completed_ = false; 212 213 // tracks status of request 214 int request_status_ = ERR_IO_PENDING; 215 216 // our read buffer 217 scoped_refptr<IOBuffer> buf_; 218 219 RedirectInfo redirect_info_; 220 221 bool on_connected_run_callback_ = false; 222 }; 223 224 //----------------------------------------------------------------------------- 225 226 class TestNetworkDelegate : public NetworkDelegateImpl { 227 public: 228 enum Options { 229 NO_GET_COOKIES = 1 << 0, 230 NO_SET_COOKIE = 1 << 1, 231 }; 232 233 TestNetworkDelegate(); 234 ~TestNetworkDelegate() override; 235 236 // Writes the LoadTimingInfo during the most recent call to OnBeforeRedirect. 237 bool GetLoadTimingInfoBeforeRedirect( 238 LoadTimingInfo* load_timing_info_before_redirect) const; 239 240 // Will redirect once to the given URL when the next set of headers are 241 // received. set_redirect_on_headers_received_url(GURL redirect_on_headers_received_url)242 void set_redirect_on_headers_received_url( 243 GURL redirect_on_headers_received_url) { 244 redirect_on_headers_received_url_ = redirect_on_headers_received_url; 245 } 246 247 // Adds a X-Network-Delegate header to the first OnHeadersReceived call, but 248 // not subsequent ones. set_add_header_to_first_response(bool add_header_to_first_response)249 void set_add_header_to_first_response(bool add_header_to_first_response) { 250 add_header_to_first_response_ = add_header_to_first_response; 251 } 252 set_preserve_fragment_on_redirect_url(const std::optional<GURL> & preserve_fragment_on_redirect_url)253 void set_preserve_fragment_on_redirect_url( 254 const std::optional<GURL>& preserve_fragment_on_redirect_url) { 255 preserve_fragment_on_redirect_url_ = preserve_fragment_on_redirect_url; 256 } 257 set_cookie_options(int o)258 void set_cookie_options(int o) {cookie_options_bit_mask_ = o; } 259 last_error()260 int last_error() const { return last_error_; } error_count()261 int error_count() const { return error_count_; } created_requests()262 int created_requests() const { return created_requests_; } destroyed_requests()263 int destroyed_requests() const { return destroyed_requests_; } completed_requests()264 int completed_requests() const { return completed_requests_; } canceled_requests()265 int canceled_requests() const { return canceled_requests_; } blocked_annotate_cookies_count()266 int blocked_annotate_cookies_count() const { 267 return blocked_annotate_cookies_count_; 268 } blocked_set_cookie_count()269 int blocked_set_cookie_count() const { return blocked_set_cookie_count_; } set_cookie_count()270 int set_cookie_count() const { return set_cookie_count_; } 271 set_cancel_request_with_policy_violating_referrer(bool val)272 void set_cancel_request_with_policy_violating_referrer(bool val) { 273 cancel_request_with_policy_violating_referrer_ = val; 274 } 275 before_start_transaction_count()276 int before_start_transaction_count() const { 277 return before_start_transaction_count_; 278 } 279 headers_received_count()280 int headers_received_count() const { return headers_received_count_; } 281 set_before_start_transaction_fails()282 void set_before_start_transaction_fails() { 283 before_start_transaction_fails_ = true; 284 } 285 cookie_setting_overrides_records()286 const std::vector<CookieSettingOverrides>& cookie_setting_overrides_records() 287 const { 288 return cookie_setting_overrides_records_; 289 } 290 291 protected: 292 // NetworkDelegate: 293 int OnBeforeURLRequest(URLRequest* request, 294 CompletionOnceCallback callback, 295 GURL* new_url) override; 296 int OnBeforeStartTransaction( 297 URLRequest* request, 298 const HttpRequestHeaders& headers, 299 OnBeforeStartTransactionCallback callback) override; 300 int OnHeadersReceived( 301 URLRequest* request, 302 CompletionOnceCallback callback, 303 const HttpResponseHeaders* original_response_headers, 304 scoped_refptr<HttpResponseHeaders>* override_response_headers, 305 const IPEndPoint& endpoint, 306 std::optional<GURL>* preserve_fragment_on_redirect_url) override; 307 void OnBeforeRedirect(URLRequest* request, const GURL& new_location) override; 308 void OnResponseStarted(URLRequest* request, int net_error) override; 309 void OnCompleted(URLRequest* request, bool started, int net_error) override; 310 void OnURLRequestDestroyed(URLRequest* request) override; 311 bool OnAnnotateAndMoveUserBlockedCookies( 312 const URLRequest& request, 313 const net::FirstPartySetMetadata& first_party_set_metadata, 314 net::CookieAccessResultList& maybe_included_cookies, 315 net::CookieAccessResultList& excluded_cookies) override; 316 NetworkDelegate::PrivacySetting OnForcePrivacyMode( 317 const URLRequest& request) const override; 318 bool OnCanSetCookie( 319 const URLRequest& request, 320 const net::CanonicalCookie& cookie, 321 CookieOptions* options, 322 const net::FirstPartySetMetadata& first_party_set_metadata, 323 CookieInclusionStatus* inclusion_status) override; 324 bool OnCancelURLRequestWithPolicyViolatingReferrerHeader( 325 const URLRequest& request, 326 const GURL& target_url, 327 const GURL& referrer_url) const override; 328 329 void InitRequestStatesIfNew(int request_id); 330 331 // Gets a request ID if it already has one, assigns a new one and returns that 332 // if not. 333 int GetRequestId(URLRequest* request); 334 RecordCookieSettingOverrides(CookieSettingOverrides overrides)335 void RecordCookieSettingOverrides(CookieSettingOverrides overrides) const { 336 cookie_setting_overrides_records_.push_back(overrides); 337 } 338 339 GURL redirect_on_headers_received_url_; 340 // URL to mark as retaining its fragment if redirected to at the 341 // OnHeadersReceived() stage. 342 std::optional<GURL> preserve_fragment_on_redirect_url_; 343 344 int last_error_ = 0; 345 int error_count_ = 0; 346 int created_requests_ = 0; 347 int destroyed_requests_ = 0; 348 int completed_requests_ = 0; 349 int canceled_requests_ = 0; 350 int cookie_options_bit_mask_ = 0; 351 int blocked_annotate_cookies_count_ = 0; 352 int blocked_set_cookie_count_ = 0; 353 int set_cookie_count_ = 0; 354 int before_start_transaction_count_ = 0; 355 int headers_received_count_ = 0; 356 357 // NetworkDelegate callbacks happen in a particular order (e.g. 358 // OnBeforeURLRequest is always called before OnBeforeStartTransaction). 359 // This bit-set indicates for each request id (key) what events may be sent 360 // next. 361 std::map<int, int> next_states_; 362 363 // A log that records for each request id (key) the order in which On... 364 // functions were called. 365 std::map<int, std::string> event_order_; 366 367 LoadTimingInfo load_timing_info_before_redirect_; 368 bool has_load_timing_info_before_redirect_ = false; 369 370 bool cancel_request_with_policy_violating_referrer_ = 371 false; // false by default 372 bool before_start_transaction_fails_ = false; 373 bool add_header_to_first_response_ = false; 374 int next_request_id_ = 0; 375 376 mutable std::vector<CookieSettingOverrides> cookie_setting_overrides_records_; 377 }; 378 379 // ---------------------------------------------------------------------------- 380 381 class FilteringTestNetworkDelegate : public TestNetworkDelegate { 382 public: 383 FilteringTestNetworkDelegate(); 384 ~FilteringTestNetworkDelegate() override; 385 386 bool OnCanSetCookie( 387 const URLRequest& request, 388 const net::CanonicalCookie& cookie, 389 CookieOptions* options, 390 const net::FirstPartySetMetadata& first_party_set_metadata, 391 CookieInclusionStatus* inclusion_status) override; 392 SetCookieFilter(std::string filter)393 void SetCookieFilter(std::string filter) { 394 cookie_name_filter_ = std::move(filter); 395 } 396 set_cookie_called_count()397 int set_cookie_called_count() { return set_cookie_called_count_; } 398 blocked_set_cookie_count()399 int blocked_set_cookie_count() { return blocked_set_cookie_count_; } 400 ResetSetCookieCalledCount()401 void ResetSetCookieCalledCount() { set_cookie_called_count_ = 0; } 402 ResetBlockedSetCookieCount()403 void ResetBlockedSetCookieCount() { blocked_set_cookie_count_ = 0; } 404 405 bool OnAnnotateAndMoveUserBlockedCookies( 406 const URLRequest& request, 407 const net::FirstPartySetMetadata& first_party_set_metadata, 408 net::CookieAccessResultList& maybe_included_cookies, 409 net::CookieAccessResultList& excluded_cookies) override; 410 411 NetworkDelegate::PrivacySetting OnForcePrivacyMode( 412 const URLRequest& request) const override; 413 set_block_annotate_cookies()414 void set_block_annotate_cookies() { block_annotate_cookies_ = true; } 415 unset_block_annotate_cookies()416 void unset_block_annotate_cookies() { block_annotate_cookies_ = false; } 417 annotate_cookies_called_count()418 int annotate_cookies_called_count() const { 419 return annotate_cookies_called_count_; 420 } 421 blocked_annotate_cookies_count()422 int blocked_annotate_cookies_count() const { 423 return blocked_annotate_cookies_count_; 424 } 425 ResetAnnotateCookiesCalledCount()426 void ResetAnnotateCookiesCalledCount() { annotate_cookies_called_count_ = 0; } 427 ResetBlockedAnnotateCookiesCount()428 void ResetBlockedAnnotateCookiesCount() { 429 blocked_annotate_cookies_count_ = 0; 430 } 431 set_block_get_cookies_by_name(bool block)432 void set_block_get_cookies_by_name(bool block) { 433 block_get_cookies_by_name_ = block; 434 } 435 set_force_privacy_mode(bool enabled)436 void set_force_privacy_mode(bool enabled) { force_privacy_mode_ = enabled; } 437 set_partitioned_state_allowed(bool allowed)438 void set_partitioned_state_allowed(bool allowed) { 439 partitioned_state_allowed_ = allowed; 440 } 441 442 private: 443 std::string cookie_name_filter_ = ""; 444 int set_cookie_called_count_ = 0; 445 int blocked_set_cookie_count_ = 0; 446 447 bool block_annotate_cookies_ = false; 448 int annotate_cookies_called_count_ = 0; 449 int blocked_annotate_cookies_count_ = 0; 450 bool block_get_cookies_by_name_ = false; 451 452 bool force_privacy_mode_ = false; 453 bool partitioned_state_allowed_ = false; 454 }; 455 456 // ---------------------------------------------------------------------------- 457 458 // Less verbose way of running a simple testserver. 459 class HttpTestServer : public EmbeddedTestServer { 460 public: HttpTestServer(const base::FilePath & document_root)461 explicit HttpTestServer(const base::FilePath& document_root) { 462 AddDefaultHandlers(document_root); 463 } 464 HttpTestServer()465 HttpTestServer() { RegisterDefaultHandlers(this); } 466 }; 467 //----------------------------------------------------------------------------- 468 469 class TestScopedURLInterceptor { 470 public: 471 // Sets up a URLRequestInterceptor that intercepts a single request for |url|, 472 // returning the provided job. 473 // 474 // On destruction, cleans makes sure the job was removed, and cleans up the 475 // interceptor. Other interceptors for the same URL may not be created until 476 // the interceptor is deleted. 477 TestScopedURLInterceptor(const GURL& url, 478 std::unique_ptr<URLRequestJob> intercept_job); 479 ~TestScopedURLInterceptor(); 480 481 private: 482 class TestRequestInterceptor; 483 484 GURL url_; 485 486 // This is owned by the URLFilter. 487 raw_ptr<TestRequestInterceptor> interceptor_ = nullptr; 488 }; 489 490 } // namespace net 491 492 #endif // NET_URL_REQUEST_URL_REQUEST_TEST_UTIL_H_ 493