Commit Graph

3 Commits

  • gsa: disregard keepalive (#247)
    GSA seems to, sometimes, reject HTTP requests made on a kept-alive
    connection with a 503. This was either the real root cause, or a second
    root cause, for #243. Fix this by creating a new HTTP connection for
    each GSA request.
    
    See also: https://github.com/rileytestut/AltSign/pull/52 and
    https://github.com/rileytestut/AltSign/pull/47
    
    Speculatively fixes #232
  • http: throw on unsuccessful responses (#246)
    Ref #243. `makeRequest` never inspected `response.status`, so a non-2xx
    body was
    returned as if it had succeeded. Every caller decodes that body as a
    property list
    or JSON, so Apple answering with an HTML error page surfaced as:
    
    ```
    Error: DecodingError.dataCorrupted: Data was corrupted. Debug description: The given
    data was not a valid property list.. Underlying error: ... Encountered unknown tag
    html on line 1
    ```
    
    which says nothing about what actually happened. In the case that
    prompted #243, GSA
    was returning `503 Service Temporarily Unavailable` for the `apptokens`
    operation. It
    now reads:
    
    ```
    Error: POST https://gsa.apple.com/grandslam/GsService2 failed: HTTP 503 Service
    Unavailable (text/html): <html> <head><title>503 Service Temporarily
    Unavailable</title></head> ...
    ```
    
    ### Notes
    
    - The response body is only included in the message for `text/html` and
    `text/plain`,
    i.e. gateway error pages. Bodies from the auth endpoints can carry
    account details
    (the 2FA requests use `Accept: application/x-buddyml`), and errors get
    printed
    verbatim in places such as `DevCommand.swift:164`, so those are left
    out. It also
      avoids emitting replacement characters for binary bodies.
    - The non-2xx path does not report progress, so `XADIProvider`'s
    download no longer
      prints `100%` immediately before failing.
    - Body collection moved to `collect(_:onProgress:)` so there is a single
    exit point.
      Buffer pre-sizing and progress reporting are unchanged.
    - `SDKBuilder` already does this check by hand on `send()`, so it is
    unaffected.
    
    ### Behaviour changes worth a look
    
    - `XADIProvider` writes the Apple Music APK download straight to disk; a
    failed
      download now throws instead of leaving a corrupt `applemusic.apk`.
    - The 2FA requests (`GrandSlamTrustedDeviceRequest`,
    `GrandSlamSMSAuthRequest`,
    `GrandSlamValidateRequest`) use no-op decoders, so a rejected request is
    currently
    discarded and xtool goes on to prompt for a code that was never sent —
    the symptom
      in #235. Those now fail loudly.
    
    ### Two things I left alone
    
    - `GrandSlamTwoFactorAuthenticateOperation.swift:47` catches
    `GrandSlamOperationError`
    with code `-21669` to report an incorrect verification code, but that
    error is only
    thrown by `GrandSlamOperationDecoder`, which the validate requests do
    not use, so the
    catch is unreachable. With this change a wrong code surfaces as a raw
    HTTP error
    instead. Mapping the status back to `incorrectVerificationCode` seemed
    like your call,
      since I do not know what GSA returns for a bad code.
    - If any endpoint reports errors in a decodable body under a non-2xx
    status, this guard
    would pre-empt it. I could not find one — `developerservices2` returns
    HTTP 200 with
      `resultCode`/`userString` in the body, which is untouched here.
    
    Built and linted on Linux (`swift build --product xtool`, `make lint`: 0
    violations).
    
    ---------
    
    Co-authored-by: Robetronica <noreply@Robetronica.com>
    Co-authored-by: Kabir Oberai <oberai.kabir@gmail.com>