1 // Copyright 2013 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 5 #ifndef COMPONENTS_COMPONENT_UPDATER_TEST_URL_REQUEST_POST_INTERCEPTOR_H_ 6 #define COMPONENTS_COMPONENT_UPDATER_TEST_URL_REQUEST_POST_INTERCEPTOR_H_ 7 8 #include <stdint.h> 9 #include <map> 10 #include <queue> 11 #include <string> 12 #include <utility> 13 #include <vector> 14 15 #include "base/macros.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/synchronization/lock.h" 18 #include "url/gurl.h" 19 20 namespace base { 21 class FilePath; 22 class SequencedTaskRunner; 23 } 24 25 namespace net { 26 class URLRequest; 27 } 28 29 namespace component_updater { 30 31 // component 1 has extension id "jebgalgnebhfojomionfpkfelancnnkf", and 32 // the RSA public key the following hash: 33 const uint8_t jebg_hash[] = {0x94, 0x16, 0x0b, 0x6d, 0x41, 0x75, 0xe9, 0xec, 34 0x8e, 0xd5, 0xfa, 0x54, 0xb0, 0xd2, 0xdd, 0xa5, 35 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47, 0xf6, 0xc4, 36 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40}; 37 // component 2 has extension id "abagagagagagagagagagagagagagagag", and 38 // the RSA public key the following hash: 39 const uint8_t abag_hash[] = {0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 40 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 41 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 42 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01}; 43 // component 3 has extension id "ihfokbkgjpifnbbojhneepfflplebdkc", and 44 // the RSA public key the following hash: 45 const uint8_t ihfo_hash[] = {0x87, 0x5e, 0xa1, 0xa6, 0x9f, 0x85, 0xd1, 0x1e, 46 0x97, 0xd4, 0x4f, 0x55, 0xbf, 0xb4, 0x13, 0xa2, 47 0xe7, 0xc5, 0xc8, 0xf5, 0x60, 0x19, 0x78, 0x1b, 48 0x6d, 0xe9, 0x4c, 0xeb, 0x96, 0x05, 0x42, 0x17}; 49 50 // Intercepts requests to a file path, counts them, and captures the body of 51 // the requests. Optionally, for each request, it can return a canned response 52 // from a given file. The class maintains a queue of expectations, and returns 53 // one and only one response for each request that matches and it is 54 // intercepted. 55 class URLRequestPostInterceptor { 56 public: 57 // Allows a generic string maching interface when setting up expectations. 58 class RequestMatcher { 59 public: 60 virtual bool Match(const std::string& actual) const = 0; 61 virtual ~RequestMatcher() {} 62 }; 63 64 // Returns the url that is intercepted. 65 GURL GetUrl() const; 66 67 // Sets an expection for the body of the POST request and optionally, 68 // provides a canned response identified by a |file_path| to be returned when 69 // the expectation is met. If no |file_path| is provided, then an empty 70 // response body is served. If |response_code| is provided, then an empty 71 // response body with that response code is returned. 72 // Returns |true| if the expectation was set. This class takes ownership of 73 // the |request_matcher| object. 74 bool ExpectRequest(class RequestMatcher* request_matcher); 75 bool ExpectRequest(class RequestMatcher* request_matcher, int response_code); 76 bool ExpectRequest(class RequestMatcher* request_matcher, 77 const base::FilePath& filepath); 78 79 // Returns how many requests have been intercepted and matched by 80 // an expectation. One expectation can only be matched by one request. 81 int GetHitCount() const; 82 83 // Returns how many requests in total have been captured by the interceptor. 84 int GetCount() const; 85 86 // Returns all requests that have been intercepted, matched or not. 87 std::vector<std::string> GetRequests() const; 88 89 // Returns all requests as a string for debugging purposes. 90 std::string GetRequestsAsString() const; 91 92 // Resets the state of the interceptor so that new expectations can be set. 93 void Reset(); 94 95 class Delegate; 96 97 private: 98 friend class URLRequestPostInterceptorFactory; 99 100 static const int kResponseCode200 = 200; 101 102 struct ExpectationResponse { 103 ExpectationResponse(int code, const std::string& body) 104 : response_code(code), response_body(body) {} 105 const int response_code; 106 const std::string response_body; 107 }; 108 typedef std::pair<const RequestMatcher*, ExpectationResponse> Expectation; 109 110 URLRequestPostInterceptor( 111 const GURL& url, 112 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner); 113 ~URLRequestPostInterceptor(); 114 115 void ClearExpectations(); 116 117 const GURL url_; 118 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; 119 120 mutable base::Lock interceptor_lock_; 121 mutable int hit_count_; 122 mutable std::vector<std::string> requests_; 123 mutable std::queue<Expectation> expectations_; 124 125 DISALLOW_COPY_AND_ASSIGN(URLRequestPostInterceptor); 126 }; 127 128 class URLRequestPostInterceptorFactory { 129 public: 130 URLRequestPostInterceptorFactory( 131 const std::string& scheme, 132 const std::string& hostname, 133 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner); 134 ~URLRequestPostInterceptorFactory(); 135 136 // Creates an interceptor object for the specified url path. Returns NULL 137 // in case of errors or a valid interceptor object otherwise. The caller 138 // does not own the returned object. 139 URLRequestPostInterceptor* CreateInterceptor(const base::FilePath& filepath); 140 141 private: 142 const std::string scheme_; 143 const std::string hostname_; 144 scoped_refptr<base::SequencedTaskRunner> io_task_runner_; 145 146 // After creation, |delegate_| lives on the IO thread and it is owned by 147 // a URLRequestFilter after registration. A task to unregister it and 148 // implicitly destroy it is posted from ~URLRequestPostInterceptorFactory(). 149 URLRequestPostInterceptor::Delegate* delegate_; 150 151 DISALLOW_COPY_AND_ASSIGN(URLRequestPostInterceptorFactory); 152 }; 153 154 // Intercepts HTTP POST requests sent to "localhost2". 155 class InterceptorFactory : public URLRequestPostInterceptorFactory { 156 public: 157 explicit InterceptorFactory( 158 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner); 159 ~InterceptorFactory(); 160 161 // Creates an interceptor for the url path defined by POST_INTERCEPT_PATH. 162 URLRequestPostInterceptor* CreateInterceptor(); 163 164 // Creates an interceptor for the given url path. 165 URLRequestPostInterceptor* CreateInterceptorForPath(const char* url_path); 166 167 private: 168 DISALLOW_COPY_AND_ASSIGN(InterceptorFactory); 169 }; 170 171 class PartialMatch : public URLRequestPostInterceptor::RequestMatcher { 172 public: 173 explicit PartialMatch(const std::string& expected) : expected_(expected) {} 174 virtual bool Match(const std::string& actual) const OVERRIDE; 175 176 private: 177 const std::string expected_; 178 179 DISALLOW_COPY_AND_ASSIGN(PartialMatch); 180 }; 181 182 } // namespace component_updater 183 184 #endif // COMPONENTS_COMPONENT_UPDATER_TEST_URL_REQUEST_POST_INTERCEPTOR_H_ 185