url_loader_post_interceptor.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_UPDATE_CLIENT_NET_URL_LOADER_POST_INTERCEPTOR_H_
  5. #define COMPONENTS_UPDATE_CLIENT_NET_URL_LOADER_POST_INTERCEPTOR_H_
  6. #include <memory>
  7. #include <string>
  8. #include <tuple>
  9. #include <utility>
  10. #include <vector>
  11. #include "base/callback.h"
  12. #include "base/containers/queue.h"
  13. #include "base/files/file_path.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "net/http/http_request_headers.h"
  16. #include "net/http/http_status_code.h"
  17. #include "url/gurl.h"
  18. namespace network {
  19. class TestURLLoaderFactory;
  20. }
  21. namespace net {
  22. namespace test_server {
  23. class EmbeddedTestServer;
  24. class HttpResponse;
  25. struct HttpRequest;
  26. } // namespace test_server
  27. } // namespace net
  28. namespace update_client {
  29. // Intercepts requests to a file path, counts them, and captures the body of
  30. // the requests. Optionally, for each request, it can return a canned response
  31. // from a given file. The class maintains a queue of expectations, and returns
  32. // one and only one response for each request that matches the expectation.
  33. // Then, the expectation is removed from the queue.
  34. class URLLoaderPostInterceptor {
  35. public:
  36. using InterceptedRequest =
  37. std::tuple<std::string, net::HttpRequestHeaders, GURL>;
  38. // Called when the load associated with the url request is intercepted
  39. // by this object:.
  40. using UrlJobRequestReadyCallback = base::OnceCallback<void()>;
  41. // Allows a generic string maching interface when setting up expectations.
  42. class RequestMatcher {
  43. public:
  44. virtual bool Match(const std::string& actual) const = 0;
  45. virtual ~RequestMatcher() = default;
  46. };
  47. explicit URLLoaderPostInterceptor(
  48. network::TestURLLoaderFactory* url_loader_factory);
  49. URLLoaderPostInterceptor(std::vector<GURL> supported_urls,
  50. network::TestURLLoaderFactory* url_loader_factory);
  51. URLLoaderPostInterceptor(std::vector<GURL> supported_urls,
  52. net::test_server::EmbeddedTestServer*);
  53. URLLoaderPostInterceptor(const URLLoaderPostInterceptor&) = delete;
  54. URLLoaderPostInterceptor& operator=(const URLLoaderPostInterceptor&) = delete;
  55. ~URLLoaderPostInterceptor();
  56. // Sets an expection for the body of the POST request and optionally,
  57. // provides a canned response identified by a |file_path| to be returned when
  58. // the expectation is met. If no |file_path| is provided, then an empty
  59. // response body is served. If |response_code| is provided, then an empty
  60. // response body with that response code is returned.
  61. // Returns |true| if the expectation was set.
  62. bool ExpectRequest(std::unique_ptr<RequestMatcher> request_matcher);
  63. bool ExpectRequest(std::unique_ptr<RequestMatcher> request_matcher,
  64. net::HttpStatusCode response_code);
  65. bool ExpectRequest(std::unique_ptr<RequestMatcher> request_matcher,
  66. const base::FilePath& filepath);
  67. // Returns how many requests have been intercepted and matched by
  68. // an expectation. One expectation can only be matched by one request.
  69. int GetHitCount() const;
  70. // Returns how many requests in total have been captured by the interceptor.
  71. int GetCount() const;
  72. // Returns all requests that have been intercepted, matched or not.
  73. std::vector<InterceptedRequest> GetRequests() const;
  74. // Return the body of the n-th request, zero-based.
  75. std::string GetRequestBody(size_t n) const;
  76. // Returns the joined bodies of all requests for debugging purposes.
  77. std::string GetRequestsAsString() const;
  78. // Resets the state of the interceptor so that new expectations can be set.
  79. void Reset();
  80. // Prevents the intercepted request from starting, as a way to simulate
  81. // the effects of a very slow network. Call this function before the actual
  82. // network request occurs.
  83. void Pause();
  84. // Allows a previously paused request to continue.
  85. void Resume();
  86. // Sets a callback to be invoked when the request job associated with
  87. // an intercepted request is created. This allows the test execution to
  88. // synchronize with network tasks running on the IO thread and avoid polling
  89. // using idle run loops. A paused request can be resumed after this callback
  90. // has been invoked.
  91. void url_job_request_ready_callback(
  92. UrlJobRequestReadyCallback url_job_request_ready_callback);
  93. int GetHitCountForURL(const GURL& url);
  94. private:
  95. void InitializeWithInterceptor();
  96. void InitializeWithRequestHandler();
  97. std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
  98. const net::test_server::HttpRequest& request);
  99. struct ExpectationResponse {
  100. ExpectationResponse(net::HttpStatusCode code, const std::string& body)
  101. : response_code(code), response_body(body) {}
  102. const net::HttpStatusCode response_code;
  103. const std::string response_body;
  104. };
  105. using Expectation =
  106. std::pair<std::unique_ptr<RequestMatcher>, ExpectationResponse>;
  107. using PendingExpectation = std::pair<GURL, ExpectationResponse>;
  108. // Contains the count of the request matching expectations.
  109. int hit_count_ = 0;
  110. // Contains the request body and the extra headers of the intercepted
  111. // requests.
  112. std::vector<InterceptedRequest> requests_;
  113. // Contains the expectations which this interceptor tries to match.
  114. base::queue<Expectation> expectations_;
  115. base::queue<PendingExpectation> pending_expectations_;
  116. raw_ptr<network::TestURLLoaderFactory> url_loader_factory_ = nullptr;
  117. raw_ptr<net::test_server::EmbeddedTestServer> embedded_test_server_ = nullptr;
  118. bool is_paused_ = false;
  119. std::vector<GURL> filtered_urls_;
  120. UrlJobRequestReadyCallback url_job_request_ready_callback_;
  121. };
  122. class PartialMatch : public URLLoaderPostInterceptor::RequestMatcher {
  123. public:
  124. explicit PartialMatch(const std::string& expected) : expected_(expected) {}
  125. PartialMatch(const PartialMatch&) = delete;
  126. PartialMatch& operator=(const PartialMatch&) = delete;
  127. bool Match(const std::string& actual) const override;
  128. private:
  129. const std::string expected_;
  130. };
  131. class AnyMatch : public URLLoaderPostInterceptor::RequestMatcher {
  132. public:
  133. AnyMatch() = default;
  134. AnyMatch(const AnyMatch&) = delete;
  135. AnyMatch& operator=(const AnyMatch&) = delete;
  136. bool Match(const std::string& actual) const override;
  137. };
  138. } // namespace update_client
  139. #endif // COMPONENTS_UPDATE_CLIENT_NET_URL_LOADER_POST_INTERCEPTOR_H_