1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file.
4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/component_updater/test/url_request_post_interceptor.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/macros.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/stringprintf.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/component_updater/test/test_configurator.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h"
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/url_request/url_request.h"
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/url_request/url_request_filter.h"
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/url_request/url_request_interceptor.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/url_request/url_request_simple_job.h"
17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/url_request/url_request_test_util.h"
18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace component_updater {
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns a canned response.
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class URLRequestMockJob : public net::URLRequestSimpleJob {
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  URLRequestMockJob(net::URLRequest* request,
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    net::NetworkDelegate* network_delegate,
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    int response_code,
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    const std::string& response_body)
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : net::URLRequestSimpleJob(request, network_delegate),
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        response_code_(response_code),
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        response_body_(response_body) {}
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual int GetResponseCode() const OVERRIDE { return response_code_; }
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual int GetData(std::string* mime_type,
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      std::string* charset,
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      std::string* data,
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      const net::CompletionCallback& callback) const OVERRIDE {
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    mime_type->assign("text/plain");
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    charset->assign("US-ASCII");
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    data->assign(response_body_);
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return net::OK;
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~URLRequestMockJob() {}
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int response_code_;
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string response_body_;
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(URLRequestMockJob);
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciURLRequestPostInterceptor::URLRequestPostInterceptor(
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GURL& url,
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : url_(url), io_task_runner_(io_task_runner), hit_count_(0) {
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochURLRequestPostInterceptor::~URLRequestPostInterceptor() {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ClearExpectations();
62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void URLRequestPostInterceptor::ClearExpectations() {
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  while (!expectations_.empty()) {
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Expectation expectation(expectations_.front());
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delete expectation.first;
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    expectations_.pop();
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)GURL URLRequestPostInterceptor::GetUrl() const {
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return url_;
74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool URLRequestPostInterceptor::ExpectRequest(
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    class RequestMatcher* request_matcher) {
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  expectations_.push(std::make_pair(request_matcher,
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    ExpectationResponse(kResponseCode200, "")));
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool URLRequestPostInterceptor::ExpectRequest(
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    class RequestMatcher* request_matcher,
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int response_code) {
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  expectations_.push(
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      std::make_pair(request_matcher, ExpectationResponse(response_code, "")));
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool URLRequestPostInterceptor::ExpectRequest(
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    class RequestMatcher* request_matcher,
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::FilePath& filepath) {
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string response;
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (filepath.empty() || !base::ReadFileToString(filepath, &response))
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  expectations_.push(std::make_pair(
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      request_matcher, ExpectationResponse(kResponseCode200, response)));
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int URLRequestPostInterceptor::GetHitCount() const {
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AutoLock auto_lock(interceptor_lock_);
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return hit_count_;
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int URLRequestPostInterceptor::GetCount() const {
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AutoLock auto_lock(interceptor_lock_);
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return static_cast<int>(requests_.size());
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)std::vector<std::string> URLRequestPostInterceptor::GetRequests() const {
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::AutoLock auto_lock(interceptor_lock_);
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return requests_;
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string URLRequestPostInterceptor::GetRequestsAsString() const {
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::vector<std::string> requests(GetRequests());
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string s = "Requests are:";
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int i = 0;
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (std::vector<std::string>::const_iterator it = requests.begin();
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)       it != requests.end();
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)       ++it) {
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    s.append(base::StringPrintf("\n  (%d): %s", ++i, it->c_str()));
128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return s;
131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void URLRequestPostInterceptor::Reset() {
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AutoLock auto_lock(interceptor_lock_);
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  hit_count_ = 0;
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  requests_.clear();
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ClearExpectations();
138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
139ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class URLRequestPostInterceptor::Delegate : public net::URLRequestInterceptor {
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Delegate(const std::string& scheme,
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           const std::string& hostname,
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : scheme_(scheme), hostname_(hostname), io_task_runner_(io_task_runner) {}
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Register() {
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        scheme_, hostname_, scoped_ptr<net::URLRequestInterceptor>(this));
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Unregister() {
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    for (InterceptorMap::iterator it = interceptors_.begin();
156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)         it != interceptors_.end();
157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)         ++it)
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      delete (*it).second;
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(scheme_,
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                                hostname_);
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnCreateInterceptor(URLRequestPostInterceptor* interceptor) {
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(interceptors_.find(interceptor->GetUrl()) == interceptors_.end());
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    interceptors_.insert(std::make_pair(interceptor->GetUrl(), interceptor));
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~Delegate() {}
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual net::URLRequestJob* MaybeInterceptRequest(
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      net::URLRequest* request,
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      net::NetworkDelegate* network_delegate) const OVERRIDE {
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Only intercepts POST.
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!request->has_upload())
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return NULL;
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GURL url = request->url();
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (url.has_query()) {
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GURL::Replacements replacements;
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      replacements.ClearQuery();
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      url = url.ReplaceComponents(replacements);
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    InterceptorMap::const_iterator it(interceptors_.find(url));
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (it == interceptors_.end())
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return NULL;
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // There is an interceptor hooked up for this url. Read the request body,
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // check the existing expectations, and handle the matching case by
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // popping the expectation off the queue, counting the match, and
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // returning a mock object to serve the canned response.
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    URLRequestPostInterceptor* interceptor(it->second);
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const net::UploadDataStream* stream = request->get_upload();
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const net::UploadBytesElementReader* reader =
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        stream->element_readers()[0]->AsBytesReader();
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const int size = reader->length();
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(size));
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string request_body(reader->bytes());
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::AutoLock auto_lock(interceptor->interceptor_lock_);
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      interceptor->requests_.push_back(request_body);
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (interceptor->expectations_.empty())
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return NULL;
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const URLRequestPostInterceptor::Expectation& expectation(
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          interceptor->expectations_.front());
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (expectation.first->Match(request_body)) {
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        const int response_code(expectation.second.response_code);
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        const std::string response_body(expectation.second.response_body);
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delete expectation.first;
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        interceptor->expectations_.pop();
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ++interceptor->hit_count_;
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return new URLRequestMockJob(
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            request, network_delegate, response_code, response_body);
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef std::map<GURL, URLRequestPostInterceptor*> InterceptorMap;
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InterceptorMap interceptors_;
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string scheme_;
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string hostname_;
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Delegate);
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)URLRequestPostInterceptorFactory::URLRequestPostInterceptorFactory(
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& scheme,
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& hostname,
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : scheme_(scheme),
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      hostname_(hostname),
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      io_task_runner_(io_task_runner),
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      delegate_(new URLRequestPostInterceptor::Delegate(scheme,
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                        hostname,
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                        io_task_runner)) {
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  io_task_runner_->PostTask(
249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&URLRequestPostInterceptor::Delegate::Register,
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 base::Unretained(delegate_)));
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)URLRequestPostInterceptorFactory::~URLRequestPostInterceptorFactory() {
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  io_task_runner_->PostTask(
256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&URLRequestPostInterceptor::Delegate::Unregister,
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 base::Unretained(delegate_)));
259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)URLRequestPostInterceptor* URLRequestPostInterceptorFactory::CreateInterceptor(
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::FilePath& filepath) {
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const GURL base_url(
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::StringPrintf("%s://%s", scheme_.c_str(), hostname_.c_str()));
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL absolute_url(base_url.Resolve(filepath.MaybeAsASCII()));
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  URLRequestPostInterceptor* interceptor(
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new URLRequestPostInterceptor(absolute_url, io_task_runner_));
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool res = io_task_runner_->PostTask(
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      FROM_HERE,
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&URLRequestPostInterceptor::Delegate::OnCreateInterceptor,
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 base::Unretained(delegate_),
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 base::Unretained(interceptor)));
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!res) {
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delete interceptor;
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return interceptor;
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool PartialMatch::Match(const std::string& actual) const {
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return actual.find(expected_) != std::string::npos;
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciInterceptorFactory::InterceptorFactory(
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : URLRequestPostInterceptorFactory(POST_INTERCEPT_SCHEME,
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       POST_INTERCEPT_HOSTNAME,
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       io_task_runner) {
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciInterceptorFactory::~InterceptorFactory() {
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciURLRequestPostInterceptor* InterceptorFactory::CreateInterceptor() {
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return CreateInterceptorForPath(POST_INTERCEPT_PATH);
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciURLRequestPostInterceptor* InterceptorFactory::CreateInterceptorForPath(
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* url_path) {
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return URLRequestPostInterceptorFactory::CreateInterceptor(
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::FilePath::FromUTF8Unsafe(url_path));
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace component_updater
306