15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/resolve_proxy_msg_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/load_flags.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResolveProxyMsgHelper::ResolveProxyMsgHelper(
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContextGetter* getter)
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : BrowserMessageFilter(ViewMsgStart),
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      context_getter_(getter),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_service_(NULL) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResolveProxyMsgHelper::ResolveProxyMsgHelper(net::ProxyService* proxy_service)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : BrowserMessageFilter(ViewMsgStart),
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      proxy_service_(proxy_service) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ResolveProxyMsgHelper::OnMessageReceived(const IPC::Message& message) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ResolveProxyMsgHelper, message)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ResolveProxy, OnResolveProxy)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResolveProxyMsgHelper::OnResolveProxy(const GURL& url,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           IPC::Message* reply_msg) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enqueue the pending request.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_requests_.push_back(PendingRequest(url, reply_msg));
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If nothing is in progress, start.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pending_requests_.size() == 1)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartPendingRequest();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResolveProxyMsgHelper::~ResolveProxyMsgHelper() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all pending requests if the ProxyService is still alive (if we have a
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default request context or override).
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pending_requests_.empty()) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PendingRequest req = pending_requests_.front();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proxy_service_->CancelPacRequest(req.pac_req);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (PendingRequestList::iterator it = pending_requests_.begin();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != pending_requests_.end();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++it) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete it->reply_msg;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_requests_.clear();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResolveProxyMsgHelper::OnResolveProxyCompleted(int result) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!pending_requests_.empty());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PendingRequest& completed_req = pending_requests_.front();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewHostMsg_ResolveProxy::WriteReplyParams(
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      completed_req.reply_msg, result == net::OK, proxy_info_.ToPacString());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(completed_req.reply_msg);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the current (completed) request.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_requests_.pop_front();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the next request.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pending_requests_.empty())
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartPendingRequest();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResolveProxyMsgHelper::StartPendingRequest() {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingRequest& req = pending_requests_.front();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the request wasn't started yet.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(NULL == req.pac_req);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (context_getter_.get()) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proxy_service_ = context_getter_->GetURLRequestContext()->proxy_service();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_getter_ = NULL;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the request.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = proxy_service_->ResolveProxy(
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      req.url, net::LOAD_NORMAL, &proxy_info_,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ResolveProxyMsgHelper::OnResolveProxyCompleted,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      &req.pac_req, NULL, net::BoundNetLog());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Completed synchronously.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result != net::ERR_IO_PENDING)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnResolveProxyCompleted(result);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
106