On Nov 30, 2011, at 7:13 AM, Quinn The Eskimo! wrote:
There are a bunch of different retry mechanisms built in to NSURLConnection. Most of them don't have knobs to twiddle, and you'll have to move to a lower layer to prevent the retry (as per Jens's suggestion). However, before you do that you should check whether your -connection:willSendRequest:redirectResponse: delegate method is being called. If so, you can use it to stop the retry.
Unfortunately, -connection:willSendRequest:redirectResponse: is only called once (with nil redirectResponse, as usual). Could that be considered a bug?
On Nov 29, 2011, at 3:02 PM, Jens Alfke wrote:
On Nov 29, 2011, at 10:31 AM, Jeff Johnson wrote:
I'm using NSURLConnection to update song information on a SHOUTcast server. This is done via an HTTP GET request with the path format "/admin?song=“.
Wow, really? That’s a terrible design on their part; GETs are supposed to be read-only and idempotent (precisely because of problems like the one you’re running into.) But from what I recall, Shoutcast/Icecast is an incredibly kludgy protocol :-p
Unfortunately, SHOUTcast is very poorly designed, so it does not give an HTTP response to the request. Instead, it simply does ACK and then FIN. This seems to cause NSURLConnection to retry twice (on different source ports) before giving up. The result is that the song information is updated three times on the SHOUTcast server instead of once, because there are three GET requests.
Is there any way to prevent NSURLConnection from retrying after the connection is closed?
I don’t think so. What it’s doing is appropriate for any reasonable server, so I doubt anyone would have added an option to turn it off.
Your best bet is probably to send the request yourself using a raw NSStream. Pretty much all you have to do is open a stream to the host and send “GET /admin?song=%@ HTTP/1.1\r\nHost: %@\r\n\r\n”, where the first param is the track name and the second is the DNS name of the server.
I replaced it with some CFStream code that I already had. Which I seem to be doing more and more often with NSURLConnection...
This still won’t solve the problem if there are any HTTP proxies between you and the server, because they’re likely to use the same retry behavior when they relay your request.
At that point it's no longer my problem, because any other app will have the same problem. :-)