Undo workaround for SameSite support in WebFlux

This commit implements Cookie support in WebFlux without any workaround
as now all supported servers have the SameSite feature enabled.

Closes gh-31954
This commit is contained in:
Brian Clozel
2024-01-05 14:44:32 +01:00
parent 476ef0c3ca
commit 1372265bd9
3 changed files with 51 additions and 28 deletions

View File

@@ -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.
@@ -17,10 +17,11 @@
package org.springframework.http.server.reactive;
import java.nio.file.Path;
import java.util.List;
import io.netty5.buffer.Buffer;
import io.netty5.channel.ChannelId;
import io.netty5.handler.codec.http.headers.DefaultHttpSetCookie;
import io.netty5.handler.codec.http.headers.HttpSetCookie;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.reactivestreams.Publisher;
@@ -106,11 +107,13 @@ class ReactorNetty2ServerHttpResponse extends AbstractServerHttpResponse impleme
@Override
protected void applyCookies() {
// Netty Cookie doesn't support sameSite. When this is resolved, we can adapt to it again:
// https://github.com/netty/netty/issues/8161
for (List<ResponseCookie> cookies : getCookies().values()) {
for (ResponseCookie cookie : cookies) {
this.response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
for (String name : getCookies().keySet()) {
for (ResponseCookie httpCookie : getCookies().get(name)) {
Long maxAge = (!httpCookie.getMaxAge().isNegative()) ? httpCookie.getMaxAge().getSeconds() : null;
HttpSetCookie.SameSite sameSite = (httpCookie.getSameSite() != null) ? HttpSetCookie.SameSite.valueOf(httpCookie.getSameSite()) : null;
DefaultHttpSetCookie cookie = new DefaultHttpSetCookie(name, httpCookie.getValue(), httpCookie.getPath(),
httpCookie.getDomain(), null, maxAge, sameSite, false, httpCookie.isSecure(), httpCookie.isHttpOnly());
this.response.addCookie(cookie);
}
}
}

View File

@@ -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.
@@ -17,11 +17,12 @@
package org.springframework.http.server.reactive;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelId;
import io.netty.handler.codec.http.cookie.CookieHeaderNames;
import io.netty.handler.codec.http.cookie.DefaultCookie;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.reactivestreams.Publisher;
@@ -105,11 +106,24 @@ class ReactorServerHttpResponse extends AbstractServerHttpResponse implements Ze
@Override
protected void applyCookies() {
// Netty Cookie doesn't support sameSite. When this is resolved, we can adapt to it again:
// https://github.com/netty/netty/issues/8161
for (List<ResponseCookie> cookies : getCookies().values()) {
for (ResponseCookie cookie : cookies) {
this.response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
for (String name : getCookies().keySet()) {
for (ResponseCookie httpCookie : getCookies().get(name)) {
DefaultCookie cookie = new DefaultCookie(name, httpCookie.getValue());
if (!httpCookie.getMaxAge().isNegative()) {
cookie.setMaxAge(httpCookie.getMaxAge().getSeconds());
}
if (httpCookie.getDomain() != null) {
cookie.setDomain(httpCookie.getDomain());
}
if (httpCookie.getPath() != null) {
cookie.setPath(httpCookie.getPath());
}
cookie.setSecure(httpCookie.isSecure());
cookie.setHttpOnly(httpCookie.isHttpOnly());
if (httpCookie.getSameSite() != null) {
cookie.setSameSite(CookieHeaderNames.SameSite.valueOf(httpCookie.getSameSite()));
}
this.response.addCookie(cookie);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -19,13 +19,13 @@ package org.springframework.http.server.reactive;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List;
import jakarta.servlet.AsyncContext;
import jakarta.servlet.AsyncEvent;
import jakarta.servlet.AsyncListener;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.WriteListener;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import org.reactivestreams.Processor;
import org.reactivestreams.Publisher;
@@ -164,18 +164,24 @@ class ServletServerHttpResponse extends AbstractListenerServerHttpResponse {
@Override
protected void applyCookies() {
// Servlet Cookie doesn't support same site:
// https://github.com/eclipse-ee4j/servlet-api/issues/175
// For Jetty, starting 9.4.21+ we could adapt to HttpCookie:
// https://github.com/eclipse/jetty.project/issues/3040
// For Tomcat, it seems to be a global option only:
// https://tomcat.apache.org/tomcat-8.5-doc/config/cookie-processor.html
for (List<ResponseCookie> cookies : getCookies().values()) {
for (ResponseCookie cookie : cookies) {
this.response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
for (String name : getCookies().keySet()) {
for (ResponseCookie httpCookie : getCookies().get(name)) {
Cookie cookie = new Cookie(name, httpCookie.getValue());
if (!httpCookie.getMaxAge().isNegative()) {
cookie.setMaxAge((int) httpCookie.getMaxAge().getSeconds());
}
if (httpCookie.getDomain() != null) {
cookie.setDomain(httpCookie.getDomain());
}
if (httpCookie.getPath() != null) {
cookie.setPath(httpCookie.getPath());
}
if (httpCookie.getSameSite() != null) {
cookie.setAttribute("SameSite", httpCookie.getSameSite());
}
cookie.setSecure(httpCookie.isSecure());
cookie.setHttpOnly(httpCookie.isHttpOnly());
this.response.addCookie(cookie);
}
}
}