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.
5 #include "net/url_request/url_request_filter.h"
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "net/url_request/url_request_job_factory_impl.h"
17 class URLRequestFilterInterceptor
: public URLRequestInterceptor
{
19 explicit URLRequestFilterInterceptor(URLRequest::ProtocolFactory
* factory
)
20 : factory_(factory
) {}
21 virtual ~URLRequestFilterInterceptor() {}
23 // URLRequestInterceptor implementation.
24 virtual URLRequestJob
* MaybeInterceptRequest(
25 URLRequest
* request
, NetworkDelegate
* network_delegate
) const OVERRIDE
{
26 return factory_(request
, network_delegate
, request
->url().scheme());
30 URLRequest::ProtocolFactory
* factory_
;
32 DISALLOW_COPY_AND_ASSIGN(URLRequestFilterInterceptor
);
37 URLRequestFilter
* URLRequestFilter::shared_instance_
= NULL
;
40 URLRequestFilter
* URLRequestFilter::GetInstance() {
41 if (!shared_instance_
)
42 shared_instance_
= new URLRequestFilter
;
43 return shared_instance_
;
46 void URLRequestFilter::AddHostnameHandler(const std::string
& scheme
,
47 const std::string
& hostname
, URLRequest::ProtocolFactory
* factory
) {
48 AddHostnameInterceptor(
50 scoped_ptr
<URLRequestInterceptor
>(
51 new URLRequestFilterInterceptor(factory
)));
54 void URLRequestFilter::AddHostnameInterceptor(
55 const std::string
& scheme
,
56 const std::string
& hostname
,
57 scoped_ptr
<URLRequestInterceptor
> interceptor
) {
58 DCHECK_EQ(0u, hostname_interceptor_map_
.count(make_pair(scheme
, hostname
)));
59 hostname_interceptor_map_
[make_pair(scheme
, hostname
)] =
60 interceptor
.release();
63 // Check to see if we're masking URLs in the url_interceptor_map_.
64 for (URLInterceptorMap::const_iterator it
= url_interceptor_map_
.begin();
65 it
!= url_interceptor_map_
.end(); ++it
) {
66 const GURL
& url
= GURL(it
->first
);
67 HostnameInterceptorMap::const_iterator host_it
=
68 hostname_interceptor_map_
.find(make_pair(url
.scheme(), url
.host()));
69 if (host_it
!= hostname_interceptor_map_
.end())
75 void URLRequestFilter::RemoveHostnameHandler(const std::string
& scheme
,
76 const std::string
& hostname
) {
77 HostnameInterceptorMap::iterator it
=
78 hostname_interceptor_map_
.find(make_pair(scheme
, hostname
));
79 DCHECK(it
!= hostname_interceptor_map_
.end());
82 hostname_interceptor_map_
.erase(it
);
83 // Note that we don't unregister from the URLRequest ProtocolFactory as
84 // this would leave no protocol factory for the remaining hostname and URL
88 bool URLRequestFilter::AddUrlHandler(
90 URLRequest::ProtocolFactory
* factory
) {
91 return AddUrlInterceptor(
93 scoped_ptr
<URLRequestInterceptor
>(
94 new URLRequestFilterInterceptor(factory
)));
97 bool URLRequestFilter::AddUrlInterceptor(
99 scoped_ptr
<URLRequestInterceptor
> interceptor
) {
102 DCHECK_EQ(0u, url_interceptor_map_
.count(url
.spec()));
103 url_interceptor_map_
[url
.spec()] = interceptor
.release();
105 // Check to see if this URL is masked by a hostname handler.
106 DCHECK_EQ(0u, hostname_interceptor_map_
.count(make_pair(url
.scheme(),
112 void URLRequestFilter::RemoveUrlHandler(const GURL
& url
) {
113 URLInterceptorMap::iterator it
= url_interceptor_map_
.find(url
.spec());
114 DCHECK(it
!= url_interceptor_map_
.end());
117 url_interceptor_map_
.erase(it
);
118 // Note that we don't unregister from the URLRequest ProtocolFactory as
119 // this would leave no protocol factory for the remaining hostname and URL
123 void URLRequestFilter::ClearHandlers() {
124 STLDeleteValues(&url_interceptor_map_
);
125 STLDeleteValues(&hostname_interceptor_map_
);
129 URLRequestJob
* URLRequestFilter::MaybeInterceptRequest(
131 NetworkDelegate
* network_delegate
) const {
132 URLRequestJob
* job
= NULL
;
133 if (!request
->url().is_valid())
136 // Check the hostname map first.
137 const std::string hostname
= request
->url().host();
138 const std::string scheme
= request
->url().scheme();
140 HostnameInterceptorMap::const_iterator it
=
141 hostname_interceptor_map_
.find(make_pair(scheme
, hostname
));
142 if (it
!= hostname_interceptor_map_
.end())
143 job
= it
->second
->MaybeInterceptRequest(request
, network_delegate
);
146 // Not in the hostname map, check the url map.
147 const std::string
& url
= request
->url().spec();
148 URLInterceptorMap::const_iterator it
= url_interceptor_map_
.find(url
);
149 if (it
!= url_interceptor_map_
.end())
150 job
= it
->second
->MaybeInterceptRequest(request
, network_delegate
);
153 DVLOG(1) << "URLRequestFilter hit for " << request
->url().spec();
159 URLRequestFilter::URLRequestFilter() : hit_count_(0) {
160 URLRequestJobFactoryImpl::SetInterceptorForTesting(this);
163 URLRequestFilter::~URLRequestFilter() {
164 URLRequestJobFactoryImpl::SetInterceptorForTesting(NULL
);