OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "ios/net/request_tracker.h" |
| 6 |
| 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" |
| 10 |
| 11 namespace net { |
| 12 |
| 13 namespace { |
| 14 |
| 15 // Reference to the single instance of the RequestTrackerFactory. |
| 16 RequestTracker::RequestTrackerFactory* g_request_tracker_factory = nullptr; |
| 17 |
| 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 } |
| 27 |
| 28 // Gets the factories. |
| 29 NSArray* GetFactories() { |
| 30 DCHECK(thread_checker_.CalledOnValidThread()); |
| 31 return factories_.get(); |
| 32 } |
| 33 |
| 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 } |
| 45 |
| 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 } |
| 54 |
| 55 private: |
| 56 GlobalNetworkClientFactories() : factories_([[NSMutableArray alloc] init]) {} |
| 57 |
| 58 base::scoped_nsobject<NSMutableArray> factories_; |
| 59 base::ThreadChecker thread_checker_; |
| 60 |
| 61 static GlobalNetworkClientFactories* g_global_network_client_factories; |
| 62 }; |
| 63 |
| 64 GlobalNetworkClientFactories* |
| 65 GlobalNetworkClientFactories::g_global_network_client_factories = nullptr; |
| 66 |
| 67 } // namespace |
| 68 |
| 69 // static |
| 70 void RequestTracker::SetRequestTrackerFactory(RequestTrackerFactory* factory) { |
| 71 g_request_tracker_factory = factory; |
| 72 } |
| 73 |
| 74 // static |
| 75 bool RequestTracker::GetRequestTracker(NSURLRequest* request, |
| 76 base::WeakPtr<RequestTracker>* tracker) { |
| 77 DCHECK(request); |
| 78 DCHECK(tracker); |
| 79 DCHECK(!tracker->get()); |
| 80 if (!g_request_tracker_factory) { |
| 81 return true; |
| 82 } |
| 83 return g_request_tracker_factory->GetRequestTracker(request, tracker); |
| 84 } |
| 85 |
| 86 void RequestTracker::AddNetworkClientFactory( |
| 87 CRNForwardingNetworkClientFactory* factory) { |
| 88 DCHECK(thread_checker_.CalledOnValidThread()); |
| 89 DCHECK([[factory clientClass] |
| 90 isSubclassOfClass:[CRNForwardingNetworkClient class]]); |
| 91 // Sanity check: We don't already have a factory of the type being added. |
| 92 DCHECK([client_factories_ indexOfObjectPassingTest:^BOOL(id obj, |
| 93 NSUInteger idx, |
| 94 BOOL* stop) { |
| 95 return [obj clientClass] == [factory clientClass]; |
| 96 }] == NSNotFound); |
| 97 [client_factories_ addObject:factory]; |
| 98 if ([factory requiresOrdering]) { |
| 99 [client_factories_ sortUsingSelector:@selector(orderRelativeTo:)]; |
| 100 } |
| 101 } |
| 102 |
| 103 // static |
| 104 void RequestTracker::AddGlobalNetworkClientFactory( |
| 105 CRNForwardingNetworkClientFactory* factory) { |
| 106 GlobalNetworkClientFactories::GetInstance()->AddFactory(factory); |
| 107 } |
| 108 |
| 109 RequestTracker::RequestTracker() |
| 110 : client_factories_([[NSMutableArray alloc] init]), |
| 111 initialized_(false), |
| 112 cache_mode_(CACHE_NORMAL), |
| 113 weak_ptr_factory_(this) { |
| 114 // RequestTracker can be created from the main thread and used from another |
| 115 // thread. |
| 116 thread_checker_.DetachFromThread(); |
| 117 } |
| 118 |
| 119 RequestTracker::~RequestTracker() { |
| 120 } |
| 121 |
| 122 base::WeakPtr<RequestTracker> RequestTracker::GetWeakPtr() { |
| 123 return weak_ptr_factory_.GetWeakPtr(); |
| 124 } |
| 125 |
| 126 void RequestTracker::InvalidateWeakPtrs() { |
| 127 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 128 } |
| 129 |
| 130 void RequestTracker::Init() { |
| 131 DCHECK(thread_checker_.CalledOnValidThread()); |
| 132 DCHECK(!initialized_); |
| 133 initialized_ = true; |
| 134 for (CRNForwardingNetworkClientFactory* factory in |
| 135 GlobalNetworkClientFactories::GetInstance()->GetFactories()) { |
| 136 AddNetworkClientFactory(factory); |
| 137 } |
| 138 } |
| 139 |
| 140 // static |
| 141 NSArray* RequestTracker::GlobalClientsHandlingAnyRequest() { |
| 142 NSMutableArray* applicable_clients = [NSMutableArray array]; |
| 143 for (CRNForwardingNetworkClientFactory* factory in |
| 144 GlobalNetworkClientFactories::GetInstance()->GetFactories()) { |
| 145 CRNForwardingNetworkClient* client = [factory clientHandlingAnyRequest]; |
| 146 if (client) |
| 147 [applicable_clients addObject:client]; |
| 148 } |
| 149 return applicable_clients; |
| 150 } |
| 151 |
| 152 NSArray* RequestTracker::ClientsHandlingAnyRequest() { |
| 153 DCHECK(thread_checker_.CalledOnValidThread()); |
| 154 DCHECK(initialized_); |
| 155 NSMutableArray* applicable_clients = [NSMutableArray array]; |
| 156 for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) { |
| 157 CRNForwardingNetworkClient* client = [factory clientHandlingAnyRequest]; |
| 158 if (client) |
| 159 [applicable_clients addObject:client]; |
| 160 } |
| 161 return applicable_clients; |
| 162 } |
| 163 |
| 164 NSArray* RequestTracker::ClientsHandlingRequest(const URLRequest& request) { |
| 165 DCHECK(thread_checker_.CalledOnValidThread()); |
| 166 DCHECK(initialized_); |
| 167 NSMutableArray* applicable_clients = [NSMutableArray array]; |
| 168 for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) { |
| 169 CRNForwardingNetworkClient* client = |
| 170 [factory clientHandlingRequest:request]; |
| 171 if (client) |
| 172 [applicable_clients addObject:client]; |
| 173 } |
| 174 return applicable_clients; |
| 175 } |
| 176 |
| 177 NSArray* RequestTracker::ClientsHandlingRequestAndResponse( |
| 178 const URLRequest& request, |
| 179 NSURLResponse* response) { |
| 180 DCHECK(thread_checker_.CalledOnValidThread()); |
| 181 DCHECK(initialized_); |
| 182 NSMutableArray* applicable_clients = [NSMutableArray array]; |
| 183 for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) { |
| 184 CRNForwardingNetworkClient* client = |
| 185 [factory clientHandlingResponse:response request:request]; |
| 186 if (client) |
| 187 [applicable_clients addObject:client]; |
| 188 } |
| 189 return applicable_clients; |
| 190 } |
| 191 |
| 192 NSArray* RequestTracker::ClientsHandlingRedirect( |
| 193 const URLRequest& request, |
| 194 const GURL& new_url, |
| 195 NSURLResponse* redirect_response) { |
| 196 DCHECK(thread_checker_.CalledOnValidThread()); |
| 197 DCHECK(initialized_); |
| 198 NSMutableArray* applicable_clients = [NSMutableArray array]; |
| 199 for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) { |
| 200 CRNForwardingNetworkClient* client = |
| 201 [factory clientHandlingRedirect:request |
| 202 url:new_url |
| 203 response:redirect_response]; |
| 204 if (client) |
| 205 [applicable_clients addObject:client]; |
| 206 } |
| 207 return applicable_clients; |
| 208 } |
| 209 |
| 210 RequestTracker::CacheMode RequestTracker::GetCacheMode() const { |
| 211 DCHECK(thread_checker_.CalledOnValidThread()); |
| 212 return cache_mode_; |
| 213 } |
| 214 |
| 215 void RequestTracker::SetCacheMode(RequestTracker::CacheMode mode) { |
| 216 DCHECK(thread_checker_.CalledOnValidThread()); |
| 217 cache_mode_ = mode; |
| 218 } |
| 219 |
| 220 } // namespace net |
OLD | NEW |