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 16namespace net { 17 18// Asynchronous mock proxy resolver. All requests complete asynchronously, 19// user must call Request::CompleteNow() on a pending request to signal it. 20class 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 165class MockAsyncProxyResolver : public MockAsyncProxyResolverBase { 166 public: 167 MockAsyncProxyResolver() 168 : MockAsyncProxyResolverBase(false /*expects_pac_bytes*/) {} 169}; 170 171class 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