Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2009 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 #ifndef NET_PROXY_MOCK_PROXY_RESOLVER_H_
      6 #define NET_PROXY_MOCK_PROXY_RESOLVER_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/logging.h"
     11 #include "base/message_loop.h"
     12 #include "googleurl/src/gurl.h"
     13 #include "net/base/net_errors.h"
     14 #include "net/proxy/proxy_resolver.h"
     15 
     16 namespace net {
     17 
     18 // Asynchronous mock proxy resolver. All requests complete asynchronously,
     19 // user must call Request::CompleteNow() on a pending request to signal it.
     20 class MockAsyncProxyResolverBase : public ProxyResolver {
     21  public:
     22   class Request : public base::RefCounted<Request> {
     23    public:
     24     Request(MockAsyncProxyResolverBase* resolver,
     25             const GURL& url,
     26             ProxyInfo* results,
     27             CompletionCallback* callback)
     28         : resolver_(resolver),
     29           url_(url),
     30           results_(results),
     31           callback_(callback),
     32           origin_loop_(MessageLoop::current()) {
     33     }
     34 
     35     const GURL& url() const { return url_; }
     36     ProxyInfo* results() const { return results_; }
     37     CompletionCallback* callback() const { return callback_; }
     38 
     39     void CompleteNow(int rv) {
     40       CompletionCallback* callback = callback_;
     41 
     42       // May delete |this|.
     43       resolver_->RemovePendingRequest(this);
     44 
     45       callback->Run(rv);
     46     }
     47 
     48    private:
     49     friend class base::RefCounted<Request>;
     50 
     51     ~Request() {}
     52 
     53     MockAsyncProxyResolverBase* resolver_;
     54     const GURL url_;
     55     ProxyInfo* results_;
     56     CompletionCallback* callback_;
     57     MessageLoop* origin_loop_;
     58   };
     59 
     60   class SetPacScriptRequest {
     61    public:
     62     SetPacScriptRequest(MockAsyncProxyResolverBase* resolver,
     63                         const GURL& pac_url,
     64                         const std::string& pac_bytes,
     65                         CompletionCallback* callback)
     66         : resolver_(resolver),
     67           pac_url_(pac_url),
     68           pac_bytes_(pac_bytes),
     69           callback_(callback),
     70           origin_loop_(MessageLoop::current()) {
     71     }
     72 
     73     const GURL& pac_url() const { return pac_url_; }
     74     const std::string& pac_bytes() const { return pac_bytes_; }
     75 
     76     void CompleteNow(int rv) {
     77        CompletionCallback* callback = callback_;
     78 
     79       // Will delete |this|.
     80       resolver_->RemovePendingSetPacScriptRequest(this);
     81 
     82       callback->Run(rv);
     83     }
     84 
     85    private:
     86     MockAsyncProxyResolverBase* resolver_;
     87     const GURL pac_url_;
     88     const std::string pac_bytes_;
     89     CompletionCallback* callback_;
     90     MessageLoop* origin_loop_;
     91   };
     92 
     93   typedef std::vector<scoped_refptr<Request> > RequestsList;
     94 
     95   // ProxyResolver implementation:
     96   virtual int GetProxyForURL(const GURL& url,
     97                              ProxyInfo* results,
     98                              CompletionCallback* callback,
     99                              RequestHandle* request_handle,
    100                              LoadLog* /*load_log*/) {
    101     scoped_refptr<Request> request = new Request(this, url, results, callback);
    102     pending_requests_.push_back(request);
    103 
    104     if (request_handle)
    105       *request_handle = reinterpret_cast<RequestHandle>(request.get());
    106 
    107     // Test code completes the request by calling request->CompleteNow().
    108     return ERR_IO_PENDING;
    109   }
    110 
    111   virtual void CancelRequest(RequestHandle request_handle) {
    112     scoped_refptr<Request> request = reinterpret_cast<Request*>(request_handle);
    113     cancelled_requests_.push_back(request);
    114     RemovePendingRequest(request);
    115   }
    116 
    117   virtual int SetPacScript(const GURL& pac_url,
    118                            const std::string& pac_bytes,
    119                            CompletionCallback* callback) {
    120     DCHECK(!pending_set_pac_script_request_.get());
    121     pending_set_pac_script_request_.reset(
    122         new SetPacScriptRequest(this, pac_url, pac_bytes, callback));
    123     // Finished when user calls SetPacScriptRequest::CompleteNow().
    124     return ERR_IO_PENDING;
    125   }
    126 
    127   virtual void CancelSetPacScript() {
    128     // Do nothing (caller was responsible for completing the request).
    129   }
    130 
    131   const RequestsList& pending_requests() const {
    132     return pending_requests_;
    133   }
    134 
    135   const RequestsList& cancelled_requests() const {
    136     return cancelled_requests_;
    137   }
    138 
    139   SetPacScriptRequest* pending_set_pac_script_request() const {
    140     return pending_set_pac_script_request_.get();
    141   }
    142 
    143   void RemovePendingRequest(Request* request) {
    144     RequestsList::iterator it = std::find(
    145         pending_requests_.begin(), pending_requests_.end(), request);
    146     DCHECK(it != pending_requests_.end());
    147     pending_requests_.erase(it);
    148   }
    149 
    150   void RemovePendingSetPacScriptRequest(SetPacScriptRequest* request) {
    151     DCHECK_EQ(request, pending_set_pac_script_request());
    152     pending_set_pac_script_request_.reset();
    153   }
    154 
    155  protected:
    156   explicit MockAsyncProxyResolverBase(bool expects_pac_bytes)
    157       : ProxyResolver(expects_pac_bytes) {}
    158 
    159  private:
    160   RequestsList pending_requests_;
    161   RequestsList cancelled_requests_;
    162   scoped_ptr<SetPacScriptRequest> pending_set_pac_script_request_;
    163 };
    164 
    165 class MockAsyncProxyResolver : public MockAsyncProxyResolverBase {
    166  public:
    167   MockAsyncProxyResolver()
    168       : MockAsyncProxyResolverBase(false /*expects_pac_bytes*/) {}
    169 };
    170 
    171 class MockAsyncProxyResolverExpectsBytes : public MockAsyncProxyResolverBase {
    172  public:
    173   MockAsyncProxyResolverExpectsBytes()
    174       : MockAsyncProxyResolverBase(true /*expects_pac_bytes*/) {}
    175 };
    176 
    177 }  // namespace net
    178 
    179 #endif  // NET_PROXY_MOCK_PROXY_RESOLVER_H_
    180