SwiftHTTP 认证错误超时
SwiftHTTP authentication error timeout
我在 iOS 应用程序中使用 SwiftHTTP 在 Web 服务器中执行基本身份验证。如果身份验证成功,一切都会按预期进行。但是,如果身份验证失败(代码为 401),调用失败处理程序大约需要 35 到 45 秒。代码如下:
var request = HTTPTask()
auth = HTTPAuth(username: user, password: password)
auth!.persistence = .ForSession
request.auth = auth
request.requestSerializer.timeoutInterval = 5
request.GET("http://\(ipaddr)", parameters: nil,
success: {(response : HTTPResponse) in
NSLog("login success")
},
failure: {(error: NSError, response: HTTPResponse?) in
NSLog("login failure")
}
)
请注意,超时值设置为 5 秒。查看SwiftHTTP代码,实际的请求实现归结为:
var request = NSMutableURLRequest(URL: url, cachePolicy: cachePolicy, timeoutInterval: timeoutInterval)
我在 SwiftHTTP 中添加了一些调试行来检查 timeoutInterval
是否设置正确,确实如此。我尝试了缓存策略和其他可配置参数的变体,结果没有任何变化。我也打开了一个 telnet 连接到 HTTP 服务器并手动发送了相同的请求,结果立即返回了 401,正如预期的那样。
知道为什么会这样吗?
看起来 HTTPTask
是这样处理挑战的:
public func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
if let a = auth {
let cred = a(challenge)
if let c = cred {
completionHandler(.UseCredential, c)
return
}
completionHandler(.RejectProtectionSpace, nil)
return
}
completionHandler(.PerformDefaultHandling, nil)
}
我建议您仅在 previousFailureCount
为零时才使用凭据,例如
public func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
if let credential = auth?(challenge) {
if challenge.previousFailureCount == 0 {
completionHandler(.UseCredential, credential)
} else {
completionHandler(.RejectProtectionSpace, nil)
}
} else {
completionHandler(.PerformDefaultHandling, nil)
}
}
当一个库不能以一种奇怪的、意想不到的或荒谬的方式工作时,很可能是该库中存在错误。如果您使用了不稳定的版本或 git 存储库快照,请务必检查上游树中的修复程序,即使您认为该库工作正常。
所以这是通过更新库解决的。 HTTPAuth
当前(在撰写本文时)库中不再存在。它被用户提供的闭包所取代,如 library documentation:
所示
var request = HTTPTask()
//the auth closures will continually be called until a successful auth or rejection
var attempted = false
request.auth = {(challenge: NSURLAuthenticationChallenge) in
if !attempted {
attempted = true
return NSURLCredential(user: "user", password: "passwd", persistence: .ForSession)
}
return nil //auth failed, nil causes the request to be properly cancelled.
}
我在 iOS 应用程序中使用 SwiftHTTP 在 Web 服务器中执行基本身份验证。如果身份验证成功,一切都会按预期进行。但是,如果身份验证失败(代码为 401),调用失败处理程序大约需要 35 到 45 秒。代码如下:
var request = HTTPTask()
auth = HTTPAuth(username: user, password: password)
auth!.persistence = .ForSession
request.auth = auth
request.requestSerializer.timeoutInterval = 5
request.GET("http://\(ipaddr)", parameters: nil,
success: {(response : HTTPResponse) in
NSLog("login success")
},
failure: {(error: NSError, response: HTTPResponse?) in
NSLog("login failure")
}
)
请注意,超时值设置为 5 秒。查看SwiftHTTP代码,实际的请求实现归结为:
var request = NSMutableURLRequest(URL: url, cachePolicy: cachePolicy, timeoutInterval: timeoutInterval)
我在 SwiftHTTP 中添加了一些调试行来检查 timeoutInterval
是否设置正确,确实如此。我尝试了缓存策略和其他可配置参数的变体,结果没有任何变化。我也打开了一个 telnet 连接到 HTTP 服务器并手动发送了相同的请求,结果立即返回了 401,正如预期的那样。
知道为什么会这样吗?
看起来 HTTPTask
是这样处理挑战的:
public func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
if let a = auth {
let cred = a(challenge)
if let c = cred {
completionHandler(.UseCredential, c)
return
}
completionHandler(.RejectProtectionSpace, nil)
return
}
completionHandler(.PerformDefaultHandling, nil)
}
我建议您仅在 previousFailureCount
为零时才使用凭据,例如
public func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
if let credential = auth?(challenge) {
if challenge.previousFailureCount == 0 {
completionHandler(.UseCredential, credential)
} else {
completionHandler(.RejectProtectionSpace, nil)
}
} else {
completionHandler(.PerformDefaultHandling, nil)
}
}
当一个库不能以一种奇怪的、意想不到的或荒谬的方式工作时,很可能是该库中存在错误。如果您使用了不稳定的版本或 git 存储库快照,请务必检查上游树中的修复程序,即使您认为该库工作正常。
所以这是通过更新库解决的。 HTTPAuth
当前(在撰写本文时)库中不再存在。它被用户提供的闭包所取代,如 library documentation:
var request = HTTPTask()
//the auth closures will continually be called until a successful auth or rejection
var attempted = false
request.auth = {(challenge: NSURLAuthenticationChallenge) in
if !attempted {
attempted = true
return NSURLCredential(user: "user", password: "passwd", persistence: .ForSession)
}
return nil //auth failed, nil causes the request to be properly cancelled.
}