gpt4 book ai didi

ios - NSURLSession 取消 dataTask 有时会出现错误消息 Task finished with error - code : -999

转载 作者:行者123 更新时间:2023-11-28 05:51:15 29 4
gpt4 key购买 nike

我正在上传 Images->Base64->jsonData 格式的 URLRequest.httpBody 大小约为 6MB。我正在使用具有默认配置的静态 NSURLSession 并使用 urlsession 上的 dataTask 上传。有时它成功上传到服务器有时它不是并且低于错误并且没有在服务器端打印。我没有进行并行调用。我们正在正确使用 SSL 固定和处理身份验证挑战,因此没有 SSL 身份验证错误。我们使用的是 iOS 设备 11.3 和 XCode 10。

任务 <58BF437E-7388-4AE4-B676-2485A57CB0CD>。<10> 已完成,但出现错误 - 代码:-999

private lazy var configuration: URLSessionConfiguration = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = TimeInterval(120)
configuration.timeoutIntervalForResource = TimeInterval(120)
return configuration
}()
private lazy var urlSession = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)

func invokeService(methodName : String, collectionName: String, queryDictionary: [String:AnyObject]! = nil, httpMethod: String! = nil) {
// Set up the URL request
let baseUrl: String = WebServiceConstants.hostUrl.qaUrl + "/\(collectionName)" + "/\(methodName)"
// let baseUrl: String = WebServiceConstants.hostUrl.demoUrl + "/\(collectionName)" + "/\(methodName)"
// let baseUrl: String = WebServiceConstants.hostUrl.prod_Url + "/\(collectionName)" + "/\(methodName)"


guard let url = URL(string: baseUrl) else {
return
}
var urlRequest = URLRequest(url: url)
// set up the session
// let configuration = URLSessionConfiguration.default
// configuration.timeoutIntervalForRequest = TimeInterval(120)
// configuration.timeoutIntervalForResource = TimeInterval(120)
//
// let session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
urlRequest.httpMethod = httpMethod
do {
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: queryDictionary, options: []) // pass dictionary to nsdata object and set it as request body
}
catch _ {
}

urlRequest.setValue(WebServiceConstants.HTTPStrings.contentTypeJSON, forHTTPHeaderField: WebServiceConstants.HTTPStrings.contentTypeHeader)


// print(queryDictionary)
if AppController.sharedInstance.isAlreadyLogin() && (KeychainWrapper.standard.string(forKey: Constants.UserDefaultKeys.authorizationHeaderValue) != nil) {
let authorizationHeaderValue = WebServiceConstants.HTTPStrings.authorizationHeaderValue + KeychainWrapper.standard.string(forKey: Constants.UserDefaultKeys.authorizationHeaderValue)!
urlRequest.setValue(authorizationHeaderValue, forHTTPHeaderField: WebServiceConstants.HTTPStrings.authorizationHeader)
}

let _ = urlSession.dataTask(with: urlRequest, completionHandler: { [unowned self]
(data, response, error) in

//print(response)
if error != nil {

if error?._code == NSURLErrorTimedOut {
// print(error?.localizedDescription)
let userInfo = [
NSLocalizedDescriptionKey: BWLocalizer.sharedInstance.localizedStringForKey(key:"App_Timeout_Message")
]
let errorTemp = NSError(domain:"", code:-1001, userInfo:userInfo)
self.delegate?.didFailWithError(errorObject: errorTemp)
} else if error?._code == NSURLErrorNotConnectedToInternet {
let userInfo = [
NSLocalizedDescriptionKey: BWLocalizer.sharedInstance.localizedStringForKey(key:"Internet_Not_Available")
]
let errorTemp = NSError(domain:"", code:-1001, userInfo:userInfo)
self.delegate?.didFailWithError(errorObject: errorTemp)
}
else if error?._code == NSURLErrorCancelled {
// canceled
print("Request is cancelled") // Control reaches here on Finished with Error code = -999
self.delegate?.didFailWithError(errorObject: error!)

}
else {
self.delegate?.didFailWithError(errorObject: error!)
}

} else {

do {

if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]
{
self.delegate?.didReceiveResponse(responseObject: json as AnyObject)
//Implement your logic
print(json)
}

} catch {
self.delegate?.didFailWithError(errorObject: error)

}
}

}).resume()


}

*添加了 SSL 证书固定代码 *

extension WebserviceHandler : URLSessionDelegate {
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

guard let trust = challenge.protectionSpace.serverTrust else {
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
let credential = URLCredential(trust: trust)
let pinner = setupCertificatePinner() // adding CertificateHash

if (!pinner.validateCertificateTrustChain(trust)) {
challenge.sender?.cancel(challenge)

}

if (pinner.validateTrustPublicKeys(trust)) {
completionHandler(.useCredential, credential)

}
else {
completionHandler(.cancelAuthenticationChallenge, nil)
let popUp = UIAlertController(title: "", message: BWLocalizer.sharedInstance.localizedStringForKey(key:"Certificate_Pining_Fail_Message"), preferredStyle: UIAlertController.Style.alert)
popUp.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: {alertAction in popUp.dismiss(animated: true, completion: nil)}))
popUp.addAction(UIAlertAction(title: BWLocalizer.sharedInstance.localizedStringForKey(key:"Action_Go"), style: UIAlertAction.Style.default, handler: { action in
let urlToOpenAppStorepage = URL(string: WebServiceConstants.hostUrl.appstore_url)
let objApp = UIApplication.shared
objApp.openURL(urlToOpenAppStorepage!)

}))
UIApplication.shared.keyWindow?.rootViewController?.present(popUp, animated: true, completion: nil)
}
}

}

func setupCertificatePinner() -> CertificatePinner {
// let baseUrl: String = WebServiceConstants.hostUrl.dev_URL

let baseUrl: String = WebServiceConstants.hostUrl.qaUrl
// let baseUrl: String = WebServiceConstants.hostUrl.demoUrl
// let baseUrl: String = WebServiceConstants.hostUrl.prod_Url
let pinner = CertificatePinner(baseUrl)

/*

You will see something like this:

being challanged! for www.google.co.nz
hash order is usually most specific to least, so the first one is your domain, the last is the root CA
Production
hash: 8U/k3RvTcMVSafJeS9NGpY4KDFdTLwpQ/GUc+lmPH/s=
hash: 4vkhpuZeIkPQ+6k0lXGi7ywkVNV55LhVgU0GaWWMOdk=
hash: jZzMXbxSnIsuAiEBqDZulZ/wCrrpW9bRLMZ6QYxs0Gk=
hash: uthKDtpuYHgn+wRsokVptSysyqBzmr4RP86mOC703bg=
you might need to change the has below to be the second one in the list for the code to pass

QA
hash: LX6ZGwP3Uii+KCZxDxDWlDWijvNI6K/t2906cUzKYM4=
hash: 4vkhpuZeIkPQ+6k0lXGi7ywkVNV55LhVgU0GaWWMOdk=
hash: jZzMXbxSnIsuAiEBqDZulZ/wCrrpW9bRLMZ6QYxs0Gk=
*/

pinner.debugMode = true
pinner.addCertificateHash(WebServiceConstants.HTTPStrings.hashKey)

return pinner
}

使用固定库:https://github.com/nicwise/certificatepinner

最佳答案

我在该代码中发现了几个错误。

  • 如果您在经过身份验证的代理之后,您的身份验证处理程序中的第一行将导致失败。

    如果服务器需要任何类型的 HTTP 身份验证密码或 OAuth 凭据,它也会失败。

    在许多其他情况下它也会失败。

    除非请求在某种程度上确实是错误的,否则您永远不应该取消身份验证请求。如果可以的话,取消身份验证请求也会阻止操作系统为您透明地处理它。您应该取消身份验证请求的唯一情况是,如果您检查了证书或其他内容,而它实际上是无效。否则,当您请求外部处理时,您通常应该相信操作系统会默认执行正确的操作。

    因此,除非身份验证方法是服务器信任,否则请使用默认处理。

  • 代码根本不检查身份验证方法。出于上述所有原因,您不应该进行任何 检查,除非身份验证方法是服务器信任。如果是其他情况,请使用默认处理。总是。

  • 下一个 if 语句有两个问题:

    • 它为身份验证请求提供一个新的状态而不返回。这意味着您可以在之后调用完成处理程序,这可能会导致崩溃和其他不当行为。

    • 它正在调用旨在影响行为的质询发送方的方法。这就是您过去使用 NSURLConnection 执行此操作的方式,但您应该永远不要调用质询发送方的任何方法(除了可能查看它是否是您自己创建的对象之外) ,如果你使用自定义 NSURLProtocol 类)和 NSURLSession,因为它会导致各种问题,甚至包括崩溃。 (请参阅文档中关于 NSURLAuthenticationChallenge's -sender method 的巨大警告,或者就此而言,请参阅该警告之前的两段。)

  • 我也不完全确定我是否信任固定代码。如果信任链中的任何 key 是受信任的 key ,它看起来就会通过,而通常固定要求信任链中的最后(叶) key 是受信任的 key 。

  • 固定代码中的安全建议也很可疑。您可能不应该固定到证书,而应该固定到证书中的 key 。固定叶证书的 key 是完全合适的,并且确实是唯一合适的选择,因为它通常是唯一一个其 key 实际上在您的直接控制之下的选择。如果您重新颁发证书,那没什么大不了的,因为您应该使用与以前相同的 key 重新颁发,除非您的 key 以某种方式遭到破坏。

    或者,您可以根据需要添加信任层,但这需要运行您自己的自定义根证书(这需要更改 validateCertificateTrustChain 方法以在验证信任链时添加您的自定义根证书)或说服 CA卖给你一个可以签署其他证书的证书,价格为 $$$$。这些选项似乎都不实用。

    这些问题让我有点担心整个图书馆,但我没有时间审核它。您可能应该四处打听一下,看看是否有人对相关库进行了彻底的审核,因为众所周知,在编写使用 TLS key 的代码时很容易出错,而且我不想看到您以后遇到安全问题.

修复上面列出的所有错误后,如果您仍然遇到问题,请返回并使用更新的代码提出另一个问题。此外,还请询问有问题的代码固定项目来修复他们的代码片段,因为它们似乎包含相同的错误。 :-) 谢谢。

关于ios - NSURLSession 取消 dataTask 有时会出现错误消息 Task finished with error - code : -999,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52889242/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com