Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.1.x
This commit is contained in:
commit
76962e966a
|
@ -423,6 +423,7 @@ public abstract class IteratingCallback implements Callback
|
|||
{
|
||||
// we won the race against the callback, so the callback has to process and we can break processing
|
||||
_state = State.PENDING;
|
||||
_reprocess = false;
|
||||
if (_aborted)
|
||||
{
|
||||
onAbortedOnFailureIfNotPendingDoCompleted = _failure;
|
||||
|
@ -482,6 +483,7 @@ public abstract class IteratingCallback implements Callback
|
|||
}
|
||||
callOnSuccess = true;
|
||||
_state = State.PROCESSING;
|
||||
_reprocess = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -818,6 +820,14 @@ public abstract class IteratingCallback implements Callback
|
|||
return true;
|
||||
}
|
||||
|
||||
boolean isPending()
|
||||
{
|
||||
try (AutoLock ignored = _lock.lock())
|
||||
{
|
||||
return _state == State.PENDING;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this callback is idle, and {@link #iterate()} needs to be called
|
||||
*/
|
||||
|
|
|
@ -33,7 +33,9 @@ import org.junit.jupiter.api.Test;
|
|||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
@ -63,6 +65,45 @@ public class IteratingCallbackTest
|
|||
scheduler.stop();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testIterateWhileProcessingLoopCount(boolean succeededWinsRace)
|
||||
{
|
||||
var icb = new IteratingCallback()
|
||||
{
|
||||
int counter = 0;
|
||||
|
||||
@Override
|
||||
protected Action process()
|
||||
{
|
||||
int counter = this.counter++;
|
||||
if (counter == 0)
|
||||
{
|
||||
iterate();
|
||||
if (succeededWinsRace)
|
||||
{
|
||||
succeeded();
|
||||
}
|
||||
else
|
||||
{
|
||||
new Thread(() ->
|
||||
{
|
||||
await().atMost(5, TimeUnit.SECONDS).until(this::isPending, is(true));
|
||||
succeeded();
|
||||
}).start();
|
||||
}
|
||||
return Action.SCHEDULED;
|
||||
}
|
||||
return Action.IDLE;
|
||||
}
|
||||
};
|
||||
|
||||
icb.iterate();
|
||||
|
||||
await().atMost(10, TimeUnit.SECONDS).until(icb::isIdle, is(true));
|
||||
assertEquals(2, icb.counter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonWaitingProcess() throws Exception
|
||||
{
|
||||
|
|
|
@ -76,20 +76,20 @@ public class Response implements HttpServletResponse
|
|||
* String used in the {@code Comment} attribute of {@link Cookie}
|
||||
* to support the {@code HttpOnly} attribute.
|
||||
**/
|
||||
private static final String HTTP_ONLY_COMMENT = "__HTTP_ONLY__";
|
||||
protected static final String HTTP_ONLY_COMMENT = "__HTTP_ONLY__";
|
||||
/**
|
||||
* String used in the {@code Comment} attribute of {@link Cookie}
|
||||
* to support the {@code Partitioned} attribute.
|
||||
**/
|
||||
private static final String PARTITIONED_COMMENT = "__PARTITIONED__";
|
||||
protected static final String PARTITIONED_COMMENT = "__PARTITIONED__";
|
||||
/**
|
||||
* The strings used in the {@code Comment} attribute of {@link Cookie}
|
||||
* to support the {@code SameSite} attribute.
|
||||
**/
|
||||
private static final String SAME_SITE_COMMENT = "__SAME_SITE_";
|
||||
private static final String SAME_SITE_NONE_COMMENT = SAME_SITE_COMMENT + "NONE__";
|
||||
private static final String SAME_SITE_LAX_COMMENT = SAME_SITE_COMMENT + "LAX__";
|
||||
private static final String SAME_SITE_STRICT_COMMENT = SAME_SITE_COMMENT + "STRICT__";
|
||||
protected static final String SAME_SITE_COMMENT = "__SAME_SITE_";
|
||||
protected static final String SAME_SITE_NONE_COMMENT = SAME_SITE_COMMENT + "NONE__";
|
||||
protected static final String SAME_SITE_LAX_COMMENT = SAME_SITE_COMMENT + "LAX__";
|
||||
protected static final String SAME_SITE_STRICT_COMMENT = SAME_SITE_COMMENT + "STRICT__";
|
||||
|
||||
public enum OutputType
|
||||
{
|
||||
|
@ -1465,7 +1465,7 @@ public class Response implements HttpServletResponse
|
|||
return (HttpServletResponse)servletResponse;
|
||||
}
|
||||
|
||||
private static class HttpFieldsSupplier implements Supplier<HttpFields>
|
||||
protected static class HttpFieldsSupplier implements Supplier<HttpFields>
|
||||
{
|
||||
private final Supplier<Map<String, String>> _supplier;
|
||||
|
||||
|
@ -1494,7 +1494,7 @@ public class Response implements HttpServletResponse
|
|||
}
|
||||
}
|
||||
|
||||
private static class HttpCookieFacade implements HttpCookie
|
||||
protected static class HttpCookieFacade implements HttpCookie
|
||||
{
|
||||
private final Cookie _cookie;
|
||||
private final String _comment;
|
||||
|
@ -1622,12 +1622,12 @@ public class Response implements HttpServletResponse
|
|||
return comment != null && comment.contains(HTTP_ONLY_COMMENT);
|
||||
}
|
||||
|
||||
private static boolean isPartitionedInComment(String comment)
|
||||
protected static boolean isPartitionedInComment(String comment)
|
||||
{
|
||||
return comment != null && comment.contains(PARTITIONED_COMMENT);
|
||||
}
|
||||
|
||||
private static SameSite getSameSiteFromComment(String comment)
|
||||
protected static SameSite getSameSiteFromComment(String comment)
|
||||
{
|
||||
if (comment == null)
|
||||
return null;
|
||||
|
@ -1640,7 +1640,7 @@ public class Response implements HttpServletResponse
|
|||
return null;
|
||||
}
|
||||
|
||||
private static String getCommentWithoutAttributes(String comment)
|
||||
protected static String getCommentWithoutAttributes(String comment)
|
||||
{
|
||||
if (comment == null)
|
||||
return null;
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.eclipse.jetty.session.SessionConfig;
|
|||
import org.eclipse.jetty.session.SessionIdManager;
|
||||
import org.eclipse.jetty.session.SessionManager;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -613,7 +614,8 @@ public class SessionHandler extends ScopedHandler implements SessionConfig.Mutab
|
|||
* CookieConfig
|
||||
*
|
||||
* Implementation of the jakarta.servlet.SessionCookieConfig.
|
||||
* SameSite configuration can be achieved by using setComment
|
||||
* SameSite configuration can be achieved by using setComment.
|
||||
* Partitioned configuration can be achieved by using setComment.
|
||||
*
|
||||
* @see HttpCookie
|
||||
*/
|
||||
|
@ -671,7 +673,19 @@ public class SessionHandler extends ScopedHandler implements SessionConfig.Mutab
|
|||
public void setComment(String comment)
|
||||
{
|
||||
checkAvailable();
|
||||
_sessionManager.setSessionComment(comment);
|
||||
|
||||
if (!StringUtil.isEmpty(comment))
|
||||
{
|
||||
HttpCookie.SameSite sameSite = Response.HttpCookieFacade.getSameSiteFromComment(comment);
|
||||
if (sameSite != null)
|
||||
_sessionManager.setSameSite(sameSite);
|
||||
|
||||
boolean partitioned = Response.HttpCookieFacade.isPartitionedInComment(comment);
|
||||
if (partitioned)
|
||||
_sessionManager.setPartitioned(partitioned);
|
||||
|
||||
_sessionManager.setSessionComment(Response.HttpCookieFacade.getCommentWithoutAttributes(comment));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -168,7 +168,7 @@ public class SessionHandlerTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSessionCookie() throws Exception
|
||||
public void testSessionCookieConfig() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
MockSessionIdManager idMgr = new MockSessionIdManager(server);
|
||||
|
@ -191,8 +191,47 @@ public class SessionHandlerTest
|
|||
sessionCookieConfig.setPath("/foo");
|
||||
sessionCookieConfig.setMaxAge(99);
|
||||
|
||||
//for < ee10, SameSite cannot be set on the SessionCookieConfig, only on the SessionManager, or
|
||||
//a default value on the context attribute org.eclipse.jetty.cookie.sameSiteDefault
|
||||
//test setting SameSite and Partitioned the old way in the comment
|
||||
sessionCookieConfig.setComment(Response.PARTITIONED_COMMENT + " " + Response.SAME_SITE_STRICT_COMMENT);
|
||||
|
||||
HttpCookie cookie = mgr.getSessionManager().getSessionCookie(session, false);
|
||||
assertEquals("SPECIAL", cookie.getName());
|
||||
assertEquals("universe", cookie.getDomain());
|
||||
assertEquals("/foo", cookie.getPath());
|
||||
assertFalse(cookie.isHttpOnly());
|
||||
assertFalse(cookie.isSecure());
|
||||
assertTrue(cookie.isPartitioned());
|
||||
assertEquals(99, cookie.getMaxAge());
|
||||
assertEquals(HttpCookie.SameSite.STRICT, cookie.getSameSite());
|
||||
|
||||
String cookieStr = HttpCookieUtils.getRFC6265SetCookie(cookie);
|
||||
assertThat(cookieStr, containsString("; Partitioned; SameSite=Strict"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSessionCookieViaSetters() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
MockSessionIdManager idMgr = new MockSessionIdManager(server);
|
||||
idMgr.setWorkerName("node1");
|
||||
SessionHandler mgr = new SessionHandler();
|
||||
MockSessionCache cache = new MockSessionCache(mgr.getSessionManager());
|
||||
cache.setSessionDataStore(new NullSessionDataStore());
|
||||
mgr.setSessionCache(cache);
|
||||
mgr.setSessionIdManager(idMgr);
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
ManagedSession session = new ManagedSession(mgr.getSessionManager(), new SessionData("123", "_foo", "0.0.0.0", now, now, now, 30));
|
||||
session.setExtendedId("123.node1");
|
||||
|
||||
//test setting up session cookie via setters on SessionHandler
|
||||
mgr.setSessionCookie("SPECIAL");
|
||||
mgr.setSessionDomain("universe");
|
||||
mgr.setHttpOnly(false);
|
||||
mgr.setSecureCookies(false);
|
||||
mgr.setSessionPath("/foo");
|
||||
mgr.setMaxCookieAge(99);
|
||||
mgr.setSameSite(HttpCookie.SameSite.STRICT);
|
||||
mgr.setPartitioned(true);
|
||||
|
||||
|
|
Loading…
Reference in New Issue