• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/proxy_resolution/mock_proxy_resolver.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/check.h"
11 #include "base/not_fatal_until.h"
12 #include "base/ranges/algorithm.h"
13 
14 namespace net {
15 
RequestImpl(std::unique_ptr<Job> job)16 MockAsyncProxyResolver::RequestImpl::RequestImpl(std::unique_ptr<Job> job)
17     : job_(std::move(job)) {
18   DCHECK(job_);
19 }
20 
~RequestImpl()21 MockAsyncProxyResolver::RequestImpl::~RequestImpl() {
22   MockAsyncProxyResolver* resolver = job_->Resolver();
23   // AddCancelledJob will check if request is already cancelled
24   resolver->AddCancelledJob(std::move(job_));
25 }
26 
GetLoadState()27 LoadState MockAsyncProxyResolver::RequestImpl::GetLoadState() {
28   return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
29 }
30 
Job(MockAsyncProxyResolver * resolver,const GURL & url,ProxyInfo * results,CompletionOnceCallback callback)31 MockAsyncProxyResolver::Job::Job(MockAsyncProxyResolver* resolver,
32                                  const GURL& url,
33                                  ProxyInfo* results,
34                                  CompletionOnceCallback callback)
35     : resolver_(resolver),
36       url_(url),
37       results_(results),
38       callback_(std::move(callback)) {}
39 
40 MockAsyncProxyResolver::Job::~Job() = default;
41 
CompleteNow(int rv)42 void MockAsyncProxyResolver::Job::CompleteNow(int rv) {
43   CompletionOnceCallback callback = std::move(callback_);
44 
45   resolver_->RemovePendingJob(this);
46 
47   std::move(callback).Run(rv);
48 }
49 
50 MockAsyncProxyResolver::~MockAsyncProxyResolver() = default;
51 
GetProxyForURL(const GURL & url,const NetworkAnonymizationKey & network_anonymization_key,ProxyInfo * results,CompletionOnceCallback callback,std::unique_ptr<Request> * request,const NetLogWithSource &)52 int MockAsyncProxyResolver::GetProxyForURL(
53     const GURL& url,
54     const NetworkAnonymizationKey& network_anonymization_key,
55     ProxyInfo* results,
56     CompletionOnceCallback callback,
57     std::unique_ptr<Request>* request,
58     const NetLogWithSource& /*net_log*/) {
59   auto job = std::make_unique<Job>(this, url, results, std::move(callback));
60 
61   pending_jobs_.push_back(job.get());
62   *request = std::make_unique<RequestImpl>(std::move(job));
63 
64   // Test code completes the request by calling job->CompleteNow().
65   return ERR_IO_PENDING;
66 }
67 
AddCancelledJob(std::unique_ptr<Job> job)68 void MockAsyncProxyResolver::AddCancelledJob(std::unique_ptr<Job> job) {
69   auto it = base::ranges::find(pending_jobs_, job.get());
70   // Because this is called always when RequestImpl is destructed,
71   // we need to check if it is still in pending jobs.
72   if (it != pending_jobs_.end()) {
73     cancelled_jobs_.push_back(std::move(job));
74     pending_jobs_.erase(it);
75   }
76 }
77 
RemovePendingJob(Job * job)78 void MockAsyncProxyResolver::RemovePendingJob(Job* job) {
79   DCHECK(job);
80   auto it = base::ranges::find(pending_jobs_, job);
81   CHECK(it != pending_jobs_.end(), base::NotFatalUntil::M130);
82   pending_jobs_.erase(it);
83 }
84 
85 MockAsyncProxyResolver::MockAsyncProxyResolver() = default;
86 
Request(MockAsyncProxyResolverFactory * factory,const scoped_refptr<PacFileData> & script_data,std::unique_ptr<ProxyResolver> * resolver,CompletionOnceCallback callback)87 MockAsyncProxyResolverFactory::Request::Request(
88     MockAsyncProxyResolverFactory* factory,
89     const scoped_refptr<PacFileData>& script_data,
90     std::unique_ptr<ProxyResolver>* resolver,
91     CompletionOnceCallback callback)
92     : factory_(factory),
93       script_data_(script_data),
94       resolver_(resolver),
95       callback_(std::move(callback)) {}
96 
97 MockAsyncProxyResolverFactory::Request::~Request() = default;
98 
CompleteNow(int rv,std::unique_ptr<ProxyResolver> resolver)99 void MockAsyncProxyResolverFactory::Request::CompleteNow(
100     int rv,
101     std::unique_ptr<ProxyResolver> resolver) {
102   *resolver_ = std::move(resolver);
103 
104   // RemovePendingRequest may remove the last external reference to |this|.
105   scoped_refptr<MockAsyncProxyResolverFactory::Request> keep_alive(this);
106   factory_->RemovePendingRequest(this);
107   factory_ = nullptr;
108   std::move(callback_).Run(rv);
109 }
110 
CompleteNowWithForwarder(int rv,ProxyResolver * resolver)111 void MockAsyncProxyResolverFactory::Request::CompleteNowWithForwarder(
112     int rv,
113     ProxyResolver* resolver) {
114   DCHECK(resolver);
115   CompleteNow(rv, std::make_unique<ForwardingProxyResolver>(resolver));
116 }
117 
FactoryDestroyed()118 void MockAsyncProxyResolverFactory::Request::FactoryDestroyed() {
119   factory_ = nullptr;
120 }
121 
122 class MockAsyncProxyResolverFactory::Job
123     : public ProxyResolverFactory::Request {
124  public:
Job(const scoped_refptr<MockAsyncProxyResolverFactory::Request> & request)125   explicit Job(
126       const scoped_refptr<MockAsyncProxyResolverFactory::Request>& request)
127       : request_(request) {}
~Job()128   ~Job() override {
129     if (request_->factory_) {
130       request_->factory_->cancelled_requests_.push_back(request_);
131       request_->factory_->RemovePendingRequest(request_.get());
132     }
133   }
134 
135  private:
136   scoped_refptr<MockAsyncProxyResolverFactory::Request> request_;
137 };
138 
MockAsyncProxyResolverFactory(bool resolvers_expect_pac_bytes)139 MockAsyncProxyResolverFactory::MockAsyncProxyResolverFactory(
140     bool resolvers_expect_pac_bytes)
141     : ProxyResolverFactory(resolvers_expect_pac_bytes) {
142 }
143 
CreateProxyResolver(const scoped_refptr<PacFileData> & pac_script,std::unique_ptr<ProxyResolver> * resolver,CompletionOnceCallback callback,std::unique_ptr<ProxyResolverFactory::Request> * request_handle)144 int MockAsyncProxyResolverFactory::CreateProxyResolver(
145     const scoped_refptr<PacFileData>& pac_script,
146     std::unique_ptr<ProxyResolver>* resolver,
147     CompletionOnceCallback callback,
148     std::unique_ptr<ProxyResolverFactory::Request>* request_handle) {
149   auto request = base::MakeRefCounted<Request>(this, pac_script, resolver,
150                                                std::move(callback));
151   pending_requests_.push_back(request);
152 
153   *request_handle = std::make_unique<Job>(request);
154 
155   // Test code completes the request by calling request->CompleteNow().
156   return ERR_IO_PENDING;
157 }
158 
RemovePendingRequest(Request * request)159 void MockAsyncProxyResolverFactory::RemovePendingRequest(Request* request) {
160   auto it = base::ranges::find(pending_requests_, request);
161   CHECK(it != pending_requests_.end(), base::NotFatalUntil::M130);
162   pending_requests_.erase(it);
163 }
164 
~MockAsyncProxyResolverFactory()165 MockAsyncProxyResolverFactory::~MockAsyncProxyResolverFactory() {
166   for (auto& request : pending_requests_) {
167     request->FactoryDestroyed();
168   }
169 }
170 
ForwardingProxyResolver(ProxyResolver * impl)171 ForwardingProxyResolver::ForwardingProxyResolver(ProxyResolver* impl)
172     : impl_(impl) {
173 }
174 
GetProxyForURL(const GURL & query_url,const NetworkAnonymizationKey & network_anonymization_key,ProxyInfo * results,CompletionOnceCallback callback,std::unique_ptr<Request> * request,const NetLogWithSource & net_log)175 int ForwardingProxyResolver::GetProxyForURL(
176     const GURL& query_url,
177     const NetworkAnonymizationKey& network_anonymization_key,
178     ProxyInfo* results,
179     CompletionOnceCallback callback,
180     std::unique_ptr<Request>* request,
181     const NetLogWithSource& net_log) {
182   return impl_->GetProxyForURL(query_url, network_anonymization_key, results,
183                                std::move(callback), request, net_log);
184 }
185 
186 }  // namespace net
187