11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2013 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#ifndef COMPONENTS_COMPONENT_UPDATER_TEST_URL_REQUEST_POST_INTERCEPTOR_H_ 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define COMPONENTS_COMPONENT_UPDATER_TEST_URL_REQUEST_POST_INTERCEPTOR_H_ 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <stdint.h> 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <map> 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <queue> 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <string> 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <utility> 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <vector> 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/macros.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/ref_counted.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/synchronization/lock.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "url/gurl.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace base { 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass FilePath; 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass SequencedTaskRunner; 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace net { 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass URLRequest; 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace component_updater { 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// component 1 has extension id "jebgalgnebhfojomionfpkfelancnnkf", and 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the RSA public key the following hash: 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst uint8_t jebg_hash[] = {0x94, 0x16, 0x0b, 0x6d, 0x41, 0x75, 0xe9, 0xec, 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0x8e, 0xd5, 0xfa, 0x54, 0xb0, 0xd2, 0xdd, 0xa5, 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47, 0xf6, 0xc4, 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40}; 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// component 2 has extension id "abagagagagagagagagagagagagagagag", and 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the RSA public key the following hash: 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst uint8_t abag_hash[] = {0x01, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x01}; 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// component 3 has extension id "ihfokbkgjpifnbbojhneepfflplebdkc", and 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the RSA public key the following hash: 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst uint8_t ihfo_hash[] = {0x87, 0x5e, 0xa1, 0xa6, 0x9f, 0x85, 0xd1, 0x1e, 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0x97, 0xd4, 0x4f, 0x55, 0xbf, 0xb4, 0x13, 0xa2, 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0xe7, 0xc5, 0xc8, 0xf5, 0x60, 0x19, 0x78, 0x1b, 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0x6d, 0xe9, 0x4c, 0xeb, 0x96, 0x05, 0x42, 0x17}; 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Intercepts requests to a file path, counts them, and captures the body of 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the requests. Optionally, for each request, it can return a canned response 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// from a given file. The class maintains a queue of expectations, and returns 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// one and only one response for each request that matches and it is 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// intercepted. 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass URLRequestPostInterceptor { 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Allows a generic string maching interface when setting up expectations. 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci class RequestMatcher { 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual bool Match(const std::string& actual) const = 0; 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual ~RequestMatcher() {} 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Returns the url that is intercepted. 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL GetUrl() const; 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Sets an expection for the body of the POST request and optionally, 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // provides a canned response identified by a |file_path| to be returned when 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the expectation is met. If no |file_path| is provided, then an empty 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // response body is served. If |response_code| is provided, then an empty 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // response body with that response code is returned. 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Returns |true| if the expectation was set. This class takes ownership of 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the |request_matcher| object. 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool ExpectRequest(class RequestMatcher* request_matcher); 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool ExpectRequest(class RequestMatcher* request_matcher, int response_code); 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool ExpectRequest(class RequestMatcher* request_matcher, 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::FilePath& filepath); 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Returns how many requests have been intercepted and matched by 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // an expectation. One expectation can only be matched by one request. 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int GetHitCount() const; 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Returns how many requests in total have been captured by the interceptor. 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int GetCount() const; 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Returns all requests that have been intercepted, matched or not. 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<std::string> GetRequests() const; 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Returns all requests as a string for debugging purposes. 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string GetRequestsAsString() const; 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Resets the state of the interceptor so that new expectations can be set. 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void Reset(); 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci class Delegate; 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci friend class URLRequestPostInterceptorFactory; 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static const int kResponseCode200 = 200; 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct ExpectationResponse { 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ExpectationResponse(int code, const std::string& body) 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : response_code(code), response_body(body) {} 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const int response_code; 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string response_body; 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef std::pair<const RequestMatcher*, ExpectationResponse> Expectation; 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci URLRequestPostInterceptor( 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& url, 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SequencedTaskRunner>& io_task_runner); 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ~URLRequestPostInterceptor(); 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void ClearExpectations(); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL url_; 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<base::SequencedTaskRunner> io_task_runner_; 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mutable base::Lock interceptor_lock_; 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mutable int hit_count_; 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mutable std::vector<std::string> requests_; 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mutable std::queue<Expectation> expectations_; 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(URLRequestPostInterceptor); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass URLRequestPostInterceptorFactory { 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci URLRequestPostInterceptorFactory( 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& scheme, 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& hostname, 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SequencedTaskRunner>& io_task_runner); 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ~URLRequestPostInterceptorFactory(); 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Creates an interceptor object for the specified url path. Returns NULL 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // in case of errors or a valid interceptor object otherwise. The caller 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // does not own the returned object. 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci URLRequestPostInterceptor* CreateInterceptor(const base::FilePath& filepath); 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string scheme_; 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string hostname_; 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<base::SequencedTaskRunner> io_task_runner_; 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // After creation, |delegate_| lives on the IO thread and it is owned by 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // a URLRequestFilter after registration. A task to unregister it and 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // implicitly destroy it is posted from ~URLRequestPostInterceptorFactory(). 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci URLRequestPostInterceptor::Delegate* delegate_; 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(URLRequestPostInterceptorFactory); 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Intercepts HTTP POST requests sent to "localhost2". 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass InterceptorFactory : public URLRequestPostInterceptorFactory { 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci explicit InterceptorFactory( 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SequencedTaskRunner>& io_task_runner); 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ~InterceptorFactory(); 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Creates an interceptor for the url path defined by POST_INTERCEPT_PATH. 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci URLRequestPostInterceptor* CreateInterceptor(); 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Creates an interceptor for the given url path. 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci URLRequestPostInterceptor* CreateInterceptorForPath(const char* url_path); 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(InterceptorFactory); 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass PartialMatch : public URLRequestPostInterceptor::RequestMatcher { 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci explicit PartialMatch(const std::string& expected) : expected_(expected) {} 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual bool Match(const std::string& actual) const OVERRIDE; 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string expected_; 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(PartialMatch); 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace component_updater 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif // COMPONENTS_COMPONENT_UPDATER_TEST_URL_REQUEST_POST_INTERCEPTOR_H_ 185