24
24
static NSString * const kHTTPHeaderFieldContentType = @" Content-Type" ;
25
25
static NSString * const kHTTPHeaderFieldValueApplicationJSON = @" application/json" ;
26
26
27
- @interface OPTLYHTTPRequestManager ()
27
+ @interface OPTLYHTTPRequestManager () < NSURLSessionDelegate >
28
28
29
29
- (NSURLSession *)session ;
30
30
@@ -41,7 +41,7 @@ - (NSURLSession *)session {
41
41
NSURLSession *ephemeralSession = nil ;
42
42
43
43
@try {
44
- ephemeralSession = [NSURLSession sessionWithConfiguration: [NSURLSessionConfiguration ephemeralSessionConfiguration ]];
44
+ ephemeralSession = [NSURLSession sessionWithConfiguration: [NSURLSessionConfiguration ephemeralSessionConfiguration ] delegate: self delegateQueue: nil ];
45
45
ephemeralSession.configuration .TLSMinimumSupportedProtocol = kTLSProtocol12 ;
46
46
47
47
}
@@ -453,3 +453,97 @@ - (NSURL *)buildQueryURL:(NSURL *)url
453
453
}
454
454
455
455
@end
456
+
457
+ typedef enum : NSUInteger {
458
+ kOPTLY_Unknown ,
459
+ kOPTLY_CDN ,
460
+ kOPTLY_LOGX ,
461
+ kOPTLY_API ,
462
+ } OPTLYEndpointHostType;
463
+
464
+ NSString * const OPTLYDefaultEndpointHost = @" cdn.optimizely.com" ;
465
+ NSString * const OPTLYLogEventEndpointHost = @" logx.optimizely.com" ;
466
+ NSString * const OPTLYAPIEndpointHost = @" api.optimizely.com" ;
467
+
468
+ @implementation OPTLYHTTPRequestManager (NSURLSessionDelegate)
469
+ - (OPTLYEndpointHostType)hostTypeForChallenge : (NSURLAuthenticationChallenge *)challenge {
470
+ NSString *host = challenge.protectionSpace .host ;
471
+ OPTLYEndpointHostType hostType = kOPTLY_Unknown ;
472
+ if ([host isEqualToString: OPTLYDefaultEndpointHost]) {
473
+ hostType = kOPTLY_CDN ;
474
+ } else if ([host isEqualToString: OPTLYLogEventEndpointHost]) {
475
+ hostType = kOPTLY_LOGX ;
476
+ } else if ([host isEqualToString: OPTLYAPIEndpointHost]) {
477
+ hostType = kOPTLY_API ;
478
+ }
479
+ return hostType;
480
+ }
481
+
482
+ - (NSString *)certificateFileNameForHostType : (OPTLYEndpointHostType)hostType {
483
+ NSString *fileName = nil ;
484
+ switch (hostType) {
485
+ case kOPTLY_CDN :
486
+ fileName = @" cdnDump" ;
487
+ break ;
488
+ case kOPTLY_LOGX :
489
+ fileName = @" logxDump" ;
490
+ break ;
491
+ case kOPTLY_API :
492
+ fileName = @" apiDump" ;
493
+ break ;
494
+ default :
495
+ break ;
496
+ }
497
+ return fileName;
498
+ }
499
+
500
+ - (void )URLSession : (NSURLSession *)session didReceiveChallenge : (NSURLAuthenticationChallenge *)challenge
501
+ completionHandler : (void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
502
+ BOOL allowConnection = NO ;
503
+ SecTrustRef serverTrust = NULL ;
504
+
505
+ if (challenge.protectionSpace .authenticationMethod == NSURLAuthenticationMethodServerTrust ) {
506
+ OPTLYEndpointHostType hostType = [self hostTypeForChallenge: challenge];
507
+ NSString *bundleCertFileName = [self certificateFileNameForHostType: hostType];
508
+ if (bundleCertFileName != nil ) {
509
+ serverTrust = challenge.protectionSpace .serverTrust ;
510
+ SecTrustResultType sectTrustResult = kSecTrustResultInvalid ;
511
+ if (serverTrust != nil && SecTrustEvaluate (serverTrust, §TrustResult) == errSecSuccess) {
512
+ NSString *bundledCertFilePath = [[NSBundle bundleForClass: [self class ]] pathForResource: bundleCertFileName ofType: @" cer" ];
513
+ if (bundledCertFilePath != nil ) {
514
+ CFIndex certCount = SecTrustGetCertificateCount (serverTrust);
515
+ CFIndex certIndex;
516
+ NSMutableArray * certificates = [NSMutableArray array ];
517
+ for (certIndex = 0 ; certIndex < certCount; certIndex++) {
518
+ SecCertificateRef aServerCertificate = SecTrustGetCertificateAtIndex (serverTrust, certIndex);
519
+ [certificates addObject: (__bridge id )aServerCertificate];
520
+ }
521
+
522
+ SecTrustRef newTrust = NULL ;
523
+ SecTrustResultType newTrustResult;
524
+ OSStatus err = SecTrustCreateWithCertificates ((__bridge CFArrayRef) certificates, NULL , &newTrust);
525
+ if (err == noErr) {
526
+ err = SecTrustEvaluate (newTrust, &newTrustResult);
527
+ }
528
+
529
+ allowConnection = NO ;
530
+
531
+ if (err == noErr) {
532
+ allowConnection = (newTrustResult == kSecTrustResultProceed ) || (newTrustResult == kSecTrustResultUnspecified );
533
+ }
534
+
535
+ if (newTrust != NULL ) {
536
+ CFRelease (newTrust);
537
+ }
538
+ }
539
+ }
540
+ }
541
+ }
542
+
543
+ if (allowConnection) {
544
+ completionHandler (NSURLSessionAuthChallengeUseCredential , [NSURLCredential credentialForTrust: serverTrust]);
545
+ } else {
546
+ completionHandler (NSURLSessionAuthChallengeCancelAuthenticationChallenge , nil );
547
+ }
548
+ }
549
+ @end
0 commit comments