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