1 // Copyright 2011 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 #ifndef NET_URL_REQUEST_URL_REQUEST_FILTER_H_ 5 #define NET_URL_REQUEST_URL_REQUEST_FILTER_H_ 6 7 #include <map> 8 #include <memory> 9 #include <string> 10 #include <unordered_map> 11 12 #include "net/base/net_export.h" 13 #include "net/url_request/url_request_interceptor.h" 14 15 class GURL; 16 17 namespace net { 18 class URLRequest; 19 class URLRequestJob; 20 class URLRequestInterceptor; 21 22 // A class to help filter URLRequest jobs based on the URL of the request 23 // rather than just the scheme. Example usage: 24 // 25 // // Intercept "scheme://host/" requests. 26 // URLRequestFilter::GetInstance()->AddHostnameInterceptor( 27 // "scheme", "host", std::move(interceptor)); 28 // // Add special handling for the URL http://foo.com/ 29 // URLRequestFilter::GetInstance()->AddUrlInterceptor( 30 // GURL("http://foo.com/"), std::move(interceptor)); 31 // 32 // The URLRequestFilter is implemented as a singleton that is not thread-safe, 33 // and hence must only be used in test code where the network stack is used 34 // from a single thread. It must only be accessed on that networking thread. 35 // One exception is that during startup, before any message loops have been 36 // created, interceptors may be added (the session restore tests rely on this). 37 // If the URLRequestFilter::MaybeInterceptRequest can't find a handler for a 38 // request, it returns NULL and lets the configured ProtocolHandler handle the 39 // request. 40 class NET_EXPORT URLRequestFilter : public URLRequestInterceptor { 41 public: 42 // Singleton instance for use. 43 static URLRequestFilter* GetInstance(); 44 45 URLRequestFilter(const URLRequestFilter&) = delete; 46 URLRequestFilter& operator=(const URLRequestFilter&) = delete; 47 48 void AddHostnameInterceptor( 49 const std::string& scheme, 50 const std::string& hostname, 51 std::unique_ptr<URLRequestInterceptor> interceptor); 52 void RemoveHostnameHandler(const std::string& scheme, 53 const std::string& hostname); 54 55 // Returns true if we successfully added the URL handler. This will replace 56 // old handlers for the URL if one existed. 57 bool AddUrlInterceptor(const GURL& url, 58 std::unique_ptr<URLRequestInterceptor> interceptor); 59 60 void RemoveUrlHandler(const GURL& url); 61 62 // Clear all the existing URL and hostname handlers. Resets the hit count. 63 void ClearHandlers(); 64 65 // Returns the number of times a handler was used to service a request. hit_count()66 int hit_count() const { return hit_count_; } 67 68 // URLRequestInterceptor implementation: 69 std::unique_ptr<URLRequestJob> MaybeInterceptRequest( 70 URLRequest* request) const override; 71 72 private: 73 // scheme,hostname -> URLRequestInterceptor 74 using HostnameInterceptorMap = 75 std::map<std::pair<std::string, std::string>, 76 std::unique_ptr<URLRequestInterceptor>>; 77 // URL -> URLRequestInterceptor 78 using URLInterceptorMap = 79 std::unordered_map<std::string, std::unique_ptr<URLRequestInterceptor>>; 80 81 URLRequestFilter(); 82 ~URLRequestFilter() override; 83 84 // Maps hostnames to interceptors. Hostnames take priority over URLs. 85 HostnameInterceptorMap hostname_interceptor_map_; 86 87 // Maps URLs to interceptors. 88 URLInterceptorMap url_interceptor_map_; 89 90 mutable int hit_count_ = 0; 91 92 // Singleton instance. 93 static URLRequestFilter* shared_instance_; 94 }; 95 96 } // namespace net 97 98 #endif // NET_URL_REQUEST_URL_REQUEST_FILTER_H_ 99