Roll src/third_party/WebKit f36d5e0:68b67cd (svn 193299:193303)
[chromium-blink-merge.git] / ios / net / request_tracker.mm
blob6eb21c3f7e231177b7b23987332a3e684a2bc8be
1 // Copyright 2012 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 "ios/net/request_tracker.h"
7 #include "base/logging.h"
8 #import "ios/net/clients/crn_forwarding_network_client.h"
9 #import "ios/net/clients/crn_forwarding_network_client_factory.h"
11 namespace net {
13 namespace {
15 // Reference to the single instance of the RequestTrackerFactory.
16 RequestTracker::RequestTrackerFactory* g_request_tracker_factory = nullptr;
18 // Array of network client factories that should be added to any new request
19 // tracker.
20 class GlobalNetworkClientFactories {
21  public:
22   static GlobalNetworkClientFactories* GetInstance() {
23     if (!g_global_network_client_factories)
24       g_global_network_client_factories = new GlobalNetworkClientFactories;
25     return g_global_network_client_factories;
26   }
28   // Gets the factories.
29   NSArray* GetFactories() {
30     DCHECK(thread_checker_.CalledOnValidThread());
31     return factories_.get();
32   }
34   // Adds a factory.
35   void AddFactory(CRNForwardingNetworkClientFactory* factory) {
36     DCHECK(thread_checker_.CalledOnValidThread());
37     DCHECK_EQ(NSNotFound, [factories_ indexOfObject:factory]);
38     DCHECK(!IsSelectorOverriden(factory, @selector(clientHandlingRequest:)));
39     DCHECK(!IsSelectorOverriden(factory,
40                                 @selector(clientHandlingResponse:request:)));
41     DCHECK(!IsSelectorOverriden(
42                factory, @selector(clientHandlingRedirect:url:response:)));
43     [factories_ addObject:factory];
44   }
46   // Returns true if |factory| re-implements |selector|.
47   // Only used for debugging.
48   bool IsSelectorOverriden(CRNForwardingNetworkClientFactory* factory,
49                            SEL selector) {
50     return
51         [factory methodForSelector:selector] !=
52         [CRNForwardingNetworkClientFactory instanceMethodForSelector:selector];
53   }
55  private:
56   GlobalNetworkClientFactories() : factories_([[NSMutableArray alloc] init]) {}
58   base::scoped_nsobject<NSMutableArray> factories_;
59   base::ThreadChecker thread_checker_;
61   static GlobalNetworkClientFactories* g_global_network_client_factories;
64 GlobalNetworkClientFactories*
65     GlobalNetworkClientFactories::g_global_network_client_factories = nullptr;
67 }  // namespace
69 RequestTracker::RequestTrackerFactory::~RequestTrackerFactory() {
72 // static
73 void RequestTracker::SetRequestTrackerFactory(RequestTrackerFactory* factory) {
74   g_request_tracker_factory = factory;
77 // static
78 bool RequestTracker::GetRequestTracker(NSURLRequest* request,
79                                        base::WeakPtr<RequestTracker>* tracker) {
80   DCHECK(request);
81   DCHECK(tracker);
82   DCHECK(!tracker->get());
83   if (!g_request_tracker_factory) {
84     return true;
85   }
86   return g_request_tracker_factory->GetRequestTracker(request, tracker);
89 void RequestTracker::AddNetworkClientFactory(
90     CRNForwardingNetworkClientFactory* factory) {
91   DCHECK(thread_checker_.CalledOnValidThread());
92   DCHECK([[factory clientClass]
93       isSubclassOfClass:[CRNForwardingNetworkClient class]]);
94   // Sanity check: We don't already have a factory of the type being added.
95   DCHECK([client_factories_ indexOfObjectPassingTest:^BOOL(id obj,
96                                                            NSUInteger idx,
97                                                            BOOL* stop) {
98       return [obj clientClass] == [factory clientClass];
99   }] == NSNotFound);
100   [client_factories_ addObject:factory];
101   if ([factory requiresOrdering]) {
102     [client_factories_ sortUsingSelector:@selector(orderRelativeTo:)];
103   }
106 // static
107 void RequestTracker::AddGlobalNetworkClientFactory(
108     CRNForwardingNetworkClientFactory* factory) {
109   GlobalNetworkClientFactories::GetInstance()->AddFactory(factory);
112 RequestTracker::RequestTracker()
113     : client_factories_([[NSMutableArray alloc] init]),
114       initialized_(false),
115       cache_mode_(CACHE_NORMAL),
116       weak_ptr_factory_(this) {
117   // RequestTracker can be created from the main thread and used from another
118   // thread.
119   thread_checker_.DetachFromThread();
122 RequestTracker::~RequestTracker() {
125 base::WeakPtr<RequestTracker> RequestTracker::GetWeakPtr() {
126   return weak_ptr_factory_.GetWeakPtr();
129 void RequestTracker::InvalidateWeakPtrs() {
130   weak_ptr_factory_.InvalidateWeakPtrs();
133 void RequestTracker::Init() {
134   DCHECK(thread_checker_.CalledOnValidThread());
135   DCHECK(!initialized_);
136   initialized_ = true;
137   for (CRNForwardingNetworkClientFactory* factory in
138            GlobalNetworkClientFactories::GetInstance()->GetFactories()) {
139     AddNetworkClientFactory(factory);
140   }
143 // static
144 NSArray* RequestTracker::GlobalClientsHandlingAnyRequest() {
145   NSMutableArray* applicable_clients = [NSMutableArray array];
146   for (CRNForwardingNetworkClientFactory* factory in
147            GlobalNetworkClientFactories::GetInstance()->GetFactories()) {
148     CRNForwardingNetworkClient* client = [factory clientHandlingAnyRequest];
149     if (client)
150       [applicable_clients addObject:client];
151   }
152   return applicable_clients;
155 NSArray* RequestTracker::ClientsHandlingAnyRequest() {
156   DCHECK(thread_checker_.CalledOnValidThread());
157   DCHECK(initialized_);
158   NSMutableArray* applicable_clients = [NSMutableArray array];
159   for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
160     CRNForwardingNetworkClient* client = [factory clientHandlingAnyRequest];
161     if (client)
162       [applicable_clients addObject:client];
163   }
164   return applicable_clients;
167 NSArray* RequestTracker::ClientsHandlingRequest(const URLRequest& request) {
168   DCHECK(thread_checker_.CalledOnValidThread());
169   DCHECK(initialized_);
170   NSMutableArray* applicable_clients = [NSMutableArray array];
171   for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
172     CRNForwardingNetworkClient* client =
173         [factory clientHandlingRequest:request];
174     if (client)
175       [applicable_clients addObject:client];
176   }
177   return applicable_clients;
180 NSArray* RequestTracker::ClientsHandlingRequestAndResponse(
181     const URLRequest& request,
182     NSURLResponse* response) {
183   DCHECK(thread_checker_.CalledOnValidThread());
184   DCHECK(initialized_);
185   NSMutableArray* applicable_clients = [NSMutableArray array];
186   for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
187     CRNForwardingNetworkClient* client =
188         [factory clientHandlingResponse:response request:request];
189     if (client)
190       [applicable_clients addObject:client];
191   }
192   return applicable_clients;
195 NSArray* RequestTracker::ClientsHandlingRedirect(
196     const URLRequest& request,
197     const GURL& new_url,
198     NSURLResponse* redirect_response) {
199   DCHECK(thread_checker_.CalledOnValidThread());
200   DCHECK(initialized_);
201   NSMutableArray* applicable_clients = [NSMutableArray array];
202   for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
203     CRNForwardingNetworkClient* client =
204         [factory clientHandlingRedirect:request
205                                     url:new_url
206                                response:redirect_response];
207     if (client)
208       [applicable_clients addObject:client];
209   }
210   return applicable_clients;
213 RequestTracker::CacheMode RequestTracker::GetCacheMode() const {
214   DCHECK(thread_checker_.CalledOnValidThread());
215   return cache_mode_;
218 void RequestTracker::SetCacheMode(RequestTracker::CacheMode mode) {
219   DCHECK(thread_checker_.CalledOnValidThread());
220   cache_mode_ = mode;
223 }  // namespace net