xref: /aosp_15_r20/external/cronet/net/url_request/url_request_filter.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #ifndef NET_URL_REQUEST_URL_REQUEST_FILTER_H_
5 #define NET_URL_REQUEST_URL_REQUEST_FILTER_H_
6 
7 #include <map>
8 #include <memory>
9 #include <string>
10 #include <unordered_map>
11 
12 #include "net/base/net_export.h"
13 #include "net/url_request/url_request_interceptor.h"
14 
15 class GURL;
16 
17 namespace net {
18 class URLRequest;
19 class URLRequestJob;
20 class URLRequestInterceptor;
21 
22 // A class to help filter URLRequest jobs based on the URL of the request
23 // rather than just the scheme.  Example usage:
24 //
25 // // Intercept "scheme://host/" requests.
26 // URLRequestFilter::GetInstance()->AddHostnameInterceptor(
27 //     "scheme", "host", std::move(interceptor));
28 // // Add special handling for the URL http://foo.com/
29 // URLRequestFilter::GetInstance()->AddUrlInterceptor(
30 //     GURL("http://foo.com/"), std::move(interceptor));
31 //
32 // The URLRequestFilter is implemented as a singleton that is not thread-safe,
33 // and hence must only be used in test code where the network stack is used
34 // from a single thread. It must only be accessed on that networking thread.
35 // One exception is that during startup, before any message loops have been
36 // created, interceptors may be added (the session restore tests rely on this).
37 // If the URLRequestFilter::MaybeInterceptRequest can't find a handler for a
38 // request, it returns NULL and lets the configured ProtocolHandler handle the
39 // request.
40 class NET_EXPORT URLRequestFilter : public URLRequestInterceptor {
41  public:
42   // Singleton instance for use.
43   static URLRequestFilter* GetInstance();
44 
45   URLRequestFilter(const URLRequestFilter&) = delete;
46   URLRequestFilter& operator=(const URLRequestFilter&) = delete;
47 
48   void AddHostnameInterceptor(
49       const std::string& scheme,
50       const std::string& hostname,
51       std::unique_ptr<URLRequestInterceptor> interceptor);
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 AddUrlInterceptor(const GURL& url,
58                          std::unique_ptr<URLRequestInterceptor> interceptor);
59 
60   void RemoveUrlHandler(const GURL& url);
61 
62   // Clear all the existing URL and hostname handlers.  Resets the hit count.
63   void ClearHandlers();
64 
65   // Returns the number of times a handler was used to service a request.
hit_count()66   int hit_count() const { return hit_count_; }
67 
68   // URLRequestInterceptor implementation:
69   std::unique_ptr<URLRequestJob> MaybeInterceptRequest(
70       URLRequest* request) const override;
71 
72  private:
73   // scheme,hostname -> URLRequestInterceptor
74   using HostnameInterceptorMap =
75       std::map<std::pair<std::string, std::string>,
76                std::unique_ptr<URLRequestInterceptor>>;
77   // URL -> URLRequestInterceptor
78   using URLInterceptorMap =
79       std::unordered_map<std::string, std::unique_ptr<URLRequestInterceptor>>;
80 
81   URLRequestFilter();
82   ~URLRequestFilter() override;
83 
84   // Maps hostnames to interceptors.  Hostnames take priority over URLs.
85   HostnameInterceptorMap hostname_interceptor_map_;
86 
87   // Maps URLs to interceptors.
88   URLInterceptorMap url_interceptor_map_;
89 
90   mutable int hit_count_ = 0;
91 
92   // Singleton instance.
93   static URLRequestFilter* shared_instance_;
94 };
95 
96 }  // namespace net
97 
98 #endif  // NET_URL_REQUEST_URL_REQUEST_FILTER_H_
99