Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Side by Side Diff: chromeos/dbus/services/proxy_resolution_service_provider.cc

Issue 2763963003: chromeos: Simplify D-Bus proxy resolution service code. (Closed)
Patch Set: make Request private Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromeos/dbus/services/proxy_resolution_service_provider.h" 5 #include "chromeos/dbus/services/proxy_resolution_service_provider.h"
6 6
7 #include <string>
8 #include <utility> 7 #include <utility>
9 8
10 #include "base/bind.h" 9 #include "base/bind.h"
11 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
12 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/threading/thread_task_runner_handle.h" 13 #include "base/threading/thread_task_runner_handle.h"
14 #include "dbus/bus.h" 14 #include "dbus/bus.h"
15 #include "dbus/message.h" 15 #include "dbus/message.h"
16 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
17 #include "net/log/net_log_with_source.h" 17 #include "net/log/net_log_with_source.h"
18 #include "net/proxy/proxy_service.h" 18 #include "net/proxy/proxy_service.h"
19 #include "net/url_request/url_request_context.h" 19 #include "net/url_request/url_request_context.h"
20 #include "net/url_request/url_request_context_getter.h" 20 #include "net/url_request/url_request_context_getter.h"
21 #include "third_party/cros_system_api/dbus/service_constants.h" 21 #include "third_party/cros_system_api/dbus/service_constants.h"
22 22
23 namespace chromeos { 23 namespace chromeos {
24 24
25 // The ProxyResolverInterface implementation used in production. 25 // The ProxyResolverInterface implementation used in production.
26 class ProxyResolverImpl : public ProxyResolverInterface { 26 class ProxyResolverImpl : public ProxyResolverInterface {
27 public: 27 public:
28 // Data being used in one proxy resolution.
29 class Request {
Daniel Erat 2017/03/22 14:43:43 this is moved to the private section. i also made
30 public:
31 explicit Request(const std::string& source_url) : source_url_(source_url) {
32 }
33
34 virtual ~Request() {}
35
36 // Callback on IO thread for when net::ProxyService::ResolveProxy
37 // completes, synchronously or asynchronously.
38 void OnCompletion(scoped_refptr<base::SingleThreadTaskRunner> origin_thread,
39 int result) {
40 // Generate the error message if the error message is not yet set,
41 // and there was an error.
42 if (error_.empty() && result != net::OK)
43 error_ = net::ErrorToString(result);
44 origin_thread->PostTask(FROM_HERE, notify_task_);
45 }
46
47 std::string source_url_; // URL being resolved.
48 net::ProxyInfo proxy_info_; // ProxyInfo resolved for source_url_.
49 std::string error_; // Error from proxy resolution.
50 base::Closure notify_task_; // Task to notify of resolution result.
51
52 private:
53 DISALLOW_COPY_AND_ASSIGN(Request);
54 };
55
56 explicit ProxyResolverImpl(std::unique_ptr<ProxyResolverDelegate> delegate) 28 explicit ProxyResolverImpl(std::unique_ptr<ProxyResolverDelegate> delegate)
57 : delegate_(std::move(delegate)), 29 : delegate_(std::move(delegate)),
58 origin_thread_(base::ThreadTaskRunnerHandle::Get()), 30 origin_thread_(base::ThreadTaskRunnerHandle::Get()),
59 weak_ptr_factory_(this) {} 31 weak_ptr_factory_(this) {}
60 32
61 ~ProxyResolverImpl() override { 33 ~ProxyResolverImpl() override {
62 DCHECK(OnOriginThread()); 34 DCHECK(OnOriginThread());
63
64 for (std::set<Request*>::iterator iter = all_requests_.begin();
65 iter != all_requests_.end(); ++iter) {
66 Request* request = *iter;
67 LOG(WARNING) << "Pending request for " << request->source_url_;
68 delete request;
69 }
70 } 35 }
71 36
72 // ProxyResolverInterface override. 37 // ProxyResolverInterface override.
73 void ResolveProxy( 38 void ResolveProxy(
James Cook 2017/03/22 19:53:20 nit: There's a lot of inline code in these class m
Daniel Erat 2017/03/22 20:11:18 sure, i've moved the implementations out.
74 const std::string& source_url, 39 const std::string& source_url,
75 const std::string& signal_interface, 40 const std::string& signal_interface,
76 const std::string& signal_name, 41 const std::string& signal_name,
77 scoped_refptr<dbus::ExportedObject> exported_object) override { 42 scoped_refptr<dbus::ExportedObject> exported_object) override {
78 DCHECK(OnOriginThread()); 43 DCHECK(OnOriginThread());
79 44
80 // Create a request slot for this proxy resolution request. 45 auto request = base::MakeUnique<Request>(source_url, signal_interface,
81 Request* request = new Request(source_url); 46 signal_name, exported_object,
82 request->notify_task_ = base::Bind( 47 delegate_->GetRequestContext());
83 &ProxyResolverImpl::NotifyProxyResolved,
84 weak_ptr_factory_.GetWeakPtr(),
85 signal_interface,
86 signal_name,
87 exported_object,
88 request);
89 all_requests_.insert(request);
90 48
91 // GetRequestContext() must be called on UI thread. 49 // This would ideally call PostTaskAndReply() instead of PostTask(), but
92 scoped_refptr<net::URLRequestContextGetter> getter = 50 // ResolveProxyInternal()'s call to net::ProxyService::ResolveProxy() can
93 delegate_->GetRequestContext(); 51 // result in an asynchronous lookup, in which case the result won't be
94 52 // available immediately.
95 getter->GetNetworkTaskRunner()->PostTask( 53 request->context_getter->GetNetworkTaskRunner()->PostTask(
96 FROM_HERE, 54 FROM_HERE, base::Bind(&ProxyResolverImpl::ResolveProxyInternal,
97 base::Bind(&ProxyResolverImpl::ResolveProxyInternal, 55 weak_ptr_factory_.GetWeakPtr(),
98 request, 56 base::Passed(std::move(request))));
99 origin_thread_,
100 getter,
101 exported_object));
102 } 57 }
103 58
104 private: 59 private:
105 // Helper function for ResolveProxy(). 60 // Data being used in one proxy resolution.
106 static void ResolveProxyInternal( 61 struct Request {
107 Request* request, 62 public:
108 scoped_refptr<base::SingleThreadTaskRunner> origin_thread, 63 Request(const std::string& source_url,
109 scoped_refptr<net::URLRequestContextGetter> getter, 64 const std::string& signal_interface,
110 scoped_refptr<dbus::ExportedObject> exported_object) { 65 const std::string& signal_name,
111 // Make sure we're running on IO thread. 66 scoped_refptr<dbus::ExportedObject> exported_object,
112 DCHECK(getter->GetNetworkTaskRunner()->BelongsToCurrentThread()); 67 scoped_refptr<net::URLRequestContextGetter> context_getter)
68 : source_url(source_url),
69 signal_interface(signal_interface),
70 signal_name(signal_name),
71 exported_object(exported_object),
72 context_getter(context_getter) {}
73 ~Request() = default;
113 74
114 // Check if we have the URLRequestContextGetter. 75 // URL being resolved.
115 if (!getter.get()) { 76 const std::string source_url;
Daniel Erat 2017/03/22 14:43:43 i don't understand the reason for this check. it's
116 request->error_ = "No URLRequestContextGetter"; 77
117 request->OnCompletion(origin_thread, net::ERR_UNEXPECTED); 78 // D-Bus interface, name, and object for emitting result signal after
79 // resolution is complete.
80 const std::string signal_interface;
81 const std::string signal_name;
82 const scoped_refptr<dbus::ExportedObject> exported_object;
83
84 // Used to get the network context associated with the profile used to run
85 // this request.
86 const scoped_refptr<net::URLRequestContextGetter> context_getter;
87
88 // ProxyInfo resolved for |source_url|.
89 net::ProxyInfo proxy_info;
90
91 // Error from proxy resolution.
92 std::string error;
93
94 private:
95 DISALLOW_COPY_AND_ASSIGN(Request);
96 };
97
98 // Returns true if the current thread is on the origin thread.
99 bool OnOriginThread() { return origin_thread_->BelongsToCurrentThread(); }
100
101 // Helper method for ResolveProxy() that runs on network thread.
102 void ResolveProxyInternal(std::unique_ptr<Request> request) {
James Cook 2017/03/22 19:53:20 nit: Maybe ResolveProxyOnNetworkThread()?
Daniel Erat 2017/03/22 20:11:18 Done.
103 DCHECK(request->context_getter->GetNetworkTaskRunner()
104 ->BelongsToCurrentThread());
105
106 net::ProxyService* proxy_service =
107 request->context_getter->GetURLRequestContext()->proxy_service();
108 if (!proxy_service) {
109 request->error = "No proxy service in chrome";
110 OnResolutionComplete(std::move(request), net::ERR_UNEXPECTED);
118 return; 111 return;
119 } 112 }
120 113
121 // Retrieve ProxyService from profile's request context. 114 Request* request_ptr = request.get();
122 net::ProxyService* proxy_service = 115 net::CompletionCallback callback = base::Bind(
123 getter->GetURLRequestContext()->proxy_service(); 116 &ProxyResolverImpl::OnResolutionComplete,
124 if (!proxy_service) { 117 weak_ptr_factory_.GetWeakPtr(), base::Passed(std::move(request)));
125 request->error_ = "No proxy service in chrome";
126 request->OnCompletion(origin_thread, net::ERR_UNEXPECTED);
127 return;
128 }
129 118
130 VLOG(1) << "Starting network proxy resolution for " 119 VLOG(1) << "Starting network proxy resolution for "
131 << request->source_url_; 120 << request_ptr->source_url;
132 net::CompletionCallback completion_callback =
133 base::Bind(&Request::OnCompletion,
134 base::Unretained(request),
135 origin_thread);
136 const int result = proxy_service->ResolveProxy( 121 const int result = proxy_service->ResolveProxy(
137 GURL(request->source_url_), std::string(), &request->proxy_info_, 122 GURL(request_ptr->source_url), std::string(), &request_ptr->proxy_info,
Daniel Erat 2017/03/22 14:43:43 i mentioned it in an earlier patch set, but i thin
138 completion_callback, NULL, NULL, net::NetLogWithSource()); 123 callback, nullptr, nullptr, net::NetLogWithSource());
139 if (result != net::ERR_IO_PENDING) { 124 if (result != net::ERR_IO_PENDING) {
140 VLOG(1) << "Network proxy resolution completed synchronously."; 125 VLOG(1) << "Network proxy resolution completed synchronously.";
141 completion_callback.Run(result); 126 callback.Run(result);
142 } 127 }
143 } 128 }
144 129
145 // Called on UI thread as task posted from Request::OnCompletion on IO 130 // Callback on network thread for when net::ProxyService::ResolveProxy()
146 // thread. 131 // completes, synchronously or asynchronously.
147 void NotifyProxyResolved( 132 void OnResolutionComplete(std::unique_ptr<Request> request, int result) {
148 const std::string& signal_interface, 133 DCHECK(request->context_getter->GetNetworkTaskRunner()
149 const std::string& signal_name, 134 ->BelongsToCurrentThread());
150 scoped_refptr<dbus::ExportedObject> exported_object, 135
151 Request* request) { 136 if (request->error.empty() && result != net::OK)
137 request->error = net::ErrorToString(result);
138
139 origin_thread_->PostTask(FROM_HERE,
140 base::Bind(&ProxyResolverImpl::NotifyProxyResolved,
141 weak_ptr_factory_.GetWeakPtr(),
142 base::Passed(std::move(request))));
143 }
144
145 // Called on UI thread from OnResolutionCompletion().
146 void NotifyProxyResolved(std::unique_ptr<Request> request) {
152 DCHECK(OnOriginThread()); 147 DCHECK(OnOriginThread());
153 148
154 // Send a signal to the client. 149 // Send a signal to the client.
155 dbus::Signal signal(signal_interface, signal_name); 150 dbus::Signal signal(request->signal_interface, request->signal_name);
156 dbus::MessageWriter writer(&signal); 151 dbus::MessageWriter writer(&signal);
157 writer.AppendString(request->source_url_); 152 writer.AppendString(request->source_url);
158 writer.AppendString(request->proxy_info_.ToPacString()); 153 writer.AppendString(request->proxy_info.ToPacString());
159 writer.AppendString(request->error_); 154 writer.AppendString(request->error);
160 exported_object->SendSignal(&signal); 155 request->exported_object->SendSignal(&signal);
161 VLOG(1) << "Sending signal: " << signal.ToString(); 156 VLOG(1) << "Sending signal: " << signal.ToString();
162
163 std::set<Request*>::iterator iter = all_requests_.find(request);
164 if (iter == all_requests_.end()) {
165 LOG(ERROR) << "can't find request slot(" << request->source_url_
166 << ") in proxy-resolution queue";
167 } else {
168 all_requests_.erase(iter);
169 }
170 delete request;
171 }
172
173 // Returns true if the current thread is on the origin thread.
174 bool OnOriginThread() {
175 return origin_thread_->BelongsToCurrentThread();
176 } 157 }
177 158
178 std::unique_ptr<ProxyResolverDelegate> delegate_; 159 std::unique_ptr<ProxyResolverDelegate> delegate_;
179 scoped_refptr<base::SingleThreadTaskRunner> origin_thread_; 160 scoped_refptr<base::SingleThreadTaskRunner> origin_thread_;
180 std::set<Request*> all_requests_;
181 base::WeakPtrFactory<ProxyResolverImpl> weak_ptr_factory_; 161 base::WeakPtrFactory<ProxyResolverImpl> weak_ptr_factory_;
182 162
183 DISALLOW_COPY_AND_ASSIGN(ProxyResolverImpl); 163 DISALLOW_COPY_AND_ASSIGN(ProxyResolverImpl);
184 }; 164 };
185 165
186 ProxyResolutionServiceProvider::ProxyResolutionServiceProvider( 166 ProxyResolutionServiceProvider::ProxyResolutionServiceProvider(
187 ProxyResolverInterface* resolver) 167 ProxyResolverInterface* resolver)
188 : resolver_(resolver), 168 : resolver_(resolver),
189 origin_thread_(base::ThreadTaskRunnerHandle::Get()), 169 origin_thread_(base::ThreadTaskRunnerHandle::Get()),
190 weak_ptr_factory_(this) { 170 weak_ptr_factory_(this) {
191 } 171 }
192 172
193 ProxyResolutionServiceProvider::~ProxyResolutionServiceProvider() { 173 ProxyResolutionServiceProvider::~ProxyResolutionServiceProvider() = default;
194 }
195 174
196 void ProxyResolutionServiceProvider::Start( 175 void ProxyResolutionServiceProvider::Start(
197 scoped_refptr<dbus::ExportedObject> exported_object) { 176 scoped_refptr<dbus::ExportedObject> exported_object) {
198 DCHECK(OnOriginThread()); 177 DCHECK(OnOriginThread());
199 exported_object_ = exported_object; 178 exported_object_ = exported_object;
200 VLOG(1) << "ProxyResolutionServiceProvider started"; 179 VLOG(1) << "ProxyResolutionServiceProvider started";
201 exported_object_->ExportMethod( 180 exported_object_->ExportMethod(
202 kLibCrosServiceInterface, 181 kLibCrosServiceInterface,
203 kResolveNetworkProxy, 182 kResolveNetworkProxy,
204 // Weak pointers can only bind to methods without return values, 183 // Weak pointers can only bind to methods without return values,
205 // hence we cannot bind ResolveProxyInternal here. Instead we use a 184 // hence we cannot bind ResolveProxyInternal here. Instead we use a
206 // static function to solve this problem. 185 // static function to solve this problem.
207 base::Bind(&ProxyResolutionServiceProvider::CallResolveProxyHandler, 186 base::Bind(&ProxyResolutionServiceProvider::CallResolveProxyHandler,
208 weak_ptr_factory_.GetWeakPtr()), 187 weak_ptr_factory_.GetWeakPtr()),
209 base::Bind(&ProxyResolutionServiceProvider::OnExported, 188 base::Bind(&ProxyResolutionServiceProvider::OnExported,
210 weak_ptr_factory_.GetWeakPtr())); 189 weak_ptr_factory_.GetWeakPtr()));
211 } 190 }
212 191
213 void ProxyResolutionServiceProvider::OnExported( 192 void ProxyResolutionServiceProvider::OnExported(
214 const std::string& interface_name, 193 const std::string& interface_name,
215 const std::string& method_name, 194 const std::string& method_name,
216 bool success) { 195 bool success) {
217 if (!success) { 196 if (!success) {
218 LOG(ERROR) << "Failed to export " << interface_name << "." 197 LOG(ERROR) << "Failed to export " << interface_name << "."
219 << method_name; 198 << method_name;
199 } else {
200 VLOG(1) << "Method exported: " << interface_name << "." << method_name;
220 } 201 }
221 VLOG(1) << "Method exported: " << interface_name << "." << method_name;
222 } 202 }
223 203
224 bool ProxyResolutionServiceProvider::OnOriginThread() { 204 bool ProxyResolutionServiceProvider::OnOriginThread() {
225 return origin_thread_->BelongsToCurrentThread(); 205 return origin_thread_->BelongsToCurrentThread();
226 } 206 }
227 207
228 void ProxyResolutionServiceProvider::ResolveProxyHandler( 208 void ProxyResolutionServiceProvider::ResolveProxyHandler(
229 dbus::MethodCall* method_call, 209 dbus::MethodCall* method_call,
230 dbus::ExportedObject::ResponseSender response_sender) { 210 dbus::ExportedObject::ResponseSender response_sender) {
231 DCHECK(OnOriginThread()); 211 DCHECK(OnOriginThread());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 245 }
266 provider_weak_ptr->ResolveProxyHandler(method_call, response_sender); 246 provider_weak_ptr->ResolveProxyHandler(method_call, response_sender);
267 } 247 }
268 248
269 ProxyResolutionServiceProvider* ProxyResolutionServiceProvider::Create( 249 ProxyResolutionServiceProvider* ProxyResolutionServiceProvider::Create(
270 std::unique_ptr<ProxyResolverDelegate> delegate) { 250 std::unique_ptr<ProxyResolverDelegate> delegate) {
271 return new ProxyResolutionServiceProvider( 251 return new ProxyResolutionServiceProvider(
272 new ProxyResolverImpl(std::move(delegate))); 252 new ProxyResolverImpl(std::move(delegate)));
273 } 253 }
274 254
275 ProxyResolverInterface::~ProxyResolverInterface() { 255 ProxyResolverInterface::~ProxyResolverInterface() = default;
276 }
277 256
278 } // namespace chromeos 257 } // namespace chromeos
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698