| Index: ios/net/request_tracker.mm
|
| diff --git a/ios/net/request_tracker.mm b/ios/net/request_tracker.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c984f3610a334babc4f195527562a86a9a0502b8
|
| --- /dev/null
|
| +++ b/ios/net/request_tracker.mm
|
| @@ -0,0 +1,220 @@
|
| +// Copyright 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ios/net/request_tracker.h"
|
| +
|
| +#include "base/logging.h"
|
| +#import "ios/net/clients/crn_forwarding_network_client.h"
|
| +#import "ios/net/clients/crn_forwarding_network_client_factory.h"
|
| +
|
| +namespace net {
|
| +
|
| +namespace {
|
| +
|
| +// Reference to the single instance of the RequestTrackerFactory.
|
| +RequestTracker::RequestTrackerFactory* g_request_tracker_factory = nullptr;
|
| +
|
| +// Array of network client factories that should be added to any new request
|
| +// tracker.
|
| +class GlobalNetworkClientFactories {
|
| + public:
|
| + static GlobalNetworkClientFactories* GetInstance() {
|
| + if (!g_global_network_client_factories)
|
| + g_global_network_client_factories = new GlobalNetworkClientFactories;
|
| + return g_global_network_client_factories;
|
| + }
|
| +
|
| + // Gets the factories.
|
| + NSArray* GetFactories() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + return factories_.get();
|
| + }
|
| +
|
| + // Adds a factory.
|
| + void AddFactory(CRNForwardingNetworkClientFactory* factory) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK_EQ(NSNotFound, [factories_ indexOfObject:factory]);
|
| + DCHECK(!IsSelectorOverriden(factory, @selector(clientHandlingRequest:)));
|
| + DCHECK(!IsSelectorOverriden(factory,
|
| + @selector(clientHandlingResponse:request:)));
|
| + DCHECK(!IsSelectorOverriden(
|
| + factory, @selector(clientHandlingRedirect:url:response:)));
|
| + [factories_ addObject:factory];
|
| + }
|
| +
|
| + // Returns true if |factory| re-implements |selector|.
|
| + // Only used for debugging.
|
| + bool IsSelectorOverriden(CRNForwardingNetworkClientFactory* factory,
|
| + SEL selector) {
|
| + return
|
| + [factory methodForSelector:selector] !=
|
| + [CRNForwardingNetworkClientFactory instanceMethodForSelector:selector];
|
| + }
|
| +
|
| + private:
|
| + GlobalNetworkClientFactories() : factories_([[NSMutableArray alloc] init]) {}
|
| +
|
| + base::scoped_nsobject<NSMutableArray> factories_;
|
| + base::ThreadChecker thread_checker_;
|
| +
|
| + static GlobalNetworkClientFactories* g_global_network_client_factories;
|
| +};
|
| +
|
| +GlobalNetworkClientFactories*
|
| + GlobalNetworkClientFactories::g_global_network_client_factories = nullptr;
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +void RequestTracker::SetRequestTrackerFactory(RequestTrackerFactory* factory) {
|
| + g_request_tracker_factory = factory;
|
| +}
|
| +
|
| +// static
|
| +bool RequestTracker::GetRequestTracker(NSURLRequest* request,
|
| + base::WeakPtr<RequestTracker>* tracker) {
|
| + DCHECK(request);
|
| + DCHECK(tracker);
|
| + DCHECK(!tracker->get());
|
| + if (!g_request_tracker_factory) {
|
| + return true;
|
| + }
|
| + return g_request_tracker_factory->GetRequestTracker(request, tracker);
|
| +}
|
| +
|
| +void RequestTracker::AddNetworkClientFactory(
|
| + CRNForwardingNetworkClientFactory* factory) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK([[factory clientClass]
|
| + isSubclassOfClass:[CRNForwardingNetworkClient class]]);
|
| + // Sanity check: We don't already have a factory of the type being added.
|
| + DCHECK([client_factories_ indexOfObjectPassingTest:^BOOL(id obj,
|
| + NSUInteger idx,
|
| + BOOL* stop) {
|
| + return [obj clientClass] == [factory clientClass];
|
| + }] == NSNotFound);
|
| + [client_factories_ addObject:factory];
|
| + if ([factory requiresOrdering]) {
|
| + [client_factories_ sortUsingSelector:@selector(orderRelativeTo:)];
|
| + }
|
| +}
|
| +
|
| +// static
|
| +void RequestTracker::AddGlobalNetworkClientFactory(
|
| + CRNForwardingNetworkClientFactory* factory) {
|
| + GlobalNetworkClientFactories::GetInstance()->AddFactory(factory);
|
| +}
|
| +
|
| +RequestTracker::RequestTracker()
|
| + : client_factories_([[NSMutableArray alloc] init]),
|
| + initialized_(false),
|
| + cache_mode_(CACHE_NORMAL),
|
| + weak_ptr_factory_(this) {
|
| + // RequestTracker can be created from the main thread and used from another
|
| + // thread.
|
| + thread_checker_.DetachFromThread();
|
| +}
|
| +
|
| +RequestTracker::~RequestTracker() {
|
| +}
|
| +
|
| +base::WeakPtr<RequestTracker> RequestTracker::GetWeakPtr() {
|
| + return weak_ptr_factory_.GetWeakPtr();
|
| +}
|
| +
|
| +void RequestTracker::InvalidateWeakPtrs() {
|
| + weak_ptr_factory_.InvalidateWeakPtrs();
|
| +}
|
| +
|
| +void RequestTracker::Init() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK(!initialized_);
|
| + initialized_ = true;
|
| + for (CRNForwardingNetworkClientFactory* factory in
|
| + GlobalNetworkClientFactories::GetInstance()->GetFactories()) {
|
| + AddNetworkClientFactory(factory);
|
| + }
|
| +}
|
| +
|
| +// static
|
| +NSArray* RequestTracker::GlobalClientsHandlingAnyRequest() {
|
| + NSMutableArray* applicable_clients = [NSMutableArray array];
|
| + for (CRNForwardingNetworkClientFactory* factory in
|
| + GlobalNetworkClientFactories::GetInstance()->GetFactories()) {
|
| + CRNForwardingNetworkClient* client = [factory clientHandlingAnyRequest];
|
| + if (client)
|
| + [applicable_clients addObject:client];
|
| + }
|
| + return applicable_clients;
|
| +}
|
| +
|
| +NSArray* RequestTracker::ClientsHandlingAnyRequest() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK(initialized_);
|
| + NSMutableArray* applicable_clients = [NSMutableArray array];
|
| + for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
|
| + CRNForwardingNetworkClient* client = [factory clientHandlingAnyRequest];
|
| + if (client)
|
| + [applicable_clients addObject:client];
|
| + }
|
| + return applicable_clients;
|
| +}
|
| +
|
| +NSArray* RequestTracker::ClientsHandlingRequest(const URLRequest& request) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK(initialized_);
|
| + NSMutableArray* applicable_clients = [NSMutableArray array];
|
| + for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
|
| + CRNForwardingNetworkClient* client =
|
| + [factory clientHandlingRequest:request];
|
| + if (client)
|
| + [applicable_clients addObject:client];
|
| + }
|
| + return applicable_clients;
|
| +}
|
| +
|
| +NSArray* RequestTracker::ClientsHandlingRequestAndResponse(
|
| + const URLRequest& request,
|
| + NSURLResponse* response) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK(initialized_);
|
| + NSMutableArray* applicable_clients = [NSMutableArray array];
|
| + for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
|
| + CRNForwardingNetworkClient* client =
|
| + [factory clientHandlingResponse:response request:request];
|
| + if (client)
|
| + [applicable_clients addObject:client];
|
| + }
|
| + return applicable_clients;
|
| +}
|
| +
|
| +NSArray* RequestTracker::ClientsHandlingRedirect(
|
| + const URLRequest& request,
|
| + const GURL& new_url,
|
| + NSURLResponse* redirect_response) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK(initialized_);
|
| + NSMutableArray* applicable_clients = [NSMutableArray array];
|
| + for (CRNForwardingNetworkClientFactory* factory in client_factories_.get()) {
|
| + CRNForwardingNetworkClient* client =
|
| + [factory clientHandlingRedirect:request
|
| + url:new_url
|
| + response:redirect_response];
|
| + if (client)
|
| + [applicable_clients addObject:client];
|
| + }
|
| + return applicable_clients;
|
| +}
|
| +
|
| +RequestTracker::CacheMode RequestTracker::GetCacheMode() const {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + return cache_mode_;
|
| +}
|
| +
|
| +void RequestTracker::SetCacheMode(RequestTracker::CacheMode mode) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + cache_mode_ = mode;
|
| +}
|
| +
|
| +} // namespace net
|
|
|