Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion AltSign/Sources/ALTAppleAPI+Authentication.swift
Original file line number Diff line number Diff line change
Expand Up @@ -446,11 +446,28 @@ private extension ALTAppleAPI
request.httpBody = bodyData
httpHeaders.forEach { request.addValue($0.value, forHTTPHeaderField: $0.key) }

let dataTask = self.session.dataTask(with: request) { (data, response, error) in
// Apple's edge serves at most two requests per connection and answers every request
// after that with a 503 HTML error page. Authenticating takes three requests (init,
// complete, apptokens), so the third one fails whenever they share a pooled connection.
// Give each request its own session, and therefore its own connection.
let configuration = URLSessionConfiguration.ephemeral
configuration.httpMaximumConnectionsPerHost = 1
let session = URLSession(configuration: configuration)
defer { session.finishTasksAndInvalidate() }

let dataTask = session.dataTask(with: request) { (data, response, error) in
do
{
guard let data = data else { throw error ?? ALTAppleAPIError.unknown() }

// Surface server errors directly; their HTML bodies are not property lists, and
// parsing them yields a misleading "data couldn't be read" error instead.
if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode >= 500
{
let message = String(format: NSLocalizedString("Apple's authentication servers returned an error (HTTP %d). This is a problem on Apple's end, not with your Apple ID or password.", comment: ""), httpResponse.statusCode)
throw NSError(domain: ALTUnderlyingAppleAPIErrorDomain, code: httpResponse.statusCode, userInfo: [NSLocalizedDescriptionKey: message])
}

guard let responseDictionary = try PropertyListSerialization.propertyList(from: data, format: nil) as? [String: Any],
let dictionary = responseDictionary["Response"] as? [String: Any],
let status = dictionary["Status"] as? [String: Any]
Expand Down