diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/config/SockJsServiceRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/config/SockJsServiceRegistration.java index 62508e3342..1b67fea6cf 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/config/SockJsServiceRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/config/SockJsServiceRegistration.java @@ -44,7 +44,7 @@ public class SockJsServiceRegistration { private Integer streamBytesLimit; - private Boolean sessionCookieEnabled; + private Boolean sessionCookieNeeded; private Long heartbeatTime; @@ -105,14 +105,23 @@ public class SockJsServiceRegistration { } /** - * Some load balancers do sticky sessions, but only if there is a "JSESSIONID" - * cookie. Even if it is set to a dummy value, it doesn't matter since - * session information is added by the load balancer. - * - *
The default value is "false" since Java servers set the session cookie. + * The SockJS protocol requires a server to respond to the initial "/info" request + * from clients with a "cookie_needed" boolean property that indicates whether the use + * of a JSESSIONID cookie is required for the application to function correctly, e.g. + * for load balancing or in Java Servlet containers for the use of an HTTP session. + *
+ * This is especially important for IE 8,9 that support XDomainRequest -- a modified + * AJAX/XHR -- that can do requests across domains but does not send any cookies. In + * those cases, the SockJS client prefers the "iframe-htmlfile" transport over + * "xdr-streaming" in order to be able to send cookies. + *
+ * The default value is "true" to maximize the chance for applications to work + * correctly in IE 8,9 with support for cookies (and the JSESSIONID cookie in + * particular). However, an application can choose to set this to "false" if the use + * of cookies (and HTTP session) is not required. */ - public SockJsServiceRegistration setDummySessionCookieEnabled(boolean sessionCookieEnabled) { - this.sessionCookieEnabled = sessionCookieEnabled; + public SockJsServiceRegistration setSessionCookieNeeded(boolean sessionCookieNeeded) { + this.sessionCookieNeeded = sessionCookieNeeded; return this; } @@ -201,8 +210,8 @@ public class SockJsServiceRegistration { if (this.streamBytesLimit != null) { service.setStreamBytesLimit(this.streamBytesLimit); } - if (this.sessionCookieEnabled != null) { - service.setDummySessionCookieEnabled(this.sessionCookieEnabled); + if (this.sessionCookieNeeded != null) { + service.setSessionCookieNeeded(this.sessionCookieNeeded); } if (this.heartbeatTime != null) { service.setHeartbeatTime(this.heartbeatTime); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java index 9a8dc410fe..a7ddc28d46 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java @@ -77,7 +77,7 @@ public abstract class AbstractSockJsService implements SockJsService { private int streamBytesLimit = 128 * 1024; - private boolean sessionCookieEnabled = false; + private boolean sessionCookieNeeded = true; private long heartbeatTime = 25 * 1000; @@ -188,22 +188,35 @@ public abstract class AbstractSockJsService implements SockJsService { } /** - * Some load balancers do sticky sessions, but only if there is a "JSESSIONID" - * cookie. Even if it is set to a dummy value, it doesn't matter since - * session information is added by the load balancer. - * - *
The default value is "false" since Java servers set the session cookie. + * The SockJS protocol requires a server to respond to an initial "/info" request from + * clients with a "cookie_needed" boolean property that indicates whether the use of a + * JSESSIONID cookie is required for the application to function correctly, e.g. for + * load balancing or in Java Servlet containers for the use of an HTTP session. + *
+ * This is especially important for IE 8,9 that support XDomainRequest -- a modified + * AJAX/XHR -- that can do requests across domains but does not send any cookies. In + * those cases, the SockJS client prefers the "iframe-htmlfile" transport over + * "xdr-streaming" in order to be able to send cookies. + *
+ * The SockJS protocol also expects a SockJS service to echo back the JSESSIONID + * cookie when this property is set to true. However, when running in a Servlet + * container this is not necessary since the container takes care of it. + *
+ * The default value is "true" to maximize the chance for applications to work
+ * correctly in IE 8,9 with support for cookies (and the JSESSIONID cookie in
+ * particular). However, an application can choose to set this to "false" if
+ * the use of cookies (and HTTP session) is not required.
*/
- public void setDummySessionCookieEnabled(boolean sessionCookieEnabled) {
- this.sessionCookieEnabled = sessionCookieEnabled;
+ public void setSessionCookieNeeded(boolean sessionCookieNeeded) {
+ this.sessionCookieNeeded = sessionCookieNeeded;
}
/**
- * Whether setting JSESSIONID cookie is necessary.
- * @see #setDummySessionCookieEnabled(boolean)
+ * Whether JSESSIONID cookie is required for the application to function. For
+ * more detail see {@link #setSessionCookieNeeded(boolean)}.
*/
- public boolean isDummySessionCookieEnabled() {
- return this.sessionCookieEnabled;
+ public boolean isSessionCookieNeeded() {
+ return this.sessionCookieNeeded;
}
/**
@@ -506,7 +519,7 @@ public abstract class AbstractSockJsService implements SockJsService {
addCorsHeaders(request, response);
addNoCacheHeaders(response);
- String content = String.format(INFO_CONTENT, random.nextInt(), isDummySessionCookieEnabled(), isWebSocketEnabled());
+ String content = String.format(INFO_CONTENT, random.nextInt(), isSessionCookieNeeded(), isWebSocketEnabled());
response.getBody().write(content.getBytes());
}
else if (HttpMethod.OPTIONS.equals(request.getMethod())) {
diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java
index eaf2d13e26..9752031f36 100644
--- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java
+++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsService.java
@@ -29,7 +29,6 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
-import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServerHttpRequest;
@@ -306,11 +305,6 @@ public class DefaultSockJsService extends AbstractSockJsService {
addNoCacheHeaders(response);
}
- if (transportType.sendsSessionCookie() && isDummySessionCookieEnabled()) {
- String cookieValue = getJsessionIdCookieValue(request.getHeaders());
- response.getHeaders().set("Set-Cookie", "JSESSIONID=" + cookieValue + ";path=/");
- }
-
if (transportType.supportsCors()) {
addCorsHeaders(request, response);
}
@@ -386,20 +380,6 @@ public class DefaultSockJsService extends AbstractSockJsService {
}, getDisconnectDelay());
}
- private String getJsessionIdCookieValue(HttpHeaders headers) {
- List