Сбой прерывистой загрузки HTTP kCFStreamErrorDomainSSL (-9802)

У меня периодически возникает эта ошибка при попытке загрузить файлы изображений из твиттера с такими URL-адресами: https://pbs.twimg.com/media/Ck-9Oc6XIAAIb8B.jpg

Ориентация на ios8 и сбои на двух устройствах и симуляторе ios9 периодически, по крайней мере, в 20% случаев.

У меня есть тестовое приложение с кнопкой перезагрузки, которая позволяет повторить попытку. Если первый раз работает, кажется, что каждая последующая перезагрузка работает (возможно, кеширование?). Если в первый раз произойдет сбой, в конечном итоге он успешно загрузится после нескольких попыток (скажем, 5-10).

Конечно, твиттер имеет соответствующую настройку SSL. В чем дело?

Я не хочу отключать ALS полностью или даже просто для этого домена, в идеале.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var myImageView: UIImageView!

    @IBAction func didPressReload(sender: AnyObject) {

        loadImage()
    }

    func loadImage() {
        myImageView.imageFromUrl("https://pbs.twimg.com/media/Ck-9Oc6XIAAIb8B.jpg")
    }
}

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        if let url = NSURL(string: urlString) {
            let request = NSURLRequest(URL: url)
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {

                (response: NSURLResponse?, data: NSData?, error: NSError?) in

                if (error != nil) {
                    NSLog("Failed to load URL \(response?.URL?.absoluteString): \(error)")

                }

                if let imageData = data as NSData? {
                    self.image = UIImage(data: imageData)
                }
            }
        }
    }
}

Ошибка подробно при сбое:

2016-06-18 18:17:19.975 TestSSL[1027:420188] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
2016-06-18 18:17:20.011 TestSSL[1027:420137] Failed to load URL nil: Optional(Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSUnderlyingError=0x14597da0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamPropertySSLClientCertificateState=0, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x146977b0>, _kCFStreamErrorDomainKey=3, kCFStreamPropertySSLPeerCertificates=<CFArray 0x14595f90 [0x3b0ca840]>{type = immutable, count = 4, values = (
    0 : <cert(0x14696590) s: *.twimg.com i: DigiCert High Assurance CA-3>
    1 : <cert(0x14696a90) s: DigiCert High Assurance CA-3 i: DigiCert High Assurance EV Root CA>
    2 : <cert(0x14696eb0) s: DigiCert High Assurance EV Root CA i: Baltimore CyberTrust Root>
    3 : <cert(0x146971e0) s: Baltimore CyberTrust Root i: Baltimore CyberTrust Root>
)}, NSErrorFailingURLStringKey=https://pbs.twimg.com/media/Ck-9Oc6XIAAIb8B.jpg, NSErrorFailingURLKey=https://pbs.twimg.com/media/Ck-9Oc6XIAAIb8B.jpg}}, _kCFStreamErrorCodeKey=-9802, NSErrorFailingURLStringKey=https://pbs.twimg.com/media/Ck-9Oc6XIAAIb8B.jpg, NSErrorPeerCertificateChainKey=<CFArray 0x14595f90 [0x3b0ca840]>{type = immutable, count = 4, values = (
    0 : <cert(0x14696590) s: *.twimg.com i: DigiCert High Assurance CA-3>
    1 : <cert(0x14696a90) s: DigiCert High Assurance CA-3 i: DigiCert High Assurance EV Root CA>
    2 : <cert(0x14696eb0) s: DigiCert High Assurance EV Root CA i: Baltimore CyberTrust Root>
    3 : <cert(0x146971e0) s: Baltimore CyberTrust Root i: Baltimore CyberTrust Root>
)}, NSErrorClientCertificateStateKey=0, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x146977b0>, NSErrorFailingURLKey=https://pbs.twimg.com/media/Ck-9Oc6XIAAIb8B.jpg})

1 ответ

Решение

Моя ошибка заключалась в том, что "твиттер имеет правильную настройку SSL". Через неоднократную перезагрузку я обнаружил, что иногда предоставляется только сертификат SHA-1.

Возможно, тот факт, что твиттер пытается поддержать старых клиентов, как-то связан с этим:

Мы вносим свой вклад, внедряя сертификаты SHA-256 на наших конечных точках Twitter и используя переключение сертификатов, чтобы обслуживать сертификаты SHA-1, только если мы обнаруживаем более старых клиентов без поддержки SHA-256.

с https://blog.twitter.com/2015/sunsetting-sha-1

Казалось бы, твиттер иногда запутывается. Так что мой единственный выбор - разрешить исключения ALS для моего приложения.

Я надеюсь, что мой вопрос с ответом полезен для кого-то еще.

Другие вопросы по тегам