1 // Copyright (c) 2006-2008 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_URL_REQUEST_URL_REQUEST_JOB_MANAGER_H__ 6 #define NET_URL_REQUEST_URL_REQUEST_JOB_MANAGER_H__ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/lock.h" 12 #include "base/platform_thread.h" 13 #include "net/url_request/url_request.h" 14 15 // This class is responsible for managing the set of protocol factories and 16 // request interceptors that determine how an URLRequestJob gets created to 17 // handle an URLRequest. 18 // 19 // MULTI-THREADING NOTICE: 20 // URLRequest is designed to have all consumers on a single thread, and so no 21 // attempt is made to support ProtocolFactory or Interceptor instances being 22 // registered/unregistered or in any way poked on multiple threads. However, 23 // we do support checking for supported schemes FROM ANY THREAD (i.e., it is 24 // safe to call SupportsScheme on any thread). 25 // 26 class URLRequestJobManager { 27 public: 28 URLRequestJobManager(); 29 30 // Instantiate an URLRequestJob implementation based on the registered 31 // interceptors and protocol factories. This will always succeed in 32 // returning a job unless we are--in the extreme case--out of memory. 33 URLRequestJob* CreateJob(URLRequest* request) const; 34 35 // Allows interceptors to hijack the request after examining the new location 36 // of a redirect. Returns NULL if no interceptor intervenes. 37 URLRequestJob* MaybeInterceptRedirect(URLRequest* request, 38 const GURL& location) const; 39 40 // Allows interceptors to hijack the request after examining the response 41 // status and headers. This is also called when there is no server response 42 // at all to allow interception of failed requests due to network errors. 43 // Returns NULL if no interceptor intervenes. 44 URLRequestJob* MaybeInterceptResponse(URLRequest* request) const; 45 46 // Returns true if there is a protocol factory registered for the given 47 // scheme. Note: also returns true if there is a built-in handler for the 48 // given scheme. 49 bool SupportsScheme(const std::string& scheme) const; 50 51 // Register a protocol factory associated with the given scheme. The factory 52 // parameter may be null to clear any existing association. Returns the 53 // previously registered protocol factory if any. 54 URLRequest::ProtocolFactory* RegisterProtocolFactory( 55 const std::string& scheme, URLRequest::ProtocolFactory* factory); 56 57 // Register/unregister a request interceptor. 58 void RegisterRequestInterceptor(URLRequest::Interceptor* interceptor); 59 void UnregisterRequestInterceptor(URLRequest::Interceptor* interceptor); 60 61 private: 62 typedef std::map<std::string,URLRequest::ProtocolFactory*> FactoryMap; 63 typedef std::vector<URLRequest::Interceptor*> InterceptorList; 64 65 mutable Lock lock_; 66 FactoryMap factories_; 67 InterceptorList interceptors_; 68 69 #ifndef NDEBUG 70 // We use this to assert that CreateJob and the registration functions all 71 // run on the same thread. 72 mutable PlatformThreadId allowed_thread_; 73 mutable bool allowed_thread_initialized_; 74 75 // The first guy to call this function sets the allowed thread. This way we 76 // avoid needing to define that thread externally. Since we expect all 77 // callers to be on the same thread, we don't worry about threads racing to 78 // set the allowed thread. 79 bool IsAllowedThread() const { 80 #if 0 81 if (!allowed_thread_initialized_) { 82 allowed_thread_ = PlatformThread::CurrentId(); 83 allowed_thread_initialized_ = true; 84 } 85 return allowed_thread_ == PlatformThread::CurrentId(); 86 #else 87 // The previous version of this check used GetCurrentThread on Windows to 88 // get thread handles to compare. Unfortunately, GetCurrentThread returns 89 // a constant psuedo-handle (0xFFFFFFFE), and therefore IsAllowedThread 90 // always returned true. The above code that's turned off is the correct 91 // code, but causes the tree to turn red because some caller isn't 92 // respecting our thread requirements. We're turning off the check for now; 93 // bug http://b/issue?id=1338969 has been filed to fix things and turn the 94 // check back on. 95 return true; 96 #endif 97 } 98 #endif 99 100 DISALLOW_EVIL_CONSTRUCTORS(URLRequestJobManager); 101 }; 102 103 #endif // NET_URL_REQUEST_URL_REQUEST_JOB_MANAGER_H__ 104