Browse Source

Update more places to use quoteETagIfNecessary

Closes gh-33412
pull/33525/head
rstoyanchev 1 year ago
parent
commit
3dd4a8350a
  1. 10
      spring-web/src/main/java/org/springframework/http/HttpHeaders.java
  2. 29
      spring-web/src/main/java/org/springframework/web/context/request/ServletWebRequest.java
  3. 20
      spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java

10
spring-web/src/main/java/org/springframework/http/HttpHeaders.java

@ -1063,11 +1063,11 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable @@ -1063,11 +1063,11 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
/**
* 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);

29
spring-web/src/main/java/org/springframework/web/context/request/ServletWebRequest.java

@ -247,23 +247,25 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ @@ -247,23 +247,25 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
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;
}
}
@ -272,17 +274,6 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ @@ -272,17 +274,6 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
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;
@ -346,13 +337,13 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ @@ -346,13 +337,13 @@ public class ServletWebRequest extends ServletRequestAttributes implements Nativ
}
}
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));
}
}
}

20
spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java

@ -1,5 +1,5 @@ @@ -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.
@ -33,6 +33,7 @@ import org.springframework.context.ApplicationContext; @@ -33,6 +33,7 @@ import org.springframework.context.ApplicationContext;
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;
@ -341,7 +342,9 @@ public class DefaultServerWebExchange implements ServerWebExchange { @@ -341,7 +342,9 @@ public class DefaultServerWebExchange implements ServerWebExchange {
}
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)
@ -363,17 +366,6 @@ public class DefaultServerWebExchange implements ServerWebExchange { @@ -363,17 +366,6 @@ public class DefaultServerWebExchange implements ServerWebExchange {
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;
@ -431,7 +423,7 @@ public class DefaultServerWebExchange implements ServerWebExchange { @@ -431,7 +423,7 @@ public class DefaultServerWebExchange implements ServerWebExchange {
getResponseHeaders().setLastModified(lastModified.toEpochMilli());
}
if (StringUtils.hasLength(eTag) && getResponseHeaders().getETag() == null) {
getResponseHeaders().setETag(padEtagIfNecessary(eTag));
getResponseHeaders().setETag(ETag.quoteETagIfNecessary(eTag));
}
}
}

Loading…
Cancel
Save