Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / url_request / url_request_filter.cc
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 #include "base/stl_util.h"
11 #include "net/url_request/url_request_job_factory_impl.h"
12
13 namespace net {
14
15 namespace {
16
17 class URLRequestFilterInterceptor : public URLRequestInterceptor {
18  public:
19   explicit URLRequestFilterInterceptor(URLRequest::ProtocolFactory* factory)
20       : factory_(factory) {}
21   ~URLRequestFilterInterceptor() override {}
22
23   // URLRequestInterceptor implementation.
24   URLRequestJob* MaybeInterceptRequest(
25       URLRequest* request,
26       NetworkDelegate* network_delegate) const override {
27     return factory_(request, network_delegate, request->url().scheme());
28   }
29
30  private:
31   URLRequest::ProtocolFactory* factory_;
32
33   DISALLOW_COPY_AND_ASSIGN(URLRequestFilterInterceptor);
34 };
35
36 }  // namespace
37
38 URLRequestFilter* URLRequestFilter::shared_instance_ = NULL;
39
40 // static
41 URLRequestFilter* URLRequestFilter::GetInstance() {
42   if (!shared_instance_)
43     shared_instance_ = new URLRequestFilter;
44   return shared_instance_;
45 }
46
47 void URLRequestFilter::AddHostnameHandler(const std::string& scheme,
48     const std::string& hostname, URLRequest::ProtocolFactory* factory) {
49   AddHostnameInterceptor(
50       scheme, hostname,
51       scoped_ptr<URLRequestInterceptor>(
52           new URLRequestFilterInterceptor(factory)));
53 }
54
55 void URLRequestFilter::AddHostnameInterceptor(
56     const std::string& scheme,
57     const std::string& hostname,
58     scoped_ptr<URLRequestInterceptor> interceptor) {
59   DCHECK_EQ(0u, hostname_interceptor_map_.count(make_pair(scheme, hostname)));
60   hostname_interceptor_map_[make_pair(scheme, hostname)] =
61       interceptor.release();
62
63 #ifndef NDEBUG
64   // Check to see if we're masking URLs in the url_interceptor_map_.
65   for (URLInterceptorMap::const_iterator it = url_interceptor_map_.begin();
66        it != url_interceptor_map_.end(); ++it) {
67     const GURL& url = GURL(it->first);
68     HostnameInterceptorMap::const_iterator host_it =
69         hostname_interceptor_map_.find(make_pair(url.scheme(), url.host()));
70     if (host_it != hostname_interceptor_map_.end())
71       NOTREACHED();
72   }
73 #endif  // !NDEBUG
74 }
75
76 void URLRequestFilter::RemoveHostnameHandler(const std::string& scheme,
77                                              const std::string& hostname) {
78   HostnameInterceptorMap::iterator it =
79       hostname_interceptor_map_.find(make_pair(scheme, hostname));
80   DCHECK(it != hostname_interceptor_map_.end());
81
82   delete it->second;
83   hostname_interceptor_map_.erase(it);
84   // Note that we don't unregister from the URLRequest ProtocolFactory as
85   // this would leave no protocol factory for the remaining hostname and URL
86   // handlers.
87 }
88
89 bool URLRequestFilter::AddUrlHandler(
90     const GURL& url,
91     URLRequest::ProtocolFactory* factory) {
92   return AddUrlInterceptor(
93       url,
94       scoped_ptr<URLRequestInterceptor>(
95           new URLRequestFilterInterceptor(factory)));
96 }
97
98 bool URLRequestFilter::AddUrlInterceptor(
99     const GURL& url,
100     scoped_ptr<URLRequestInterceptor> interceptor) {
101   if (!url.is_valid())
102     return false;
103   DCHECK_EQ(0u, url_interceptor_map_.count(url.spec()));
104   url_interceptor_map_[url.spec()] = interceptor.release();
105
106   // Check to see if this URL is masked by a hostname handler.
107   DCHECK_EQ(0u, hostname_interceptor_map_.count(make_pair(url.scheme(),
108                                                           url.host())));
109
110   return true;
111 }
112
113 void URLRequestFilter::RemoveUrlHandler(const GURL& url) {
114   URLInterceptorMap::iterator it = url_interceptor_map_.find(url.spec());
115   DCHECK(it != url_interceptor_map_.end());
116
117   delete it->second;
118   url_interceptor_map_.erase(it);
119   // Note that we don't unregister from the URLRequest ProtocolFactory as
120   // this would leave no protocol factory for the remaining hostname and URL
121   // handlers.
122 }
123
124 void URLRequestFilter::ClearHandlers() {
125   STLDeleteValues(&url_interceptor_map_);
126   STLDeleteValues(&hostname_interceptor_map_);
127   hit_count_ = 0;
128 }
129
130 URLRequestJob* URLRequestFilter::MaybeInterceptRequest(
131     URLRequest* request,
132     NetworkDelegate* network_delegate) const {
133   URLRequestJob* job = NULL;
134   if (!request->url().is_valid())
135     return NULL;
136
137   // Check the hostname map first.
138   const std::string hostname = request->url().host();
139   const std::string scheme = request->url().scheme();
140
141   HostnameInterceptorMap::const_iterator it =
142       hostname_interceptor_map_.find(make_pair(scheme, hostname));
143   if (it != hostname_interceptor_map_.end())
144     job = it->second->MaybeInterceptRequest(request, network_delegate);
145
146   if (!job) {
147     // Not in the hostname map, check the url map.
148     const std::string& url = request->url().spec();
149     URLInterceptorMap::const_iterator it = url_interceptor_map_.find(url);
150     if (it != url_interceptor_map_.end())
151       job = it->second->MaybeInterceptRequest(request, network_delegate);
152   }
153   if (job) {
154     DVLOG(1) << "URLRequestFilter hit for " << request->url().spec();
155     hit_count_++;
156   }
157   return job;
158 }
159
160 URLRequestFilter::URLRequestFilter() : hit_count_(0) {
161   URLRequestJobFactoryImpl::SetInterceptorForTesting(this);
162 }
163
164 URLRequestFilter::~URLRequestFilter() {
165   URLRequestJobFactoryImpl::SetInterceptorForTesting(NULL);
166 }
167
168 }  // namespace net