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