url_request_filter.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_filter.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestFilter* URLRequestFilter::shared_instance_ = NULL; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestFilter::~URLRequestFilter() {} 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestJob* URLRequestFilter::Factory(URLRequest* request, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkDelegate* network_delegate, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returning null here just means that the built-in handler will be used. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetInstance()->FindRequestHandler(request, network_delegate, scheme); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestFilter* URLRequestFilter::GetInstance() { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shared_instance_) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_instance_ = new URLRequestFilter; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return shared_instance_; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFilter::AddHostnameHandler(const std::string& scheme, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& hostname, URLRequest::ProtocolFactory* factory) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_handler_map_[make_pair(scheme, hostname)] = factory; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register with the ProtocolFactory. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequest::Deprecated::RegisterProtocolFactory( 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme, &URLRequestFilter::Factory); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check to see if we're masking URLs in the url_handler_map_. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (UrlHandlerMap::const_iterator i = url_handler_map_.begin(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != url_handler_map_.end(); ++i) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url = GURL(i->first); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostnameHandlerMap::iterator host_it = 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_handler_map_.find(make_pair(url.scheme(), url.host())); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_it != hostname_handler_map_.end()) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !NDEBUG 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFilter::RemoveHostnameHandler(const std::string& scheme, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& hostname) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostnameHandlerMap::iterator iter = 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_handler_map_.find(make_pair(scheme, hostname)); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(iter != hostname_handler_map_.end()); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_handler_map_.erase(iter); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we don't unregister from the URLRequest ProtocolFactory as 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this would left no protocol factory for the scheme. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequestFilter::Factory will keep forwarding the requests to the 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequestInetJob. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestFilter::AddUrlHandler( 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequest::ProtocolFactory* factory) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_valid()) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_handler_map_[url.spec()] = factory; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register with the ProtocolFactory. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequest::Deprecated::RegisterProtocolFactory(url.scheme(), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &URLRequestFilter::Factory); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check to see if this URL is masked by a hostname handler. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostnameHandlerMap::iterator host_it = 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_handler_map_.find(make_pair(url.scheme(), url.host())); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_it != hostname_handler_map_.end()) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !NDEBUG 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFilter::RemoveUrlHandler(const GURL& url) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UrlHandlerMap::iterator iter = url_handler_map_.find(url.spec()); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(iter != url_handler_map_.end()); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_handler_map_.erase(iter); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we don't unregister from the URLRequest ProtocolFactory as 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this would left no protocol factory for the scheme. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequestFilter::Factory will keep forwarding the requests to the 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequestInetJob. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestFilter::ClearHandlers() { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unregister with the ProtocolFactory. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string> schemes; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (UrlHandlerMap::const_iterator i = url_handler_map_.begin(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != url_handler_map_.end(); ++i) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemes.insert(GURL(i->first).scheme()); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (HostnameHandlerMap::const_iterator i = hostname_handler_map_.begin(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != hostname_handler_map_.end(); ++i) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemes.insert(i->first.first); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<std::string>::const_iterator scheme = schemes.begin(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme != schemes.end(); ++scheme) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequest::Deprecated::RegisterProtocolFactory(*scheme, NULL); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_handler_map_.clear(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_handler_map_.clear(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hit_count_ = 0; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestFilter::URLRequestFilter() : hit_count_(0) { } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestJob* URLRequestFilter::FindRequestHandler( 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequest* request, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetworkDelegate* network_delegate, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestJob* job = NULL; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request->url().is_valid()) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the hostname map first. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& hostname = request->url().host(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostnameHandlerMap::iterator i = 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostname_handler_map_.find(make_pair(scheme, hostname)); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != hostname_handler_map_.end()) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job = i->second(request, network_delegate, scheme); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!job) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not in the hostname map, check the url map. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& url = request->url().spec(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UrlHandlerMap::iterator i = url_handler_map_.find(url); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != url_handler_map_.end()) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job = i->second(request, network_delegate, scheme); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (job) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "URLRequestFilter hit for " << request->url().spec(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hit_count_++; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return job; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 151