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// A class to help filter URLRequest jobs based on the URL of the request
6// rather than just the scheme.  Example usage:
7//
8// // Use as an "http" handler.
9// URLRequest::RegisterProtocolFactory("http", &URLRequestFilter::Factory);
10// // Add special handling for the URL http://foo.com/
11// URLRequestFilter::GetInstance()->AddUrlHandler(
12//     GURL("http://foo.com/"),
13//     &URLRequestCustomJob::Factory);
14//
15// If URLRequestFilter::Factory can't find a handle for the request, it passes
16// it through to URLRequestInetJob::Factory and lets the default network stack
17// handle it.
18
19#ifndef NET_URL_REQUEST_URL_REQUEST_FILTER_H_
20#define NET_URL_REQUEST_URL_REQUEST_FILTER_H_
21#pragma once
22
23#include <map>
24#include <string>
25
26#include "base/hash_tables.h"
27#include "net/url_request/url_request.h"
28
29class GURL;
30
31namespace net {
32class URLRequestJob;
33
34class URLRequestFilter {
35 public:
36  // scheme,hostname -> ProtocolFactory
37  typedef std::map<std::pair<std::string, std::string>,
38      URLRequest::ProtocolFactory*> HostnameHandlerMap;
39  typedef base::hash_map<std::string, URLRequest::ProtocolFactory*>
40      UrlHandlerMap;
41
42  ~URLRequestFilter();
43
44  static URLRequest::ProtocolFactory Factory;
45
46  // Singleton instance for use.
47  static URLRequestFilter* GetInstance();
48
49  void AddHostnameHandler(const std::string& scheme,
50                          const std::string& hostname,
51                          URLRequest::ProtocolFactory* factory);
52  void RemoveHostnameHandler(const std::string& scheme,
53                             const std::string& hostname);
54
55  // Returns true if we successfully added the URL handler.  This will replace
56  // old handlers for the URL if one existed.
57  bool AddUrlHandler(const GURL& url,
58                     URLRequest::ProtocolFactory* factory);
59
60  void RemoveUrlHandler(const GURL& url);
61
62  // Clear all the existing URL handlers and unregister with the
63  // ProtocolFactory.  Resets the hit count.
64  void ClearHandlers();
65
66  // Returns the number of times a handler was used to service a request.
67  int hit_count() const { return hit_count_; }
68
69 protected:
70  URLRequestFilter();
71
72  // Helper method that looks up the request in the url_handler_map_.
73  URLRequestJob* FindRequestHandler(URLRequest* request,
74                                    const std::string& scheme);
75
76  // Maps hostnames to factories.  Hostnames take priority over URLs.
77  HostnameHandlerMap hostname_handler_map_;
78
79  // Maps URLs to factories.
80  UrlHandlerMap url_handler_map_;
81
82  int hit_count_;
83
84 private:
85  // Singleton instance.
86  static URLRequestFilter* shared_instance_;
87
88  DISALLOW_COPY_AND_ASSIGN(URLRequestFilter);
89};
90
91}  // namespace net
92
93#endif  // NET_URL_REQUEST_URL_REQUEST_FILTER_H_
94