5

Background:

My PHP code handles typical HTTP HEAD requests by sending either an HTTP status 404 response or a 204 response. This seems correct to me, since RFC7231 specifies HTTP status 204 as:

6.3.5. 204 No Content

The 204 (No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body. Metadata in the response header fields refer to the target resource and its selected representation after the requested action was applied...

The 204 response allows a server to indicate that the action has been successfully applied to the target resource, while implying that the user agent does not need to traverse away from its current "document view" (if any)...

A 204 response is terminated by the first empty line after the header fields because it cannot contain a message body...

https://www.rfc-editor.org/rfc/rfc7231#section-6.3.5

Since the user agent is only requesting the headers and not the file itself, 204 seems to fit.

Surprise #1:

When an <object> element has a URL for the data attribute, MSIE/Edge initially makes an HTTP HEAD request in order to determine the content-type via the response headers. While another MS quirk, it makes sense, as it allows the browser to pre-load the needed handlers in advance of receiving the content. When it receives a suitable response to the HEAD request, it will then make an HTTP GET request for the file itself.

Now, this wouldn't have been so much of an issue if it weren't for...

Surprise #2:

When MSIE/Edge receives a 204 response to its HEAD request, it treats it as an error and aborts loading the file.

This was, needless to say, quite frustrating to discover (the process and the discovery itself).

Have I misunderstood the purpose or usage of the 204 response? I know industry-usage often diverges from specifications, but this seems... wrong.

Community
  • 1
  • 1
PaulC
  • 123
  • 1
  • 10
  • Why does adding an extra round trip make sense? – John Hascall Aug 16 '16 at 01:08
  • 1
    I suppose I'm assuming that the average cost to load object handlers combined with the probability of a non-successful request is greater than the cost of an HTTP HEAD request. I suppose that's conjecture, though. – PaulC Aug 17 '16 at 03:16

2 Answers2

6

When you are returning 204 with the HEAD you are telling the user-agent that if it were to do a GET then it would also get a 204 and therefore there is no content to retrieve. From the perspective of the user-agent there is no point doing a GET because the HEAD retrieved all the information that was available.

If doing a GET request returns a 200, then the HEAD should also return a 200.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • This is the correct answer, don't return 204 to a command just because it was HEAD, this is incorrect unless the GET would also have returned a 204. – Adrien Aug 16 '16 at 11:01
  • 1
    I looked at Method Definitions in RFC2616 and I agree with your answer. "The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification." https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html @Sampson – PaulC Aug 16 '16 at 16:24
2

I'm an engineer on the Edge team, and see the issue to which you are referring. For the time being, I'd encourage you to use a 200 OK response, even when you're simply sending headers (as is fairly common).

I do agree that two requests is out of the norm, and that a 204 should probably not prevent the subsequent GET request.

I have filed a bug for our team to evaluate this issue more thoroughly.

https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8499759/

Sampson
  • 265,109
  • 74
  • 539
  • 565