Skip to content

Commit

Permalink
Update more places to use quoteETagIfNecessary
Browse files Browse the repository at this point in the history
Closes gh-33412
  • Loading branch information
rstoyanchev committed Sep 10, 2024
1 parent 1b26122 commit 3dd4a83
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1063,11 +1063,11 @@ public long getDate() {
/**
* Set the (new) entity tag of the body, as specified by the {@code ETag} header.
*/
public void setETag(@Nullable String etag) {
if (etag != null) {
Assert.isTrue(etag.startsWith("\"") || etag.startsWith("W/\""), "ETag does not start with W/\" or \"");
Assert.isTrue(etag.endsWith("\""), "ETag does not end with \"");
set(ETAG, etag);
public void setETag(@Nullable String eTag) {
if (eTag != null) {
Assert.isTrue(eTag.startsWith("\"") || eTag.startsWith("W/\""), "ETag does not start with W/\" or \"");
Assert.isTrue(eTag.endsWith("\""), "ETag does not end with \"");
set(ETAG, eTag);
}
else {
remove(ETAG);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,23 +247,25 @@ private boolean validateIfNoneMatch(@Nullable String etag) {
return true;
}

private boolean matchRequestedETags(Enumeration<String> requestedETags, @Nullable String etag, boolean weakCompare) {
etag = padEtagIfNecessary(etag);
private boolean matchRequestedETags(Enumeration<String> requestedETags, @Nullable String eTag, boolean weakCompare) {
if (StringUtils.hasLength(eTag)) {
eTag = ETag.quoteETagIfNecessary(eTag);
}
while (requestedETags.hasMoreElements()) {
// Compare weak/strong ETags as per https://datatracker.ietf.org/doc/html/rfc9110#section-8.8.3
for (ETag requestedETag : ETag.parse(requestedETags.nextElement())) {
// only consider "lost updates" checks for unsafe HTTP methods
if (requestedETag.isWildcard() && StringUtils.hasLength(etag)
if (requestedETag.isWildcard() && StringUtils.hasLength(eTag)
&& !SAFE_METHODS.contains(getRequest().getMethod())) {
return false;
}
if (weakCompare) {
if (etagWeakMatch(etag, requestedETag.formattedTag())) {
if (etagWeakMatch(eTag, requestedETag.formattedTag())) {
return false;
}
}
else {
if (etagStrongMatch(etag, requestedETag.formattedTag())) {
if (etagStrongMatch(eTag, requestedETag.formattedTag())) {
return false;
}
}
Expand All @@ -272,17 +274,6 @@ private boolean matchRequestedETags(Enumeration<String> requestedETags, @Nullabl
return true;
}

@Nullable
private String padEtagIfNecessary(@Nullable String etag) {
if (!StringUtils.hasLength(etag)) {
return etag;
}
if ((etag.startsWith("\"") || etag.startsWith("W/\"")) && etag.endsWith("\"")) {
return etag;
}
return "\"" + etag + "\"";
}

private boolean etagStrongMatch(@Nullable String first, @Nullable String second) {
if (!StringUtils.hasLength(first) || first.startsWith("W/")) {
return false;
Expand Down Expand Up @@ -346,13 +337,13 @@ private void updateResponseIdempotent(@Nullable String etag, long lastModifiedTi
}
}

private void addCachingResponseHeaders(@Nullable String etag, long lastModifiedTimestamp) {
private void addCachingResponseHeaders(@Nullable String eTag, long lastModifiedTimestamp) {
if (getResponse() != null && SAFE_METHODS.contains(getRequest().getMethod())) {
if (lastModifiedTimestamp > 0 && parseDateValue(getResponse().getHeader(HttpHeaders.LAST_MODIFIED)) == -1) {
getResponse().setDateHeader(HttpHeaders.LAST_MODIFIED, lastModifiedTimestamp);
}
if (StringUtils.hasLength(etag) && getResponse().getHeader(HttpHeaders.ETAG) == null) {
getResponse().setHeader(HttpHeaders.ETAG, padEtagIfNecessary(etag));
if (StringUtils.hasLength(eTag) && getResponse().getHeader(HttpHeaders.ETAG) == null) {
getResponse().setHeader(HttpHeaders.ETAG, ETag.quoteETagIfNecessary(eTag));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -33,6 +33,7 @@
import org.springframework.context.i18n.LocaleContext;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.Hints;
import org.springframework.http.ETag;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -341,7 +342,9 @@ private boolean validateIfMatch(@Nullable String eTag) {
}

private boolean matchRequestedETags(List<String> requestedETags, @Nullable String eTag, boolean weakCompare) {
eTag = padEtagIfNecessary(eTag);
if (StringUtils.hasLength(eTag)) {
eTag = ETag.quoteETagIfNecessary(eTag);
}
for (String clientEtag : requestedETags) {
// only consider "lost updates" checks for unsafe HTTP methods
if ("*".equals(clientEtag) && StringUtils.hasLength(eTag)
Expand All @@ -363,17 +366,6 @@ private boolean matchRequestedETags(List<String> requestedETags, @Nullable Strin
return true;
}

@Nullable
private String padEtagIfNecessary(@Nullable String etag) {
if (!StringUtils.hasLength(etag)) {
return etag;
}
if ((etag.startsWith("\"") || etag.startsWith("W/\"")) && etag.endsWith("\"")) {
return etag;
}
return "\"" + etag + "\"";
}

private boolean eTagStrongMatch(@Nullable String first, @Nullable String second) {
if (!StringUtils.hasLength(first) || first.startsWith("W/")) {
return false;
Expand Down Expand Up @@ -431,7 +423,7 @@ private void addCachingResponseHeaders(@Nullable String eTag, Instant lastModifi
getResponseHeaders().setLastModified(lastModified.toEpochMilli());
}
if (StringUtils.hasLength(eTag) && getResponseHeaders().getETag() == null) {
getResponseHeaders().setETag(padEtagIfNecessary(eTag));
getResponseHeaders().setETag(ETag.quoteETagIfNecessary(eTag));
}
}
}
Expand Down

0 comments on commit 3dd4a83

Please sign in to comment.