Home | History | Annotate | Download | only in browser
      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/net_errors.h"
     12 #include "net/url_request/url_request_context.h"
     13 #include "net/url_request/url_request_context_getter.h"
     14 
     15 namespace content {
     16 
     17 ResolveProxyMsgHelper::ResolveProxyMsgHelper(
     18     net::URLRequestContextGetter* getter)
     19     : context_getter_(getter),
     20       proxy_service_(NULL) {
     21 }
     22 
     23 ResolveProxyMsgHelper::ResolveProxyMsgHelper(net::ProxyService* proxy_service)
     24     : proxy_service_(proxy_service) {
     25 }
     26 
     27 bool ResolveProxyMsgHelper::OnMessageReceived(const IPC::Message& message,
     28                                               bool* message_was_ok) {
     29   bool handled = true;
     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)
     33   IPC_END_MESSAGE_MAP()
     34   return handled;
     35 }
     36 
     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));
     41 
     42   // If nothing is in progress, start.
     43   if (pending_requests_.size() == 1)
     44     StartPendingRequest();
     45 }
     46 
     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);
     53   }
     54 
     55   for (PendingRequestList::iterator it = pending_requests_.begin();
     56        it != pending_requests_.end();
     57        ++it) {
     58     delete it->reply_msg;
     59   }
     60 
     61   pending_requests_.clear();
     62 }
     63 
     64 void ResolveProxyMsgHelper::OnResolveProxyCompleted(int result) {
     65   CHECK(!pending_requests_.empty());
     66 
     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);
     71 
     72   // Clear the current (completed) request.
     73   pending_requests_.pop_front();
     74 
     75   // Start the next request.
     76   if (!pending_requests_.empty())
     77     StartPendingRequest();
     78 }
     79 
     80 void ResolveProxyMsgHelper::StartPendingRequest() {
     81   PendingRequest& req = pending_requests_.front();
     82 
     83   // Verify the request wasn't started yet.
     84   DCHECK(NULL == req.pac_req);
     85 
     86   if (context_getter_.get()) {
     87     proxy_service_ = context_getter_->GetURLRequestContext()->proxy_service();
     88     context_getter_ = NULL;
     89   }
     90 
     91   // Start the request.
     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());
     97 
     98   // Completed synchronously.
     99   if (result != net::ERR_IO_PENDING)
    100     OnResolveProxyCompleted(result);
    101 }
    102 
    103 }  // namespace content
    104