Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ Changes log
- Upgraded Jetty library to version 12.1.14. Issue #1515.
- Upgraded Jackson library to version 2.22.4.
- Upgraded org.json library to version 20260814.
- Deprecated the legacy RFC 2109/2965 cookie API (cookie version, comment and related constructors), to be removed in Restlet 3.0 in favor of RFC 6265.
- Bugs fixed
- Slf4j bridge reports wrong line number and caller class in log4j. Issue #233.
- When GET is an allowed method of a server resource, HEAD is now also listed (e.g. in the Allow header of a 405 response). Issue #266.
- The Max-Age and Path attributes of a version 1 cookie are no longer quoted in the Set-Cookie header, as browsers ignore them otherwise. Issue #1334.
- CookieAuthenticator no longer lets the next restlet overwrite the redirection sent after a login. Issue #554.

- 2.7.0 (30-09-2026)
- Misc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ protected int authenticated(Request request, Response response) {
getLogger().log(Level.SEVERE, "Could not format credentials cookie", e);
}

return super.authenticated(request, response);
int result = super.authenticated(request, response);

// Don't let the next restlet overwrite a login redirection (issue #554)
return response.getStatus().isRedirection() ? STOP : result;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.Test;
import org.restlet.Application;
import org.restlet.Component;
Expand All @@ -21,6 +22,7 @@
import org.restlet.data.CookieSetting;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Status;
import org.restlet.resource.ClientResource;
import org.restlet.resource.ResourceException;
Expand Down Expand Up @@ -100,4 +102,36 @@ void testCookieAuth1() {
cs = logoutCr.getCookieSettings().getFirst("Credentials");
assertEquals(0, cs.getMaxAge());
}

@Test
void login_withTargetUri_redirectsWithoutCallingNextRestlet() {
AtomicInteger nextCalls = new AtomicInteger();
CookieAuthenticator co =
new CookieAuthenticator(null, false, "realm", "MyExtraSecretKey".getBytes());
MapVerifier mapVerifier = new MapVerifier();
mapVerifier.getLocalSecrets().put("scott", "tiger".toCharArray());
co.setVerifier(mapVerifier);
co.setNext(
new Restlet() {
@Override
public void handle(Request request, Response response) {
nextCalls.incrementAndGet();
response.setStatus(Status.SUCCESS_OK);
}
});

Request request = new Request(Method.POST, "http://toto.com/login?targetUri=/home");
Form form = new Form();
form.add("login", "scott");
form.add("password", "tiger");
request.getResourceRef().setBaseRef("http://toto.com");
request.setEntity(form.getWebRepresentation());
Response response = new Response(request);
co.handle(request, response);

assertEquals(Status.REDIRECTION_SEE_OTHER, response.getStatus());
assertNotNull(response.getLocationRef());
assertNotNull(response.getCookieSettings().getFirst("Credentials"));
assertEquals(0, nextCalls.get());
}
}
12 changes: 12 additions & 0 deletions org.restlet/src/main/java/org/restlet/data/Cookie.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ public Cookie() {
* @param version The version number.
* @param name The name.
* @param value The value.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public Cookie(int version, String name, String value) {
this(version, name, value, null, null);
}
Expand All @@ -66,7 +69,10 @@ public Cookie(int version, String name, String value) {
* @param value The value.
* @param path The validity path.
* @param domain The domain name.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public Cookie(int version, String name, String value, String path, String domain) {
this.version = version;
this.name = name;
Expand Down Expand Up @@ -142,7 +148,10 @@ public String getValue() {
* Returns the cookie specification version.
*
* @return The cookie specification version.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public int getVersion() {
return this.version;
}
Expand Down Expand Up @@ -193,7 +202,10 @@ public void setValue(String value) {
* Sets the cookie specification version.
*
* @param version The cookie specification version.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public void setVersion(int version) {
this.version = version;
}
Expand Down
22 changes: 20 additions & 2 deletions org.restlet/src/main/java/org/restlet/data/CookieSetting.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
* Cookie setting provided by a server. This allows a server side application to add, modify, or
* remove a cookie on the client.<br>
* <br>
* Note that when used with HTTP connectors, this class maps to the "Set-Cookie" and "Set-Cookie2"
* headers.
* Note that when used with HTTP connectors, this class maps to the "Set-Cookie" header (RFC 6265).
* The "Set-Cookie2" header (RFC 2965) is deprecated.
*
* @see Response#getCookieSettings()
* @author Jerome Louvel
Expand Down Expand Up @@ -52,7 +52,10 @@ public CookieSetting() {
* @param version The cookie's version.
* @param name The cookie's name.
* @param value The cookie's value.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public CookieSetting(int version, String name, String value) {
this(version, name, value, null, null);
}
Expand All @@ -65,7 +68,10 @@ public CookieSetting(int version, String name, String value) {
* @param value The cookie's value.
* @param path The cookie's path.
* @param domain The cookie's domain name.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public CookieSetting(int version, String name, String value, String path, String domain) {
this(version, name, value, path, domain, null, -1, false, false);
}
Expand All @@ -83,7 +89,10 @@ public CookieSetting(int version, String name, String value, String path, String
* Use 0 to immediately discard an existing cookie.<br>
* Use -1 to discard the cookie at the end of the session (default).
* @param secure Indicates if the cookie should only be transmitted by secure means.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public CookieSetting(
int version,
String name,
Expand Down Expand Up @@ -111,7 +120,10 @@ public CookieSetting(
* @param secure Indicates if the cookie should only be transmitted by secure means.
* @param accessRestricted Indicates whether to restrict cookie access to untrusted parties.
* Currently, this toggles the non-standard but widely supported HttpOnly cookie parameter.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public CookieSetting(
int version,
String name,
Expand Down Expand Up @@ -160,7 +172,10 @@ public boolean equals(Object obj) {
* Returns the comment for the user.
*
* @return The comment for the user.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public String getComment() {
return this.comment;
}
Expand Down Expand Up @@ -223,7 +238,10 @@ public void setAccessRestricted(boolean accessRestricted) {
* Sets the comment for the user.
*
* @param comment The comment for the user.
* @deprecated Legacy RFC 2109/2965 cookie support is dropped in Restlet 3.0, use RFC 6265
* cookies.
*/
@Deprecated(since = "2.7.1", forRemoval = true)
public void setComment(String comment) {
this.comment = comment;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,8 @@ public CookieSettingWriter append(CookieSetting cookieSetting) throws IllegalArg
if ((path != null) && (!path.isEmpty())) {
append("; Path=");

if (version == 0) {
append(path);
} else {
appendQuotedString(path);
}
// Browsers don't unquote attribute values (RFC 6265)
append(path);
}

// Append the expiration date
Expand All @@ -91,7 +88,8 @@ public CookieSettingWriter append(CookieSetting cookieSetting) throws IllegalArg
DateUtils.format(expires, DateUtils.FORMAT_RFC_1123.getFirst()), version);
} else {
append("; Max-Age=");
appendValue(Integer.toString(cookieSetting.getMaxAge()), version);
// Must not be quoted, browsers would ignore it (issue #1334)
append(Integer.toString(maxAge));
}
} else if ((maxAge == -1) && (version > 0)) {
// Discard the cookie at the end of the user's session (RFC 2965)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,12 @@ void testParsing() throws IOException {
testCookie(
"$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\"; $Path=\"/acme/ammo\"; Part_Number=\"Rocket_Launcher_0001\"; $Path=\"/acme\"");

testCookieSetting("Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\"", true);
testCookieSetting("Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=/acme", true);
testCookieSetting("Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=/acme", true);
testCookieSetting("Shipping=\"FedEx\"; Version=\"1\"; Path=/acme", true);
testCookieSetting("Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=/acme", true);
testCookieSetting(
"Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\"", true);
testCookieSetting("Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\"", true);
testCookieSetting(
"Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\"", true);
testCookieSetting(
"Part_Number=\"Riding_Rocket_0023\"; Version=\"1\"; Path=\"/acme/ammo\"", true);
"Part_Number=\"Riding_Rocket_0023\"; Version=\"1\"; Path=/acme/ammo", true);

// Bug #49
testCookieSetting(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ void write_pathVersionZero_appendsUnquotedPath() {
}

@Test
void write_pathVersionOne_appendsQuotedPath() {
void write_pathVersionOne_appendsUnquotedPath() {
CookieSetting cookieSetting = new CookieSetting(1, "name", "value", "/path", null);
assertTrue(CookieSettingWriter.write(cookieSetting).contains("; Path=\"/path\""));
assertTrue(CookieSettingWriter.write(cookieSetting).contains("; Path=/path"));
}

@Test
Expand All @@ -63,7 +63,7 @@ void write_maxAgeVersionZero_appendsExpiresDate() {
void write_maxAgeVersionOne_appendsMaxAge() {
CookieSetting cookieSetting = new CookieSetting(1, "name", "value");
cookieSetting.setMaxAge(3600);
assertTrue(CookieSettingWriter.write(cookieSetting).contains("; Max-Age=\"3600\""));
assertTrue(CookieSettingWriter.write(cookieSetting).contains("; Max-Age=3600"));
}

@Test
Expand Down
Loading