Home | History | Annotate | Download | only in test
      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