• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "net/url_request/url_request_filter.h"
6 
7 #include <set>
8 
9 #include "base/logging.h"
10 
11 URLRequestFilter* URLRequestFilter::shared_instance_ = NULL;
12 
13 /* static */
GetInstance()14 URLRequestFilter* URLRequestFilter::GetInstance() {
15   if (!shared_instance_)
16     shared_instance_ = new URLRequestFilter;
17   return shared_instance_;
18 }
19 
20 /* static */
Factory(URLRequest * request,const std::string & scheme)21 URLRequestJob* URLRequestFilter::Factory(URLRequest* request,
22                                          const std::string& scheme) {
23   // Returning null here just means that the built-in handler will be used.
24   return GetInstance()->FindRequestHandler(request, scheme);
25 }
26 
AddHostnameHandler(const std::string & scheme,const std::string & hostname,URLRequest::ProtocolFactory * factory)27 void URLRequestFilter::AddHostnameHandler(const std::string& scheme,
28     const std::string& hostname, URLRequest::ProtocolFactory* factory) {
29   hostname_handler_map_[make_pair(scheme, hostname)] = factory;
30 
31   // Register with the ProtocolFactory.
32   URLRequest::RegisterProtocolFactory(scheme,
33                                       &URLRequestFilter::Factory);
34 
35 #ifndef NDEBUG
36   // Check to see if we're masking URLs in the url_handler_map_.
37   for (UrlHandlerMap::const_iterator i = url_handler_map_.begin();
38        i != url_handler_map_.end(); ++i) {
39     const GURL& url = GURL(i->first);
40     HostnameHandlerMap::iterator host_it =
41         hostname_handler_map_.find(make_pair(url.scheme(), url.host()));
42     if (host_it != hostname_handler_map_.end())
43       NOTREACHED();
44   }
45 #endif  // !NDEBUG
46 }
47 
RemoveHostnameHandler(const std::string & scheme,const std::string & hostname)48 void URLRequestFilter::RemoveHostnameHandler(const std::string& scheme,
49                                              const std::string& hostname) {
50   HostnameHandlerMap::iterator iter =
51       hostname_handler_map_.find(make_pair(scheme, hostname));
52   DCHECK(iter != hostname_handler_map_.end());
53 
54   hostname_handler_map_.erase(iter);
55   // Note that we don't unregister from the URLRequest ProtocolFactory as this
56   // would left no protocol factory for the scheme.  URLRequestFilter::Factory
57   // will keep forwarding the requests to the URLRequestInetJob.
58 }
59 
AddUrlHandler(const GURL & url,URLRequest::ProtocolFactory * factory)60 bool URLRequestFilter::AddUrlHandler(const GURL& url,
61                                      URLRequest::ProtocolFactory* factory) {
62   if (!url.is_valid())
63     return false;
64   url_handler_map_[url.spec()] = factory;
65 
66   // Register with the ProtocolFactory.
67   URLRequest::RegisterProtocolFactory(url.scheme(),
68                                       &URLRequestFilter::Factory);
69 #ifndef NDEBUG
70   // Check to see if this URL is masked by a hostname handler.
71   HostnameHandlerMap::iterator host_it =
72       hostname_handler_map_.find(make_pair(url.scheme(), url.host()));
73   if (host_it != hostname_handler_map_.end())
74     NOTREACHED();
75 #endif  // !NDEBUG
76 
77   return true;
78 }
79 
RemoveUrlHandler(const GURL & url)80 void URLRequestFilter::RemoveUrlHandler(const GURL& url) {
81   UrlHandlerMap::iterator iter = url_handler_map_.find(url.spec());
82   DCHECK(iter != url_handler_map_.end());
83 
84   url_handler_map_.erase(iter);
85   // Note that we don't unregister from the URLRequest ProtocolFactory as this
86   // would left no protocol factory for the scheme.  URLRequestFilter::Factory
87   // will keep forwarding the requests to the URLRequestInetJob.
88 }
89 
ClearHandlers()90 void URLRequestFilter::ClearHandlers() {
91   // Unregister with the ProtocolFactory.
92   std::set<std::string> schemes;
93   for (UrlHandlerMap::const_iterator i = url_handler_map_.begin();
94        i != url_handler_map_.end(); ++i) {
95     schemes.insert(GURL(i->first).scheme());
96   }
97   for (HostnameHandlerMap::const_iterator i = hostname_handler_map_.begin();
98        i != hostname_handler_map_.end(); ++i) {
99     schemes.insert(i->first.first);
100   }
101   for (std::set<std::string>::const_iterator scheme = schemes.begin();
102        scheme != schemes.end(); ++scheme) {
103     URLRequest::RegisterProtocolFactory(*scheme, NULL);
104   }
105 
106   url_handler_map_.clear();
107   hostname_handler_map_.clear();
108   hit_count_ = 0;
109 }
110 
FindRequestHandler(URLRequest * request,const std::string & scheme)111 URLRequestJob* URLRequestFilter::FindRequestHandler(URLRequest* request,
112                                                     const std::string& scheme) {
113   URLRequestJob* job = NULL;
114   if (request->url().is_valid()) {
115     // Check the hostname map first.
116     const std::string& hostname = request->url().host();
117 
118     HostnameHandlerMap::iterator i =
119         hostname_handler_map_.find(make_pair(scheme, hostname));
120     if (i != hostname_handler_map_.end())
121       job = i->second(request, scheme);
122 
123     if (!job) {
124       // Not in the hostname map, check the url map.
125       const std::string& url = request->url().spec();
126       UrlHandlerMap::iterator i = url_handler_map_.find(url);
127       if (i != url_handler_map_.end())
128         job = i->second(request, scheme);
129     }
130   }
131   if (job) {
132     DLOG(INFO) << "URLRequestFilter hit for " << request->url().spec();
133     hit_count_++;
134   }
135   return job;
136 }
137