Index: components/cronet/ios/Cronet.mm |
diff --git a/components/cronet/ios/Cronet.mm b/components/cronet/ios/Cronet.mm |
index c397eefbdebd9035ae0f0189127e5caa26b961aa..18817fb297e0e9fa3146824855b49dc5275b6849 100644 |
--- a/components/cronet/ios/Cronet.mm |
+++ b/components/cronet/ios/Cronet.mm |
@@ -8,10 +8,15 @@ |
#include "base/lazy_instance.h" |
#include "base/logging.h" |
+#include "base/mac/scoped_block.h" |
#include "base/memory/scoped_vector.h" |
#include "base/strings/sys_string_conversions.h" |
#include "components/cronet/ios/cronet_environment.h" |
#include "components/cronet/url_request_context_config.h" |
+#include "ios/net/crn_http_protocol_handler.h" |
+#include "ios/net/empty_nsurlcache.h" |
+#include "net/cert/cert_verifier.h" |
+#include "net/url_request/url_request_context_getter.h" |
namespace { |
@@ -25,7 +30,46 @@ BOOL gHttp2Enabled = YES; |
BOOL gQuicEnabled = NO; |
ScopedVector<cronet::URLRequestContextConfig::QuicHint> gQuicHints; |
NSString* gUserAgent = nil; |
+std::unique_ptr<net::CertVerifier> gMockCertVerifierForTesting; |
+NSString* gHostResolverRulesForTesting = @""; |
NSString* gSslKeyLogFileName = nil; |
+RequestFilterBlock gRequestFilterBlock = nil; |
+std::unique_ptr<net::HTTPProtocolHandlerDelegate> gHttpProtocolHandlerDelegate; |
+ |
+// net::HTTPProtocolHandlerDelegate for Cronet. |
+class CronetHttpProtocolHandlerDelegate |
+ : public net::HTTPProtocolHandlerDelegate { |
+ public: |
+ CronetHttpProtocolHandlerDelegate(net::URLRequestContextGetter* getter, |
+ RequestFilterBlock filter) |
+ : getter_(getter), filter_(filter, base::scoped_policy::RETAIN) {} |
kapishnikov
2016/08/12 17:19:31
As previously noted, RETAIN can potentially create
mef
2016/08/26 14:58:07
Ack. Changed it to allow setting new (nil) block t
|
+ |
+ private: |
+ // net::HTTPProtocolHandlerDelegate implementation: |
+ bool CanHandleRequest(NSURLRequest* request) override { |
+ if (filter_) { |
+ RequestFilterBlock block = filter_.get(); |
+ return block(request); |
+ } |
+ return true; |
+ } |
+ |
+ bool IsRequestSupported(NSURLRequest* request) override { |
+ NSString* scheme = [[request URL] scheme]; |
+ if (!scheme) |
+ return false; |
+ return [scheme caseInsensitiveCompare:@"data"] == NSOrderedSame || |
+ [scheme caseInsensitiveCompare:@"http"] == NSOrderedSame || |
+ [scheme caseInsensitiveCompare:@"https"] == NSOrderedSame; |
+ } |
+ |
+ net::URLRequestContextGetter* GetDefaultURLRequestContext() override { |
+ return getter_.get(); |
+ } |
+ |
+ scoped_refptr<net::URLRequestContextGetter> getter_; |
+ base::mac::ScopedBlock<RequestFilterBlock> filter_; |
+}; |
} // namespace |
@@ -56,11 +100,27 @@ NSString* gSslKeyLogFileName = nil; |
gUserAgent = userAgent; |
} |
++ (void)setMockCertVerifierForTesting:(void*)mockCertVerifierForTesting { |
+ [self checkNotStarted]; |
+ gMockCertVerifierForTesting.reset( |
+ reinterpret_cast<net::CertVerifier*>(mockCertVerifierForTesting)); |
+} |
+ |
++ (void)setHostResolverRulesForTesting:(NSString*)hostResolverRulesForTesting { |
+ [self checkNotStarted]; |
+ gHostResolverRulesForTesting = hostResolverRulesForTesting; |
+} |
+ |
+ (void)setSslKeyLogFileName:(NSString*)sslKeyLogFileName { |
[self checkNotStarted]; |
gSslKeyLogFileName = sslKeyLogFileName; |
} |
++ (void)setRequestFilterBlock:(RequestFilterBlock)block { |
+ [self checkNotStarted]; |
+ gRequestFilterBlock = block; |
+} |
+ |
+ (void)startInternal { |
cronet::CronetEnvironment::Initialize(); |
std::string partialUserAgent = base::SysNSStringToUTF8(gUserAgent); |
@@ -74,7 +134,15 @@ NSString* gSslKeyLogFileName = nil; |
gChromeNet.Get()->AddQuicHint(quicHint->host, quicHint->port, |
quicHint->alternate_port); |
} |
+ gChromeNet.Get()->set_host_resolver_rules( |
+ [gHostResolverRulesForTesting UTF8String]); |
+ gChromeNet.Get()->set_cert_verifier(std::move(gMockCertVerifierForTesting)); |
+ |
gChromeNet.Get()->Start(); |
+ gHttpProtocolHandlerDelegate.reset(new CronetHttpProtocolHandlerDelegate( |
+ gChromeNet.Get()->GetURLRequestContextGetter(), gRequestFilterBlock)); |
+ net::HTTPProtocolHandlerDelegate::SetInstance( |
+ gHttpProtocolHandlerDelegate.get()); |
} |
+ (void)start { |
@@ -90,6 +158,25 @@ NSString* gSslKeyLogFileName = nil; |
}); |
} |
++ (void)registerHttpProtocolHandler { |
+ // Disable the default cache. |
+ [NSURLCache setSharedURLCache:[EmptyNSURLCache emptyNSURLCache]]; |
+ // Register the chrome http protocol handler to replace the default one. |
+ BOOL success = |
+ [NSURLProtocol registerClass:[CRNPauseableHTTPProtocolHandler class]]; |
+ DCHECK(success); |
+} |
+ |
++ (void)unregisterHttpProtocolHandler { |
+ // Set up an empty default cache, with default size. |
+ [NSURLCache setSharedURLCache:[[[NSURLCache alloc] init] autorelease]]; |
kapishnikov
2016/08/12 17:19:31
As noted before, [[NSURLCache alloc] init] may not
mef
2016/08/26 14:58:07
Done.
|
+ [NSURLProtocol unregisterClass:[CRNPauseableHTTPProtocolHandler class]]; |
+} |
+ |
++ (void)installIntoSessionConfiguration:(NSURLSessionConfiguration*)config { |
+ config.protocolClasses = @[ [CRNPauseableHTTPProtocolHandler class] ]; |
+} |
+ |
+ (void)startNetLogToFile:(NSString*)fileName logBytes:(BOOL)logBytes { |
if (gChromeNet.Get().get() && [fileName length]) { |
gChromeNet.Get()->StartNetLog([fileName UTF8String], logBytes); |
@@ -121,6 +208,14 @@ NSString* gSslKeyLogFileName = nil; |
return nil; |
} |
++ (NSData*)getGlobalMetricsDeltas { |
+ if (!gChromeNet.Get().get()) { |
+ return nil; |
+ } |
+ std::vector<uint8_t> deltas(gChromeNet.Get()->GetHistogramDeltas()); |
+ return [NSData dataWithBytes:deltas.data() length:deltas.size()]; |
+} |
+ |
// This is a non-public dummy method that prevents the linker from stripping out |
// the otherwise non-referenced methods from 'cronet_bidirectional_stream.cc'. |
+ (void)preventStrippingCronetBidirectionalStream { |