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

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: Sync Created 4 years, 2 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
« no previous file with comments | « components/cronet/ios/Cronet.h ('k') | components/cronet/ios/CronetTestSupport.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
12 #include "base/memory/ptr_util.h"
11 #include "base/memory/scoped_vector.h" 13 #include "base/memory/scoped_vector.h"
12 #include "base/strings/sys_string_conversions.h" 14 #include "base/strings/sys_string_conversions.h"
13 #include "components/cronet/ios/cronet_environment.h" 15 #include "components/cronet/ios/cronet_environment.h"
14 #include "components/cronet/url_request_context_config.h" 16 #include "components/cronet/url_request_context_config.h"
17 #import "components/cronet/ios/CronetTestSupport.h" // nogncheck
18 #include "ios/net/crn_http_protocol_handler.h"
19 #include "ios/net/empty_nsurlcache.h"
20 #include "net/cert/cert_verifier.h"
21 #include "net/url_request/url_request_context_getter.h"
15 22
16 namespace { 23 namespace {
17 24
25 class CronetHttpProtocolHandlerDelegate;
26
18 // Currently there is one and only one instance of CronetEnvironment, 27 // Currently there is one and only one instance of CronetEnvironment,
19 // which is leaked at the shutdown. We should consider allowing multiple 28 // which is leaked at the shutdown. We should consider allowing multiple
20 // instances if that makes sense in the future. 29 // instances if that makes sense in the future.
21 base::LazyInstance<std::unique_ptr<cronet::CronetEnvironment>>::Leaky 30 base::LazyInstance<std::unique_ptr<cronet::CronetEnvironment>>::Leaky
22 gChromeNet = LAZY_INSTANCE_INITIALIZER; 31 gChromeNet = LAZY_INSTANCE_INITIALIZER;
23 32
24 BOOL gHttp2Enabled = YES; 33 BOOL gHttp2Enabled = YES;
25 BOOL gQuicEnabled = NO; 34 BOOL gQuicEnabled = NO;
26 ScopedVector<cronet::URLRequestContextConfig::QuicHint> gQuicHints; 35 ScopedVector<cronet::URLRequestContextConfig::QuicHint> gQuicHints;
27 NSString* gUserAgent = nil; 36 NSString* gUserAgent = nil;
37 BOOL gUserAgentPartial = NO;
28 NSString* gSslKeyLogFileName = nil; 38 NSString* gSslKeyLogFileName = nil;
39 RequestFilterBlock gRequestFilterBlock = nil;
40 std::unique_ptr<CronetHttpProtocolHandlerDelegate> gHttpProtocolHandlerDelegate;
41 NSURLCache* gPreservedSharedURLCache = nil;
42 BOOL gEnableTestCertVerifierForTesting = FALSE;
43 NSString* gHostResolverRulesForTesting = @"";
44
45 // CertVerifier, which allows any certificates for testing.
46 class TestCertVerifier : public net::CertVerifier {
47 int Verify(const RequestParams& params,
48 net::CRLSet* crl_set,
49 net::CertVerifyResult* verify_result,
50 const net::CompletionCallback& callback,
51 std::unique_ptr<Request>* out_req,
52 const net::NetLogWithSource& net_log) override {
53 net::Error result = net::OK;
54 verify_result->verified_cert = params.certificate();
55 verify_result->cert_status = net::MapNetErrorToCertStatus(result);
56 return result;
57 }
58 };
59
60 // net::HTTPProtocolHandlerDelegate for Cronet.
61 class CronetHttpProtocolHandlerDelegate
62 : public net::HTTPProtocolHandlerDelegate {
63 public:
64 CronetHttpProtocolHandlerDelegate(net::URLRequestContextGetter* getter,
65 RequestFilterBlock filter)
66 : getter_(getter), filter_(filter, base::scoped_policy::RETAIN) {}
67
68 void SetRequestFilterBlock(RequestFilterBlock filter) {
69 filter_.reset(filter);
70 }
71
72 private:
73 // net::HTTPProtocolHandlerDelegate implementation:
74 bool CanHandleRequest(NSURLRequest* request) override {
75 if (filter_) {
76 RequestFilterBlock block = filter_.get();
77 return block(request);
78 }
79 return true;
80 }
81
82 bool IsRequestSupported(NSURLRequest* request) override {
83 NSString* scheme = [[request URL] scheme];
84 if (!scheme)
85 return false;
86 return [scheme caseInsensitiveCompare:@"data"] == NSOrderedSame ||
87 [scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
88 [scheme caseInsensitiveCompare:@"https"] == NSOrderedSame;
89 }
90
91 net::URLRequestContextGetter* GetDefaultURLRequestContext() override {
92 return getter_.get();
93 }
94
95 scoped_refptr<net::URLRequestContextGetter> getter_;
96 base::mac::ScopedBlock<RequestFilterBlock> filter_;
97 };
29 98
30 } // namespace 99 } // namespace
31 100
32 @implementation Cronet 101 @implementation Cronet
33 102
34 + (void)checkNotStarted { 103 + (void)checkNotStarted {
35 CHECK(gChromeNet == NULL) << "Cronet is already started."; 104 CHECK(gChromeNet == NULL) << "Cronet is already started.";
36 } 105 }
37 106
38 + (void)setHttp2Enabled:(BOOL)http2Enabled { 107 + (void)setHttp2Enabled:(BOOL)http2Enabled {
39 [self checkNotStarted]; 108 [self checkNotStarted];
40 gHttp2Enabled = http2Enabled; 109 gHttp2Enabled = http2Enabled;
41 } 110 }
42 111
43 + (void)setQuicEnabled:(BOOL)quicEnabled { 112 + (void)setQuicEnabled:(BOOL)quicEnabled {
44 [self checkNotStarted]; 113 [self checkNotStarted];
45 gQuicEnabled = quicEnabled; 114 gQuicEnabled = quicEnabled;
46 } 115 }
47 116
48 + (void)addQuicHint:(NSString*)host port:(int)port altPort:(int)altPort { 117 + (void)addQuicHint:(NSString*)host port:(int)port altPort:(int)altPort {
49 [self checkNotStarted]; 118 [self checkNotStarted];
50 gQuicHints.push_back(new cronet::URLRequestContextConfig::QuicHint( 119 gQuicHints.push_back(new cronet::URLRequestContextConfig::QuicHint(
51 base::SysNSStringToUTF8(host), port, altPort)); 120 base::SysNSStringToUTF8(host), port, altPort));
52 } 121 }
53 122
54 + (void)setPartialUserAgent:(NSString*)userAgent { 123 + (void)setUserAgent:(NSString*)userAgent partial:(bool)partial {
55 [self checkNotStarted]; 124 [self checkNotStarted];
56 gUserAgent = userAgent; 125 gUserAgent = userAgent;
126 gUserAgentPartial = partial;
57 } 127 }
58 128
59 + (void)setSslKeyLogFileName:(NSString*)sslKeyLogFileName { 129 + (void)setSslKeyLogFileName:(NSString*)sslKeyLogFileName {
60 [self checkNotStarted]; 130 [self checkNotStarted];
61 gSslKeyLogFileName = sslKeyLogFileName; 131 gSslKeyLogFileName = sslKeyLogFileName;
62 } 132 }
63 133
134 + (void)setRequestFilterBlock:(RequestFilterBlock)block {
135 if (gHttpProtocolHandlerDelegate.get())
136 gHttpProtocolHandlerDelegate.get()->SetRequestFilterBlock(block);
137 else
138 gRequestFilterBlock = block;
139 }
140
141 + (void)configureCronetEnvironmentForTesting:
142 (cronet::CronetEnvironment*)cronetEnvironment {
143 DLOG(ERROR) << "configureCronetEnvironment for testing";
144 cronetEnvironment->set_host_resolver_rules(
145 [gHostResolverRulesForTesting UTF8String]);
146 if (gEnableTestCertVerifierForTesting) {
147 std::unique_ptr<TestCertVerifier> test_cert_verifier =
148 base::MakeUnique<TestCertVerifier>();
149 cronetEnvironment->set_cert_verifier(std::move(test_cert_verifier));
150 }
151 }
152
64 + (void)startInternal { 153 + (void)startInternal {
65 cronet::CronetEnvironment::Initialize(); 154 cronet::CronetEnvironment::Initialize();
66 std::string partialUserAgent = base::SysNSStringToUTF8(gUserAgent); 155 std::string user_agent = base::SysNSStringToUTF8(gUserAgent);
67 gChromeNet.Get().reset(new cronet::CronetEnvironment(partialUserAgent)); 156 gChromeNet.Get().reset(
157 new cronet::CronetEnvironment(user_agent, gUserAgentPartial));
68 158
69 gChromeNet.Get()->set_http2_enabled(gHttp2Enabled); 159 gChromeNet.Get()->set_http2_enabled(gHttp2Enabled);
70 gChromeNet.Get()->set_quic_enabled(gQuicEnabled); 160 gChromeNet.Get()->set_quic_enabled(gQuicEnabled);
71 gChromeNet.Get()->set_ssl_key_log_file_name( 161 gChromeNet.Get()->set_ssl_key_log_file_name(
72 base::SysNSStringToUTF8(gSslKeyLogFileName)); 162 base::SysNSStringToUTF8(gSslKeyLogFileName));
73 for (const auto* quicHint : gQuicHints) { 163 for (const auto* quicHint : gQuicHints) {
74 gChromeNet.Get()->AddQuicHint(quicHint->host, quicHint->port, 164 gChromeNet.Get()->AddQuicHint(quicHint->host, quicHint->port,
75 quicHint->alternate_port); 165 quicHint->alternate_port);
76 } 166 }
167
168 [self configureCronetEnvironmentForTesting:gChromeNet.Get().get()];
77 gChromeNet.Get()->Start(); 169 gChromeNet.Get()->Start();
170 gHttpProtocolHandlerDelegate.reset(new CronetHttpProtocolHandlerDelegate(
171 gChromeNet.Get()->GetURLRequestContextGetter(), gRequestFilterBlock));
172 net::HTTPProtocolHandlerDelegate::SetInstance(
173 gHttpProtocolHandlerDelegate.get());
174 gRequestFilterBlock = nil;
78 } 175 }
79 176
80 + (void)start { 177 + (void)start {
81 static dispatch_once_t onceToken; 178 static dispatch_once_t onceToken;
82 dispatch_once(&onceToken, ^{ 179 dispatch_once(&onceToken, ^{
83 if (![NSThread isMainThread]) { 180 if (![NSThread isMainThread]) {
84 dispatch_sync(dispatch_get_main_queue(), ^(void) { 181 dispatch_sync(dispatch_get_main_queue(), ^(void) {
85 [self startInternal]; 182 [self startInternal];
86 }); 183 });
87 } else { 184 } else {
88 [self startInternal]; 185 [self startInternal];
89 } 186 }
90 }); 187 });
91 } 188 }
92 189
190 + (void)registerHttpProtocolHandler {
191 if (gPreservedSharedURLCache == nil) {
192 gPreservedSharedURLCache = [NSURLCache sharedURLCache];
193 }
194 // Disable the default cache.
195 [NSURLCache setSharedURLCache:[EmptyNSURLCache emptyNSURLCache]];
196 // Register the chrome http protocol handler to replace the default one.
197 BOOL success =
198 [NSURLProtocol registerClass:[CRNPauseableHTTPProtocolHandler class]];
199 DCHECK(success);
200 }
201
202 + (void)unregisterHttpProtocolHandler {
203 // Set up SharedURLCache preserved in registerHttpProtocolHandler.
204 if (gPreservedSharedURLCache != nil) {
205 [NSURLCache setSharedURLCache:gPreservedSharedURLCache];
206 gPreservedSharedURLCache = nil;
207 }
208 [NSURLProtocol unregisterClass:[CRNPauseableHTTPProtocolHandler class]];
209 }
210
211 + (void)installIntoSessionConfiguration:(NSURLSessionConfiguration*)config {
212 config.protocolClasses = @[ [CRNPauseableHTTPProtocolHandler class] ];
213 }
214
93 + (void)startNetLogToFile:(NSString*)fileName logBytes:(BOOL)logBytes { 215 + (void)startNetLogToFile:(NSString*)fileName logBytes:(BOOL)logBytes {
94 if (gChromeNet.Get().get() && [fileName length]) { 216 if (gChromeNet.Get().get() && [fileName length]) {
95 gChromeNet.Get()->StartNetLog([fileName UTF8String], logBytes); 217 gChromeNet.Get()->StartNetLog([fileName UTF8String], logBytes);
96 } 218 }
97 } 219 }
98 220
99 + (void)stopNetLog { 221 + (void)stopNetLog {
100 if (gChromeNet.Get().get()) { 222 if (gChromeNet.Get().get()) {
101 gChromeNet.Get()->StopNetLog(); 223 gChromeNet.Get()->StopNetLog();
102 } 224 }
(...skipping 11 matching lines...) Expand all
114 + (cronet_engine*)getGlobalEngine { 236 + (cronet_engine*)getGlobalEngine {
115 DCHECK(gChromeNet.Get().get()); 237 DCHECK(gChromeNet.Get().get());
116 if (gChromeNet.Get().get()) { 238 if (gChromeNet.Get().get()) {
117 static cronet_engine engine; 239 static cronet_engine engine;
118 engine.obj = gChromeNet.Get().get(); 240 engine.obj = gChromeNet.Get().get();
119 return &engine; 241 return &engine;
120 } 242 }
121 return nil; 243 return nil;
122 } 244 }
123 245
246 + (NSData*)getGlobalMetricsDeltas {
247 if (!gChromeNet.Get().get()) {
248 return nil;
249 }
250 std::vector<uint8_t> deltas(gChromeNet.Get()->GetHistogramDeltas());
251 return [NSData dataWithBytes:deltas.data() length:deltas.size()];
252 }
253
254 + (void)enableTestCertVerifierForTesting {
255 gEnableTestCertVerifierForTesting = TRUE;
256 }
257
258 + (void)setHostResolverRulesForTesting:(NSString*)hostResolverRulesForTesting {
259 gHostResolverRulesForTesting = hostResolverRulesForTesting;
260 }
261
124 // This is a non-public dummy method that prevents the linker from stripping out 262 // 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'. 263 // the otherwise non-referenced methods from 'cronet_bidirectional_stream.cc'.
126 + (void)preventStrippingCronetBidirectionalStream { 264 + (void)preventStrippingCronetBidirectionalStream {
127 cronet_bidirectional_stream_create(NULL, 0, 0); 265 cronet_bidirectional_stream_create(NULL, 0, 0);
128 } 266 }
129 267
130 @end 268 @end
OLDNEW
« no previous file with comments | « components/cronet/ios/Cronet.h ('k') | components/cronet/ios/CronetTestSupport.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698