spring-projects/spring-framework — pull request #440 by malkusch (2014-01-15 21:06:08+00:00)
Title: ServletWebRequest.checkNotModified() methods should treat HEAD identically to GET

`ServletWebRequest.checkNotModified()` methods don't treat a `HEAD` request identically to a `GET` request (in fact they don't consider `HEAD` at all).

[HTTP says](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4):

> The HEAD method is identical to GET except that the server MUST NOT
> return a message-body in the response. 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.

[Spring's reference documentation suggests](http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/mvc.html#mvc-ann-lastmodified) to call `WebRequest.checkNotModified()` to set the status code to 304:

> calling request.checkNotModified(lastModified) and returning null. The
> former sets the response status to 304

As a consequence of the current implementation, applications which follow that recommendation violate against HTTP. In simple words: I had some fun debugging my application for a missing 304 status code while firing HEAD requests with `wget --server-response --spider` on it.

I suggest to respect `HEAD` in the mentioned methods identically to `GET`.

Test cases
--

@Test
public void checkNotModifiedTimeStampForHEAD() {
long currentTime = new Date().getTime();
servletRequest.setMethod("HEAD");
servletRequest.addHeader("If-Modified-Since", currentTime);

request.checkNotModified(currentTime);

assertEquals(304, servletResponse.getStatus());
}

@Test
public void checkNotModifiedETagForHEAD() {
String eTag = "\"Foo\"";
servletRequest.setMethod("HEAD");
servletRequest.addHeader("If-None-Match", eTag );

request.checkNotModified(eTag);

assertEquals(304, servletResponse.getStatus());
}