2015-01-14 3 views
0

Я использую SwiftHTTP в приложении iOS для выполнения базовой проверки подлинности на веб-сервере. Если аутентификация завершается успешно, все работает так, как ожидалось. Однако, если аутентификация завершается с ошибкой (с кодом 401), для вызова обработчика отказа требуется от 35 до 45 секунд. Код выглядит следующим образом:Ошибка времени проверки подлинности SwiftHTTP

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 был возвращен немедленно, как и ожидалось.

Любые идеи, почему это происходит?

+0

Аутентификация работает, когда вы указываете правильное имя пользователя и пароль. Проблема заключается в нежелательной задержке при неудачной аутентификации (поскольку пользователь ввел неправильное имя пользователя или пароль). – cmatsuoka

ответ

0

Когда библиотека не работает в странной, неожиданной или бессмысленные образом, вероятность того, что есть ошибка в библиотеке. Если вы использовали нестабильный выпуск или моментальный снимок 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. 
} 
2

Похоже 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) 
    } 
} 
+0

Хотя это не является реальным решением проблемы, он (наряду с комментарием @ Rich о HTTPAuth, который, кажется, был удален), был необходим для исправления приложения: я использовал слегка устаревшую версию SwiftHTTP, которая имела аутентификацию ошибка. Я вытащил из текущей главы и, похоже, работал. Благодаря! – cmatsuoka

Смежные вопросы