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.
5 #include "content/browser/resolve_proxy_msg_helper.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"
18 ResolveProxyMsgHelper::ResolveProxyMsgHelper(
19 net::URLRequestContextGetter
* getter
)
20 : BrowserMessageFilter(ViewMsgStart
),
21 context_getter_(getter
),
22 proxy_service_(NULL
) {
25 ResolveProxyMsgHelper::ResolveProxyMsgHelper(net::ProxyService
* proxy_service
)
26 : BrowserMessageFilter(ViewMsgStart
),
27 proxy_service_(proxy_service
) {
30 bool ResolveProxyMsgHelper::OnMessageReceived(const IPC::Message
& message
) {
32 IPC_BEGIN_MESSAGE_MAP(ResolveProxyMsgHelper
, message
)
33 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ResolveProxy
, OnResolveProxy
)
34 IPC_MESSAGE_UNHANDLED(handled
= false)
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
));
44 // If nothing is in progress, start.
45 if (pending_requests_
.size() == 1)
46 StartPendingRequest();
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
);
57 for (PendingRequestList::iterator it
= pending_requests_
.begin();
58 it
!= pending_requests_
.end();
63 pending_requests_
.clear();
66 void ResolveProxyMsgHelper::OnResolveProxyCompleted(int result
) {
67 CHECK(!pending_requests_
.empty());
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
);
74 // Clear the current (completed) request.
75 pending_requests_
.pop_front();
77 // Start the next request.
78 if (!pending_requests_
.empty())
79 StartPendingRequest();
82 void ResolveProxyMsgHelper::StartPendingRequest() {
83 PendingRequest
& req
= pending_requests_
.front();
85 // Verify the request wasn't started yet.
86 DCHECK(NULL
== req
.pac_req
);
88 if (context_getter_
.get()) {
89 proxy_service_
= context_getter_
->GetURLRequestContext()->proxy_service();
90 context_getter_
= NULL
;
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());
100 // Completed synchronously.
101 if (result
!= net::ERR_IO_PENDING
)
102 OnResolveProxyCompleted(result
);
105 } // namespace content