Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Side by Side Diff: components/cronet/ios/Cronet.mm

Issue 2146643002: [Cronet] Integrate CrNet functionality into Cronet on iOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Andrei's comments. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "components/cronet/ios/Cronet.h" 5 #import "components/cronet/ios/Cronet.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/mac/scoped_block.h"
11 #include "base/memory/scoped_vector.h" 12 #include "base/memory/scoped_vector.h"
12 #include "base/strings/sys_string_conversions.h" 13 #include "base/strings/sys_string_conversions.h"
13 #include "components/cronet/ios/cronet_environment.h" 14 #include "components/cronet/ios/cronet_environment.h"
14 #include "components/cronet/url_request_context_config.h" 15 #include "components/cronet/url_request_context_config.h"
16 #include "ios/net/crn_http_protocol_handler.h"
17 #include "ios/net/empty_nsurlcache.h"
18 #include "net/cert/cert_verifier.h"
19 #include "net/url_request/url_request_context_getter.h"
15 20
16 namespace { 21 namespace {
17 22
18 // Currently there is one and only one instance of CronetEnvironment, 23 // Currently there is one and only one instance of CronetEnvironment,
19 // which is leaked at the shutdown. We should consider allowing multiple 24 // which is leaked at the shutdown. We should consider allowing multiple
20 // instances if that makes sense in the future. 25 // instances if that makes sense in the future.
21 base::LazyInstance<std::unique_ptr<cronet::CronetEnvironment>>::Leaky 26 base::LazyInstance<std::unique_ptr<cronet::CronetEnvironment>>::Leaky
22 gChromeNet = LAZY_INSTANCE_INITIALIZER; 27 gChromeNet = LAZY_INSTANCE_INITIALIZER;
23 28
24 BOOL gHttp2Enabled = YES; 29 BOOL gHttp2Enabled = YES;
25 BOOL gQuicEnabled = NO; 30 BOOL gQuicEnabled = NO;
26 ScopedVector<cronet::URLRequestContextConfig::QuicHint> gQuicHints; 31 ScopedVector<cronet::URLRequestContextConfig::QuicHint> gQuicHints;
27 NSString* gUserAgent = nil; 32 NSString* gUserAgent = nil;
33 std::unique_ptr<net::CertVerifier> gMockCertVerifierForTesting;
34 NSString* gHostResolverRulesForTesting = @"";
28 NSString* gSslKeyLogFileName = nil; 35 NSString* gSslKeyLogFileName = nil;
36 RequestFilterBlock gRequestFilterBlock = nil;
37 std::unique_ptr<net::HTTPProtocolHandlerDelegate> gHttpProtocolHandlerDelegate;
38
39 // net::HTTPProtocolHandlerDelegate for Cronet.
40 class CronetHttpProtocolHandlerDelegate
41 : public net::HTTPProtocolHandlerDelegate {
42 public:
43 CronetHttpProtocolHandlerDelegate(net::URLRequestContextGetter* getter,
44 RequestFilterBlock filter)
45 : 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
46
47 private:
48 // net::HTTPProtocolHandlerDelegate implementation:
49 bool CanHandleRequest(NSURLRequest* request) override {
50 if (filter_) {
51 RequestFilterBlock block = filter_.get();
52 return block(request);
53 }
54 return true;
55 }
56
57 bool IsRequestSupported(NSURLRequest* request) override {
58 NSString* scheme = [[request URL] scheme];
59 if (!scheme)
60 return false;
61 return [scheme caseInsensitiveCompare:@"data"] == NSOrderedSame ||
62 [scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
63 [scheme caseInsensitiveCompare:@"https"] == NSOrderedSame;
64 }
65
66 net::URLRequestContextGetter* GetDefaultURLRequestContext() override {
67 return getter_.get();
68 }
69
70 scoped_refptr<net::URLRequestContextGetter> getter_;
71 base::mac::ScopedBlock<RequestFilterBlock> filter_;
72 };
29 73
30 } // namespace 74 } // namespace
31 75
32 @implementation Cronet 76 @implementation Cronet
33 77
34 + (void)checkNotStarted { 78 + (void)checkNotStarted {
35 CHECK(gChromeNet == NULL) << "Cronet is already started."; 79 CHECK(gChromeNet == NULL) << "Cronet is already started.";
36 } 80 }
37 81
38 + (void)setHttp2Enabled:(BOOL)http2Enabled { 82 + (void)setHttp2Enabled:(BOOL)http2Enabled {
(...skipping 10 matching lines...) Expand all
49 [self checkNotStarted]; 93 [self checkNotStarted];
50 gQuicHints.push_back(new cronet::URLRequestContextConfig::QuicHint( 94 gQuicHints.push_back(new cronet::URLRequestContextConfig::QuicHint(
51 base::SysNSStringToUTF8(host), port, altPort)); 95 base::SysNSStringToUTF8(host), port, altPort));
52 } 96 }
53 97
54 + (void)setPartialUserAgent:(NSString*)userAgent { 98 + (void)setPartialUserAgent:(NSString*)userAgent {
55 [self checkNotStarted]; 99 [self checkNotStarted];
56 gUserAgent = userAgent; 100 gUserAgent = userAgent;
57 } 101 }
58 102
103 + (void)setMockCertVerifierForTesting:(void*)mockCertVerifierForTesting {
104 [self checkNotStarted];
105 gMockCertVerifierForTesting.reset(
106 reinterpret_cast<net::CertVerifier*>(mockCertVerifierForTesting));
107 }
108
109 + (void)setHostResolverRulesForTesting:(NSString*)hostResolverRulesForTesting {
110 [self checkNotStarted];
111 gHostResolverRulesForTesting = hostResolverRulesForTesting;
112 }
113
59 + (void)setSslKeyLogFileName:(NSString*)sslKeyLogFileName { 114 + (void)setSslKeyLogFileName:(NSString*)sslKeyLogFileName {
60 [self checkNotStarted]; 115 [self checkNotStarted];
61 gSslKeyLogFileName = sslKeyLogFileName; 116 gSslKeyLogFileName = sslKeyLogFileName;
62 } 117 }
63 118
119 + (void)setRequestFilterBlock:(RequestFilterBlock)block {
120 [self checkNotStarted];
121 gRequestFilterBlock = block;
122 }
123
64 + (void)startInternal { 124 + (void)startInternal {
65 cronet::CronetEnvironment::Initialize(); 125 cronet::CronetEnvironment::Initialize();
66 std::string partialUserAgent = base::SysNSStringToUTF8(gUserAgent); 126 std::string partialUserAgent = base::SysNSStringToUTF8(gUserAgent);
67 gChromeNet.Get().reset(new cronet::CronetEnvironment(partialUserAgent)); 127 gChromeNet.Get().reset(new cronet::CronetEnvironment(partialUserAgent));
68 128
69 gChromeNet.Get()->set_http2_enabled(gHttp2Enabled); 129 gChromeNet.Get()->set_http2_enabled(gHttp2Enabled);
70 gChromeNet.Get()->set_quic_enabled(gQuicEnabled); 130 gChromeNet.Get()->set_quic_enabled(gQuicEnabled);
71 gChromeNet.Get()->set_ssl_key_log_file_name( 131 gChromeNet.Get()->set_ssl_key_log_file_name(
72 base::SysNSStringToUTF8(gSslKeyLogFileName)); 132 base::SysNSStringToUTF8(gSslKeyLogFileName));
73 for (const auto* quicHint : gQuicHints) { 133 for (const auto* quicHint : gQuicHints) {
74 gChromeNet.Get()->AddQuicHint(quicHint->host, quicHint->port, 134 gChromeNet.Get()->AddQuicHint(quicHint->host, quicHint->port,
75 quicHint->alternate_port); 135 quicHint->alternate_port);
76 } 136 }
137 gChromeNet.Get()->set_host_resolver_rules(
138 [gHostResolverRulesForTesting UTF8String]);
139 gChromeNet.Get()->set_cert_verifier(std::move(gMockCertVerifierForTesting));
140
77 gChromeNet.Get()->Start(); 141 gChromeNet.Get()->Start();
142 gHttpProtocolHandlerDelegate.reset(new CronetHttpProtocolHandlerDelegate(
143 gChromeNet.Get()->GetURLRequestContextGetter(), gRequestFilterBlock));
144 net::HTTPProtocolHandlerDelegate::SetInstance(
145 gHttpProtocolHandlerDelegate.get());
78 } 146 }
79 147
80 + (void)start { 148 + (void)start {
81 static dispatch_once_t onceToken; 149 static dispatch_once_t onceToken;
82 dispatch_once(&onceToken, ^{ 150 dispatch_once(&onceToken, ^{
83 if (![NSThread isMainThread]) { 151 if (![NSThread isMainThread]) {
84 dispatch_sync(dispatch_get_main_queue(), ^(void) { 152 dispatch_sync(dispatch_get_main_queue(), ^(void) {
85 [self startInternal]; 153 [self startInternal];
86 }); 154 });
87 } else { 155 } else {
88 [self startInternal]; 156 [self startInternal];
89 } 157 }
90 }); 158 });
91 } 159 }
92 160
161 + (void)registerHttpProtocolHandler {
162 // Disable the default cache.
163 [NSURLCache setSharedURLCache:[EmptyNSURLCache emptyNSURLCache]];
164 // Register the chrome http protocol handler to replace the default one.
165 BOOL success =
166 [NSURLProtocol registerClass:[CRNPauseableHTTPProtocolHandler class]];
167 DCHECK(success);
168 }
169
170 + (void)unregisterHttpProtocolHandler {
171 // Set up an empty default cache, with default size.
172 [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.
173 [NSURLProtocol unregisterClass:[CRNPauseableHTTPProtocolHandler class]];
174 }
175
176 + (void)installIntoSessionConfiguration:(NSURLSessionConfiguration*)config {
177 config.protocolClasses = @[ [CRNPauseableHTTPProtocolHandler class] ];
178 }
179
93 + (void)startNetLogToFile:(NSString*)fileName logBytes:(BOOL)logBytes { 180 + (void)startNetLogToFile:(NSString*)fileName logBytes:(BOOL)logBytes {
94 if (gChromeNet.Get().get() && [fileName length]) { 181 if (gChromeNet.Get().get() && [fileName length]) {
95 gChromeNet.Get()->StartNetLog([fileName UTF8String], logBytes); 182 gChromeNet.Get()->StartNetLog([fileName UTF8String], logBytes);
96 } 183 }
97 } 184 }
98 185
99 + (void)stopNetLog { 186 + (void)stopNetLog {
100 if (gChromeNet.Get().get()) { 187 if (gChromeNet.Get().get()) {
101 gChromeNet.Get()->StopNetLog(); 188 gChromeNet.Get()->StopNetLog();
102 } 189 }
(...skipping 11 matching lines...) Expand all
114 + (cronet_engine*)getGlobalEngine { 201 + (cronet_engine*)getGlobalEngine {
115 DCHECK(gChromeNet.Get().get()); 202 DCHECK(gChromeNet.Get().get());
116 if (gChromeNet.Get().get()) { 203 if (gChromeNet.Get().get()) {
117 static cronet_engine engine; 204 static cronet_engine engine;
118 engine.obj = gChromeNet.Get().get(); 205 engine.obj = gChromeNet.Get().get();
119 return &engine; 206 return &engine;
120 } 207 }
121 return nil; 208 return nil;
122 } 209 }
123 210
211 + (NSData*)getGlobalMetricsDeltas {
212 if (!gChromeNet.Get().get()) {
213 return nil;
214 }
215 std::vector<uint8_t> deltas(gChromeNet.Get()->GetHistogramDeltas());
216 return [NSData dataWithBytes:deltas.data() length:deltas.size()];
217 }
218
124 // This is a non-public dummy method that prevents the linker from stripping out 219 // This is a non-public dummy method that prevents the linker from stripping out
125 // the otherwise non-referenced methods from 'cronet_bidirectional_stream.cc'. 220 // the otherwise non-referenced methods from 'cronet_bidirectional_stream.cc'.
126 + (void)preventStrippingCronetBidirectionalStream { 221 + (void)preventStrippingCronetBidirectionalStream {
127 cronet_bidirectional_stream_create(NULL, 0, 0); 222 cronet_bidirectional_stream_create(NULL, 0, 0);
128 } 223 }
129 224
130 @end 225 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698