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/net_errors.h"
12 #include "net/url_request/url_request_context.h"
13 #include "net/url_request/url_request_context_getter.h"
17 ResolveProxyMsgHelper::ResolveProxyMsgHelper(
18 net::URLRequestContextGetter
* getter
)
19 : context_getter_(getter
),
20 proxy_service_(NULL
) {
23 ResolveProxyMsgHelper::ResolveProxyMsgHelper(net::ProxyService
* proxy_service
)
24 : proxy_service_(proxy_service
) {
27 bool ResolveProxyMsgHelper::OnMessageReceived(const IPC::Message
& message
,
28 bool* message_was_ok
) {
30 IPC_BEGIN_MESSAGE_MAP_EX(ResolveProxyMsgHelper
, message
, *message_was_ok
)
31 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ResolveProxy
, OnResolveProxy
)
32 IPC_MESSAGE_UNHANDLED(handled
= false)
37 void ResolveProxyMsgHelper::OnResolveProxy(const GURL
& url
,
38 IPC::Message
* reply_msg
) {
39 // Enqueue the pending request.
40 pending_requests_
.push_back(PendingRequest(url
, reply_msg
));
42 // If nothing is in progress, start.
43 if (pending_requests_
.size() == 1)
44 StartPendingRequest();
47 ResolveProxyMsgHelper::~ResolveProxyMsgHelper() {
48 // Clear all pending requests if the ProxyService is still alive (if we have a
49 // default request context or override).
50 if (!pending_requests_
.empty()) {
51 PendingRequest req
= pending_requests_
.front();
52 proxy_service_
->CancelPacRequest(req
.pac_req
);
55 for (PendingRequestList::iterator it
= pending_requests_
.begin();
56 it
!= pending_requests_
.end();
61 pending_requests_
.clear();
64 void ResolveProxyMsgHelper::OnResolveProxyCompleted(int result
) {
65 CHECK(!pending_requests_
.empty());
67 const PendingRequest
& completed_req
= pending_requests_
.front();
68 ViewHostMsg_ResolveProxy::WriteReplyParams(
69 completed_req
.reply_msg
, result
== net::OK
, proxy_info_
.ToPacString());
70 Send(completed_req
.reply_msg
);
72 // Clear the current (completed) request.
73 pending_requests_
.pop_front();
75 // Start the next request.
76 if (!pending_requests_
.empty())
77 StartPendingRequest();
80 void ResolveProxyMsgHelper::StartPendingRequest() {
81 PendingRequest
& req
= pending_requests_
.front();
83 // Verify the request wasn't started yet.
84 DCHECK(NULL
== req
.pac_req
);
86 if (context_getter_
.get()) {
87 proxy_service_
= context_getter_
->GetURLRequestContext()->proxy_service();
88 context_getter_
= NULL
;
92 int result
= proxy_service_
->ResolveProxy(
93 req
.url
, &proxy_info_
,
94 base::Bind(&ResolveProxyMsgHelper::OnResolveProxyCompleted
,
95 base::Unretained(this)),
96 &req
.pac_req
, net::BoundNetLog());
98 // Completed synchronously.
99 if (result
!= net::ERR_IO_PENDING
)
100 OnResolveProxyCompleted(result
);
103 } // namespace content