Skip to content

ServletWebRequest can't validate Etag and Last-Modified together. [SPR-11324] #15948

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Jan 17, 2014 · 4 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: task A general task
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jan 17, 2014

Markus Malkusch opened SPR-11324 and commented

HTTP 1.1. recommends to send both ETag and Last-Modified header:

the preferred behavior for an HTTP/1.1 origin server is to send both a strong entity tag and a Last-Modified value. [..] If both an entity tag and a Last-Modified value have been provided by the origin server, [clients] SHOULD use both validators in cache-conditional requests. [..] upon receiving a conditional request that includes both [..] [server] MUST NOT return a response status of 304 (Not Modified) unless doing so is consistent with all of the conditional header fields in the request.

Spring's ServletWebRequest seems to be designed for an isolated use of one of them, but not both. If an application wants to implement validation for both the first checkNotModified() call has more significance. This is in particular relevant if the first sets the state to notModified. The next call has no more effect:

Here is a further test case for ServletWebRequestTests which demonstrates the issue:

    @Test
    public void checkNotModifiedETagAndTimeStamp() {
            String currentETag = "\"Foo\"";
	    String oldEtag = "Bar";
            servletRequest.setMethod("GET"); // Also for HEAD
            servletRequest.addHeader("If-None-Match", oldEtag );

            long currentTime = new Date().getTime();
            servletRequest.setMethod("GET"); // Also for HEAD
            servletRequest.addHeader("If-Modified-Since", currentTime);

            request.checkNotModified(currentTime);
            request.checkNotModified(currentETag);

            assertEquals(200, servletResponse.getStatus());
            assertEquals(currentETag, servletResponse.getHeader("ETag"));
    }

Affects: 4.0 GA

Reference URL: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4

This issue is a sub-task of #16413

Issue Links:

Referenced from: commits 0175068, 953608e

0 votes, 7 watchers

@spring-projects-issues
Copy link
Collaborator Author

Markus Malkusch commented

Reading further in HTTP I see more issues regarding checkNotModified():
-checkNotModified() doesn't offer any mechanism to identify a validator as weak or strong.
-HTTP's weak comparison function is not implemented at all. I.e. W/"ETag"=="ETag".
-A client can send a conditional request with more ETags.
-The "*" ETags seems to be unsupported.

I don't want to bother you with more issues about this topic. But I would happily offer resources and provide a pull request.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Indeed, the not-modified check probably needs some general overhaul on Spring's side. Let's use this issue for all such ETag enhancements, and target them for 4.1 RC1 (June).

A pull request would be very welcome, of course!

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 23, 2015

Brian Clozel commented

Hi Markus Malkusch, I've revisited a bit your PR, this is now in master.
See 953608ec.

See #16413 for other related changes.

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: task A general task
Projects
None yet
Development

No branches or pull requests

2 participants