diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java b/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java index 31a4615917..7bcd893cc8 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockCookie.java @@ -19,9 +19,10 @@ package org.springframework.mock.web; import javax.servlet.http.Cookie; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** - * A {@code Cookie} subclass with the additional cookie directives as defined in the + * Extension of {@code Cookie} with extra directives, as defined in * RFC 6265. * * @author Vedran Pavic @@ -31,96 +32,84 @@ public class MockCookie extends Cookie { private static final long serialVersionUID = 4312531139502726325L; + @Nullable private String sameSite; + /** - * Constructs a {@code MockCookie} instance with the specified name and value. - * - * @param name the cookie name - * @param value the cookie value + * Constructor with the cookie name and value. + * @param name the name + * @param value the value * @see Cookie#Cookie(String, String) */ public MockCookie(String name, String value) { super(name, value); } - /** - * Factory method create {@code MockCookie} instance from Set-Cookie header value. - * - * @param setCookieHeader the Set-Cookie header value - * @return the created cookie instance - */ - public static MockCookie parse(String setCookieHeader) { - String[] cookieParts = setCookieHeader.split("\\s*=\\s*", 2); - if (cookieParts.length != 2) { - throw new IllegalArgumentException("Invalid Set-Cookie header value"); - } - String name = cookieParts[0]; - String[] valueAndDirectives = cookieParts[1].split("\\s*;\\s*", 2); - String value = valueAndDirectives[0]; - String[] directives = valueAndDirectives[1].split("\\s*;\\s*"); - String domain = null; - int maxAge = -1; - String path = null; - boolean secure = false; - boolean httpOnly = false; - String sameSite = null; - for (String directive : directives) { - if (directive.startsWith("Domain")) { - domain = directive.split("=")[1]; - } - else if (directive.startsWith("Max-Age")) { - maxAge = Integer.parseInt(directive.split("=")[1]); - } - else if (directive.startsWith("Path")) { - path = directive.split("=")[1]; - } - else if (directive.startsWith("Secure")) { - secure = true; - } - else if (directive.startsWith("HttpOnly")) { - httpOnly = true; - } - else if (directive.startsWith("SameSite")) { - sameSite = directive.split("=")[1]; - } - } - MockCookie cookie = new MockCookie(name, value); - if (domain != null) { - cookie.setDomain(domain); - } - cookie.setMaxAge(maxAge); - cookie.setPath(path); - cookie.setSecure(secure); - cookie.setHttpOnly(httpOnly); - cookie.setSameSite(sameSite); - return cookie; - } - - /** - * Return the cookie "SameSite" attribute, or {@code null} if not set. - *
- * This limits the scope of the cookie such that it will only be attached to same site - * requests if {@code "Strict"} or cross-site requests if {@code "Lax"}. - * - * @see RFC6265 bis - */ - @Nullable - public String getSameSite() { - return this.sameSite; - } /** * Add the "SameSite" attribute to the cookie. - *
- * This limits the scope of the cookie such that it will only be attached to same site - * requests if {@code "Strict"} or cross-site requests if {@code "Lax"}. - * + *
This limits the scope of the cookie such that it will only be attached + * to same site requests if {@code "Strict"} or cross-site requests if + * {@code "Lax"}. * @see RFC6265 bis */ public void setSameSite(@Nullable String sameSite) { this.sameSite = sameSite; } + /** + * Return the "SameSite" attribute, or {@code null} if not set. + */ + @Nullable + public String getSameSite() { + return this.sameSite; + } + + + /** + * Factory method that parses the value of a "Set-Cookie" header. + * @param setCookieHeader the "Set-Cookie" value + * @return the created cookie + */ + public static MockCookie parse(String setCookieHeader) { + String[] cookieParts = setCookieHeader.split("\\s*=\\s*", 2); + Assert.isTrue(cookieParts.length == 2, "Invalid Set-Cookie header value"); + + String name = cookieParts[0]; + String[] valueAndDirectives = cookieParts[1].split("\\s*;\\s*", 2); + String value = valueAndDirectives[0]; + String[] directives = valueAndDirectives[1].split("\\s*;\\s*"); + + MockCookie cookie = new MockCookie(name, value); + for (String directive : directives) { + if (directive.startsWith("Domain")) { + cookie.setDomain(extractDirectiveValue(directive)); + } + else if (directive.startsWith("Max-Age")) { + cookie.setMaxAge(Integer.parseInt(extractDirectiveValue(directive))); + } + else if (directive.startsWith("Path")) { + cookie.setPath(extractDirectiveValue(directive)); + } + else if (directive.startsWith("Secure")) { + cookie.setSecure(true); + } + else if (directive.startsWith("HttpOnly")) { + cookie.setHttpOnly(true); + } + else if (directive.startsWith("SameSite")) { + cookie.setSameSite(extractDirectiveValue(directive)); + } + } + return cookie; + } + + private static String extractDirectiveValue(String directive) { + String[] nameAndValue = directive.split("="); + Assert.isTrue(nameAndValue.length == 2, () -> "No value in directive: '" + directive + "'"); + return nameAndValue[1]; + } + } diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockCookie.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockCookie.java index 4d1f05b178..75cd4b80a5 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockCookie.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockCookie.java @@ -19,9 +19,10 @@ package org.springframework.mock.web.test; import javax.servlet.http.Cookie; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** - * A {@code Cookie} subclass with the additional cookie directives as defined in the + * Extension of {@code Cookie} with extra directives, as defined in * RFC 6265. * * @author Vedran Pavic @@ -31,96 +32,84 @@ public class MockCookie extends Cookie { private static final long serialVersionUID = 4312531139502726325L; + @Nullable private String sameSite; + /** - * Constructs a {@code MockCookie} instance with the specified name and value. - * - * @param name the cookie name - * @param value the cookie value + * Constructor with the cookie name and value. + * @param name the name + * @param value the value * @see Cookie#Cookie(String, String) */ public MockCookie(String name, String value) { super(name, value); } - /** - * Factory method create {@code MockCookie} instance from Set-Cookie header value. - * - * @param setCookieHeader the Set-Cookie header value - * @return the created cookie instance - */ - public static MockCookie parse(String setCookieHeader) { - String[] cookieParts = setCookieHeader.split("\\s*=\\s*", 2); - if (cookieParts.length != 2) { - throw new IllegalArgumentException("Invalid Set-Cookie header value"); - } - String name = cookieParts[0]; - String[] valueAndDirectives = cookieParts[1].split("\\s*;\\s*", 2); - String value = valueAndDirectives[0]; - String[] directives = valueAndDirectives[1].split("\\s*;\\s*"); - String domain = null; - int maxAge = -1; - String path = null; - boolean secure = false; - boolean httpOnly = false; - String sameSite = null; - for (String directive : directives) { - if (directive.startsWith("Domain")) { - domain = directive.split("=")[1]; - } - else if (directive.startsWith("Max-Age")) { - maxAge = Integer.parseInt(directive.split("=")[1]); - } - else if (directive.startsWith("Path")) { - path = directive.split("=")[1]; - } - else if (directive.startsWith("Secure")) { - secure = true; - } - else if (directive.startsWith("HttpOnly")) { - httpOnly = true; - } - else if (directive.startsWith("SameSite")) { - sameSite = directive.split("=")[1]; - } - } - MockCookie cookie = new MockCookie(name, value); - if (domain != null) { - cookie.setDomain(domain); - } - cookie.setMaxAge(maxAge); - cookie.setPath(path); - cookie.setSecure(secure); - cookie.setHttpOnly(httpOnly); - cookie.setSameSite(sameSite); - return cookie; - } - - /** - * Return the cookie "SameSite" attribute, or {@code null} if not set. - *
- * This limits the scope of the cookie such that it will only be attached to same site - * requests if {@code "Strict"} or cross-site requests if {@code "Lax"}. - * - * @see RFC6265 bis - */ - @Nullable - public String getSameSite() { - return this.sameSite; - } /** * Add the "SameSite" attribute to the cookie. - *
- * This limits the scope of the cookie such that it will only be attached to same site - * requests if {@code "Strict"} or cross-site requests if {@code "Lax"}. - * + *
This limits the scope of the cookie such that it will only be attached + * to same site requests if {@code "Strict"} or cross-site requests if + * {@code "Lax"}. * @see RFC6265 bis */ public void setSameSite(@Nullable String sameSite) { this.sameSite = sameSite; } + /** + * Return the "SameSite" attribute, or {@code null} if not set. + */ + @Nullable + public String getSameSite() { + return this.sameSite; + } + + + /** + * Factory method that parses the value of a "Set-Cookie" header. + * @param setCookieHeader the "Set-Cookie" value + * @return the created cookie + */ + public static MockCookie parse(String setCookieHeader) { + String[] cookieParts = setCookieHeader.split("\\s*=\\s*", 2); + Assert.isTrue(cookieParts.length == 2, "Invalid Set-Cookie header value"); + + String name = cookieParts[0]; + String[] valueAndDirectives = cookieParts[1].split("\\s*;\\s*", 2); + String value = valueAndDirectives[0]; + String[] directives = valueAndDirectives[1].split("\\s*;\\s*"); + + MockCookie cookie = new MockCookie(name, value); + for (String directive : directives) { + if (directive.startsWith("Domain")) { + cookie.setDomain(extractDirectiveValue(directive)); + } + else if (directive.startsWith("Max-Age")) { + cookie.setMaxAge(Integer.parseInt(extractDirectiveValue(directive))); + } + else if (directive.startsWith("Path")) { + cookie.setPath(extractDirectiveValue(directive)); + } + else if (directive.startsWith("Secure")) { + cookie.setSecure(true); + } + else if (directive.startsWith("HttpOnly")) { + cookie.setHttpOnly(true); + } + else if (directive.startsWith("SameSite")) { + cookie.setSameSite(extractDirectiveValue(directive)); + } + } + return cookie; + } + + private static String extractDirectiveValue(String directive) { + String[] nameAndValue = directive.split("="); + Assert.isTrue(nameAndValue.length == 2, () -> "No value in directive: '" + directive + "'"); + return nameAndValue[1]; + } + }