Skip to content
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

ServletWebRequest.isEtagNotModified does not support commas and spaces in client ETags [SPR-14216] #18790

spring-issuemaster opened this issue Apr 25, 2016 · 1 comment


Copy link

@spring-issuemaster spring-issuemaster commented Apr 25, 2016

Sebastiaan van Erk opened SPR-14216 and commented

The problem is in isEtagNotModified(String etag):

String[] clientEtags = StringUtils.delimitedListToStringArray(ifNoneMatch, ",", " ");

The client ETags are taken from the ifNoneMatch header and are ETags separated by commas. However the ETags themselves are opaque (double)quoted strings: they may contain commas and/or spaces (and even "). The code above does not take this into account and splits ETags in half if they contain a comma and removes any spaces they may contain.

A workaround is to make sure generated ETags don't have commas or spaces in them (I used the @Version column which is a Date as the ETag where toString() by default generates a space, but I could format it as an ISO8601 timestamp, which contains no spaces or commas).

Affects: 4.2.5

Issue Links:

  • #18797 Consistent handling of multi-valued headers in HttpHeaders
  • #18798 Behavior of checkNotModified(String etag, long lastModifiedTimestamp) does not match HTTP recommendations

Referenced from: commits 29da44c

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Apr 26, 2016

Sebastiaan van Erk commented

I just noticed that HttpHeaders has a similar flaw:

	public List<String> getIfNoneMatch() {
		return getFirstValueAsList(IF_NONE_MATCH);

	protected List<String> getFirstValueAsList(String header) {
		List<String> result = new ArrayList<String>();
		String value = getFirst(header);
		if (value != null) {
			String[] tokens = value.split(",\\s*");
			for (String token : tokens) {
		return result;

It also does not properly parse the ETags and splits on arbitrary commas (even ones contained inside the ETag).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.