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