Search code examples
iosobjective-cnsurlconnectionnsurlconnectiondelegate

How to get http body in NSURLConnectionDelegate willSendRequestForAuthenticationChallenge


I have a HTTP Basic server where i sometimes need a user to make a selection before logging in. I thought i'd do this by sending a HTTP response 401 with json contents in the HTTP body to provide the data the client needs to show to the user.

However, i cannot for the world understand how i get the response body content in the willSendRequestForAuthenticationChallenge method. Since i use Basic Auth and provide the usr/pwd directly as a http "Authorization" header, this method gets called whenever the user cannot login, or when he/she needs to make the selection i am talking about.

So... i have the NSURLAuthenticationChallenge, but i cannot see any way of reading the body from that object.

If anybody could help out i'd really appreciate it!


Solution

  • You cannot get the body data at that point in the request process, because the URL request potentially asks you to make a decision about whether to cancel and retry with authentication before it even downloads the body data. It's a timing issue.

    What you can do is:

    • Allow the request to complete without a credential. This will cause the URL connection to download the response body (error message). Your support code can then recognize the 401 response, parse the body, and provide credentials in a retry.
    • Optionally wrap the above logic in a custom NSURLProtocol class so that it becomes transparent to the rest of your app

    Alternatively:

    • Provide the additional data in a custom HTTP header. I think you can probably get an NSURLResponse object from the protection spaces's failureResponse method, and get the headers from there.

    I'm not 100% certain that it is possible to get the header fields at that point, though. For sure, you can do it with an NSURLProtocol or with custom wrapper code as described earlier.