Browse Source

Add Vary:Origin HTTP header in SockJS responses

This change adds a "Vary: Origin" HTTP response header for /info and
/iframe SockJS endpoints.
This is preventing proxies and browsers from caching a response and
reusing it for an invalid Origin.

Reference: https://groups.google.com/forum/#!topic/sockjs/svsLWRorSis

Issue: SPR-12310
pull/614/merge
Brian Clozel 10 years ago
parent
commit
2a39081819
  1. 4
      spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java
  2. 2
      spring-websocket/src/test/java/org/springframework/web/socket/sockjs/support/SockJsServiceTests.java

4
spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java

@ -117,7 +117,7 @@ public abstract class AbstractSockJsService implements SockJsService {
* server. Since the iframe needs to load the SockJS javascript client library, * server. Since the iframe needs to load the SockJS javascript client library,
* this property allows specifying where to load it from. * this property allows specifying where to load it from.
* <p>By default this is set to point to * <p>By default this is set to point to
* "https://d1fxtkz8shb9d2.cloudfront.net/sockjs-0.3.4.min.js". * "https://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js".
* However, it can also be set to point to a URL served by the application. * However, it can also be set to point to a URL served by the application.
* <p>Note that it's possible to specify a relative URL in which case the URL * <p>Note that it's possible to specify a relative URL in which case the URL
* must be relative to the iframe URL. For example assuming a SockJS endpoint * must be relative to the iframe URL. For example assuming a SockJS endpoint
@ -390,11 +390,13 @@ public abstract class AbstractSockJsService implements SockJsService {
responseHeaders.add("Access-Control-Allow-Methods", StringUtils.arrayToDelimitedString(httpMethods, ", ")); responseHeaders.add("Access-Control-Allow-Methods", StringUtils.arrayToDelimitedString(httpMethods, ", "));
responseHeaders.add("Access-Control-Max-Age", String.valueOf(ONE_YEAR)); responseHeaders.add("Access-Control-Max-Age", String.valueOf(ONE_YEAR));
} }
responseHeaders.add(HttpHeaders.VARY, HttpHeaders.ORIGIN);
} }
protected void addCacheHeaders(ServerHttpResponse response) { protected void addCacheHeaders(ServerHttpResponse response) {
response.getHeaders().setCacheControl("public, max-age=" + ONE_YEAR); response.getHeaders().setCacheControl("public, max-age=" + ONE_YEAR);
response.getHeaders().setExpires(new Date().getTime() + ONE_YEAR * 1000); response.getHeaders().setExpires(new Date().getTime() + ONE_YEAR * 1000);
response.getHeaders().add(HttpHeaders.VARY, HttpHeaders.ORIGIN);
} }
protected void addNoCacheHeaders(ServerHttpResponse response) { protected void addNoCacheHeaders(ServerHttpResponse response) {

2
spring-websocket/src/test/java/org/springframework/web/socket/sockjs/support/SockJsServiceTests.java

@ -83,6 +83,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
assertEquals("*", this.servletResponse.getHeader("Access-Control-Allow-Origin")); assertEquals("*", this.servletResponse.getHeader("Access-Control-Allow-Origin"));
assertEquals("true", this.servletResponse.getHeader("Access-Control-Allow-Credentials")); assertEquals("true", this.servletResponse.getHeader("Access-Control-Allow-Credentials"));
assertEquals("no-store, no-cache, must-revalidate, max-age=0", this.servletResponse.getHeader("Cache-Control")); assertEquals("no-store, no-cache, must-revalidate, max-age=0", this.servletResponse.getHeader("Cache-Control"));
assertEquals("Origin", this.servletResponse.getHeader("Vary"));
String body = this.servletResponse.getContentAsString(); String body = this.servletResponse.getContentAsString();
assertEquals("{\"entropy\"", body.substring(0, body.indexOf(':'))); assertEquals("{\"entropy\"", body.substring(0, body.indexOf(':')));
@ -133,6 +134,7 @@ public class SockJsServiceTests extends AbstractHttpRequestTests {
assertEquals("Last-Modified", this.servletResponse.getHeader("Access-Control-Allow-Headers")); assertEquals("Last-Modified", this.servletResponse.getHeader("Access-Control-Allow-Headers"));
assertEquals("OPTIONS, GET", this.servletResponse.getHeader("Access-Control-Allow-Methods")); assertEquals("OPTIONS, GET", this.servletResponse.getHeader("Access-Control-Allow-Methods"));
assertEquals("31536000", this.servletResponse.getHeader("Access-Control-Max-Age")); assertEquals("31536000", this.servletResponse.getHeader("Access-Control-Max-Age"));
assertEquals("Origin", this.servletResponse.getHeader("Vary"));
} }
@Test @Test

Loading…
Cancel
Save