• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "content/browser/resolve_proxy_msg_helper.h"
6 
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h"
10 #include "content/common/view_messages.h"
11 #include "net/base/load_flags.h"
12 #include "net/base/net_errors.h"
13 #include "net/url_request/url_request_context.h"
14 #include "net/url_request/url_request_context_getter.h"
15 
16 namespace content {
17 
ResolveProxyMsgHelper(net::URLRequestContextGetter * getter)18 ResolveProxyMsgHelper::ResolveProxyMsgHelper(
19     net::URLRequestContextGetter* getter)
20     : BrowserMessageFilter(ViewMsgStart),
21       context_getter_(getter),
22       proxy_service_(NULL) {
23 }
24 
ResolveProxyMsgHelper(net::ProxyService * proxy_service)25 ResolveProxyMsgHelper::ResolveProxyMsgHelper(net::ProxyService* proxy_service)
26     : BrowserMessageFilter(ViewMsgStart),
27       proxy_service_(proxy_service) {
28 }
29 
OnMessageReceived(const IPC::Message & message)30 bool ResolveProxyMsgHelper::OnMessageReceived(const IPC::Message& message) {
31   bool handled = true;
32   IPC_BEGIN_MESSAGE_MAP(ResolveProxyMsgHelper, message)
33     IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ResolveProxy, OnResolveProxy)
34     IPC_MESSAGE_UNHANDLED(handled = false)
35   IPC_END_MESSAGE_MAP()
36   return handled;
37 }
38 
OnResolveProxy(const GURL & url,IPC::Message * reply_msg)39 void ResolveProxyMsgHelper::OnResolveProxy(const GURL& url,
40                                            IPC::Message* reply_msg) {
41   // Enqueue the pending request.
42   pending_requests_.push_back(PendingRequest(url, reply_msg));
43 
44   // If nothing is in progress, start.
45   if (pending_requests_.size() == 1)
46     StartPendingRequest();
47 }
48 
~ResolveProxyMsgHelper()49 ResolveProxyMsgHelper::~ResolveProxyMsgHelper() {
50   // Clear all pending requests if the ProxyService is still alive (if we have a
51   // default request context or override).
52   if (!pending_requests_.empty()) {
53     PendingRequest req = pending_requests_.front();
54     proxy_service_->CancelPacRequest(req.pac_req);
55   }
56 
57   for (PendingRequestList::iterator it = pending_requests_.begin();
58        it != pending_requests_.end();
59        ++it) {
60     delete it->reply_msg;
61   }
62 
63   pending_requests_.clear();
64 }
65 
OnResolveProxyCompleted(int result)66 void ResolveProxyMsgHelper::OnResolveProxyCompleted(int result) {
67   CHECK(!pending_requests_.empty());
68 
69   const PendingRequest& completed_req = pending_requests_.front();
70   ViewHostMsg_ResolveProxy::WriteReplyParams(
71       completed_req.reply_msg, result == net::OK, proxy_info_.ToPacString());
72   Send(completed_req.reply_msg);
73 
74   // Clear the current (completed) request.
75   pending_requests_.pop_front();
76 
77   // Start the next request.
78   if (!pending_requests_.empty())
79     StartPendingRequest();
80 }
81 
StartPendingRequest()82 void ResolveProxyMsgHelper::StartPendingRequest() {
83   PendingRequest& req = pending_requests_.front();
84 
85   // Verify the request wasn't started yet.
86   DCHECK(NULL == req.pac_req);
87 
88   if (context_getter_.get()) {
89     proxy_service_ = context_getter_->GetURLRequestContext()->proxy_service();
90     context_getter_ = NULL;
91   }
92 
93   // Start the request.
94   int result = proxy_service_->ResolveProxy(
95       req.url, net::LOAD_NORMAL, &proxy_info_,
96       base::Bind(&ResolveProxyMsgHelper::OnResolveProxyCompleted,
97                  base::Unretained(this)),
98       &req.pac_req, NULL, net::BoundNetLog());
99 
100   // Completed synchronously.
101   if (result != net::ERR_IO_PENDING)
102     OnResolveProxyCompleted(result);
103 }
104 
105 }  // namespace content
106