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"
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
20 class GlobalNetworkClientFactories {
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;
28 // Gets the factories.
29 NSArray* GetFactories() {
30 DCHECK(thread_checker_.CalledOnValidThread());
31 return factories_.get();
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];
46 // Returns true if |factory| re-implements |selector|.
47 // Only used for debugging.
48 bool IsSelectorOverriden(CRNForwardingNetworkClientFactory* factory,
51 [factory methodForSelector:selector] !=
52 [CRNForwardingNetworkClientFactory instanceMethodForSelector:selector];
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;
69 RequestTracker::RequestTrackerFactory::~RequestTrackerFactory() {
73 void RequestTracker::SetRequestTrackerFactory(RequestTrackerFactory* factory) {
74 g_request_tracker_factory = factory;
78 bool RequestTracker::GetRequestTracker(NSURLRequest* request,
79 base::WeakPtr<RequestTracker>* tracker) {
82 DCHECK(!tracker->get());
83 if (!g_request_tracker_factory) {
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,
98 return [obj clientClass] == [factory clientClass];
100 [client_factories_ addObject:factory];
101 if ([factory requiresOrdering]) {
102 [client_factories_ sortUsingSelector:@selector(orderRelativeTo:)];
107 void RequestTracker::AddGlobalNetworkClientFactory(
108 CRNForwardingNetworkClientFactory* factory) {
109 GlobalNetworkClientFactories::GetInstance()->AddFactory(factory);
112 RequestTracker::RequestTracker()
113 : client_factories_([[NSMutableArray alloc] init]),
115 cache_mode_(CACHE_NORMAL),
116 weak_ptr_factory_(this) {
117 // RequestTracker can be created from the main thread and used from another
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_);
137 for (CRNForwardingNetworkClientFactory* factory in
138 GlobalNetworkClientFactories::GetInstance()->GetFactories()) {
139 AddNetworkClientFactory(factory);
144 NSArray* RequestTracker::GlobalClientsHandlingAnyRequest() {
145 NSMutableArray* applicable_clients = [NSMutableArray array];
146 for (CRNForwardingNetworkClientFactory* factory in
147 GlobalNetworkClientFactories::GetInstance()->GetFactories()) {
148 CRNForwardingNetworkClient* client = [factory clientHandlingAnyRequest];
150 [applicable_clients addObject:client];
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];
162 [applicable_clients addObject:client];
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];
175 [applicable_clients addObject:client];
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];
190 [applicable_clients addObject:client];
192 return applicable_clients;
195 NSArray* RequestTracker::ClientsHandlingRedirect(
196 const URLRequest& request,
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
206 response:redirect_response];
208 [applicable_clients addObject:client];
210 return applicable_clients;
213 RequestTracker::CacheMode RequestTracker::GetCacheMode() const {
214 DCHECK(thread_checker_.CalledOnValidThread());
218 void RequestTracker::SetCacheMode(RequestTracker::CacheMode mode) {
219 DCHECK(thread_checker_.CalledOnValidThread());