32

When a TCP connection gets cancelled by the client while making a HTTP request, I'd like to stop doing any work on the server and return an empty response. What HTTP status code should such a response return?

Muhammad Rehan Saeed
  • 28,236
  • 27
  • 169
  • 261
  • 2
    When a request gets canceled, will the client read the sever response? What exactly do you mean by "canceled"? What have you tried? Why are there ten _"My situation is unique, tell me which of the 20 or so status codes I should use"_ questions per day? Does it _really_ matter? – CodeCaster Sep 18 '17 at 07:16
  • It does still matter because caches, browser developer tools and other intermediaries still read the response. So far, I'm just using a 400 Bad Request but that feels wrong. This is not a unique situation and I was surprised that an answer did not already exist. Status codes are all about language which is why it's difficult to know which to use. The language you use in your API/site is important as it conveys intent. If my browser cancels a request and I see a 400 Bad Request in the F12 developer tools, this suggests that the request was invalid which is the incorrect intent. – Muhammad Rehan Saeed Sep 18 '17 at 07:28
  • There's no ability within HTTP for a client to cancel a request. So it's not surprising that no code is defined for the server to return. – Damien_The_Unbeliever Sep 18 '17 at 08:36
  • I think it's very important to consider why the request is cancelled, rather then just look for one specific code for any request being cancelled. – Scott Flack Sep 25 '17 at 05:57
  • If the server can still send, then it can send any response it wants, including the complete repose requested. The client cancelling (closing its sending half) just means the server will not receive any more data from the client. The client may continue to receive the rest of the result from the server. ON THE OTHER HAND, if the client closes both halves of the socket, then the server gets an error when next it does anything with that socket and recovers with no need to send anything more the the client. – Jesse Chisholm Sep 28 '18 at 22:31

4 Answers4

31

To be consistent I would suggest 400 Bad Request now if your backend apps are capable of identifying when the client gets disconnected or if you reject or close the connection, probably you could return Nginx' non-standard code 499 or 444.

  • 499 Client Closed Request Used when the client has closed the request before the server could send a response.

  • 444 No Response Used to indicate that the server has returned no information to the client and closed the connection.

nbari
  • 20,729
  • 5
  • 51
  • 86
  • 4
    **204 No Content**: `The server successfully processed the request and is not returning any content.` Also seems to fit the OPs theme quite nicely. – TheChetan Sep 24 '17 at 06:13
15

HTTP (1.0/1.1) doesn't have a means to cancel a request. All that a client can do if it no longer wants the response is to close the connection and hope that the server contains an optimization to stop working on a response that can no longer be delivered. Since the connection is now closed, no response nor status code can actually be delivered to the client and so any code you "return" is only for your own satisfaction. I'd personally pick something in the 4xx range1 since the "fault" - the reason you can no longer deliver a response - is due to the client.

HTTP 2.0 does allow an endpoint to issue END_STREAM or RST_STREAM to indicate that they are no longer interested in one stream without tearing down the whole connection. However, they're meant to just ignore any further HEADERS or DATA sent on that stream and so even though you may theoretically deliver a status code, the client is still going to completely ignore it.


1Probably 400 itself since I can't identify a more specific error that seems entirely appropriate.

Damien_The_Unbeliever
  • 220,246
  • 21
  • 302
  • 402
  • Seems relevant https://en.wikipedia.org/wiki/HTTP_451: A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource. – TheChetan Sep 23 '17 at 07:28
  • 1
    @TheChetan: That's for censorship, not asynchronous cancellation. – Davis Herring Sep 24 '17 at 02:32
  • @TheChetan - and again, the context here seams to be "cancellation" from the client rather than the server - which of course isn't an HTTP concept. – Damien_The_Unbeliever Sep 26 '17 at 16:14
  • Even in the old days (HTTP 1.x) you can close the sending `half` of your socket, and leave the receiving `half` open. The server gets the close, but it can still send a response if it wants to. – Jesse Chisholm Sep 28 '18 at 22:26
5

There are just a few plausible choices (aside from 500, of course):

  1. 202 Accepted

    You haven't finished processing, and you never will.

    This is appropriate only if, in your application domain, the original requestor "expects" that not all requests will be satisfied.

  2. 409 Conflict

    …between making and cancelling the request.

    This is only weakly justified: your situation does not involve one client making a request based on out of date information, since the cancellation had not yet occurred.

  3. 503 Service Unavailable

    The service is in fact unavailable for this one request (because it was cancelled!).

The general argument of "report an error as an error" favors 409 or 503. So 503 it is by default.

Davis Herring
  • 24,173
  • 3
  • 25
  • 55
3

There really is little to do. Quoting from RFC 7230, section 6.5:

A client, server, or proxy MAY close the transport connection at any time.

That is happening at TCP-, not HTTP-level. Just stop processing the connection. A status code will confer little meaning here as the intent of an incomplete/broken request is mere speculation. Besides, there will be no means to transport it across to the client.

DaSourcerer
  • 5,318
  • 4
  • 26
  • 52
  • 3
    While the client won't receive this status code, your logging/metrics-gathering _should_ and there are many cases when knowing that the response wasn't finished as the client cancelled is important when figuring out how to make the service/server better. – Enda Farrell May 27 '20 at 12:16