2

The reference for this method only says what happens locally on the client, and says nothing about what it potentially sends to the server. Apparently, our server has some challenges with receiving a lot of status code 499 from us when we cancel a request, but I can't find anything about how URLSession handles cancellation. Is there a standard cancel-message over the protocol HTTP?

mfaani
  • 33,269
  • 19
  • 164
  • 293
Sti
  • 8,275
  • 9
  • 62
  • 124

1 Answers1

2

The client doesn’t send 499. Status codes are one-way. Rather, the client closes the network connection. The server records that dropped connection as a 499 status code in its logs.

If the server is HTTP/2 or later, the client may send either a END_STREAM or RST_STREAM message to cancel a single request without canceling other requests on the same connection, or it may just drop the connection. Either way, you’ll probably just see a 499 in your logs. There is little reason to care whether the connection was dropped or cancelled.

dgatwood
  • 10,129
  • 1
  • 28
  • 49
  • So `END_STREAM` causes a single request to end, while `RST_STREAM` causes the entire connection to end? What does RST stand for? But doesn't the client ultimately need a status code for its request? I suppose URLSession will generate some 4xx for it – mfaani Aug 07 '19 at 11:51
  • My understanding is that either end should typically send END_STREAM when it no longer cares about the stream, and the other end is expected to send RST_STREAM in response to indicate that the stream is no longer valid. If either end detects some error that it can't handle, it should send RST_STREAM, which tears down the stream immediately, and no response is required from the other end. Neither inherently results in the actual network socket getting closed. – dgatwood Aug 07 '19 at 18:15
  • If a connection is canceled, there's no status code required at the NSURLSession level, because either A. the initial response from the server has already been received, in which case the request already has a status code, or B. it hasn't been received, in which case the callback to provide your app with the status code won't ever get called, because the request is already cancelled. – dgatwood Aug 07 '19 at 18:18
  • 1
    @dgatwood How it is related to the NSURLErrorCancelled error code that we might get from NSURLSession level? https://developer.apple.com/documentation/foundation/1508628-url_loading_system_error_codes/nsurlerrorcancelled?language=objc – sliwinski.lukas Sep 05 '19 at 09:09
  • Only distantly related. You'll see that error code in any `NSError` objects provided to the task's completion handler when the app explicitly calls `-cancel` or `-cancelByProducingResumeData:` on a task (or cancels the whole session), and you'll also see them logged by the underlying `NSURL` machinery at that time. You'll also see them if you access the error property of a canceled task. Stream termination events *might* get sent, but only if there is still a connection on which to send it. A cancelation from the server side should result in `NSURLErrorNetworkConnectionLost` instead, AFAIK. – dgatwood Sep 05 '19 at 21:34
  • @dgatwood Thanks for the explanation. I asked because wasn't sure about what you said that: "B. it hasn't been received, in which case the callback to provide your app with the status code won't ever get called". I was confused that the callback of the (NSURLSession's) task won't get called, but seems like it will always be with mentioned error message when we explicitly call task.cancel() as in the original question. I only wonder if the callback can be called twice if we try to cancel when we already got the response. – sliwinski.lukas Sep 06 '19 at 11:12
  • Ah, sorry, I meant the delegate method (`didReceiveResponse`), which does not get called after you cancel the task. (It calls `URLSession:task:didCompleteWithError:` instead.) As for the callback block, it should get called if the task gets canceled indirectly — for example, if an authentication delegate or custom URL protocol cancels the request — but I honestly don't remember for sure whether it gets called when you explicitly cancel the task directly or not. I don't use the callback part of the API very often, so I'm a little fuzzier on those details. – dgatwood Sep 06 '19 at 17:54