Skip to content

Commit

Permalink
Merge pull request #891 from marcioferlan/master
Browse files Browse the repository at this point in the history
Bypass VRaptor filter in WebSocket requests.
  • Loading branch information
Turini committed Nov 24, 2014
2 parents 0cd8cb1 + b36da4f commit 5192556
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
17 changes: 16 additions & 1 deletion vraptor-core/src/main/java/br/com/caelum/vraptor/VRaptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,12 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)

final HttpServletRequest baseRequest = (HttpServletRequest) req;
final HttpServletResponse baseResponse = (HttpServletResponse) res;


if (isWebsocketRequest(baseRequest)) {
chain.doFilter(req, res);
return;
}

if (staticHandler.requestingStaticFile(baseRequest)) {
staticHandler.deferProcessingToContainer(chain, baseRequest, baseResponse);
} else {
Expand Down Expand Up @@ -172,4 +177,14 @@ private void validateIfCdiIsFound() throws ServletException {
throw new ServletException("Dependencies were not set. Do you have a Weld/CDI listener setup in your web.xml?");
}
}

/**
* According to the Websocket spec (https://tools.ietf.org/html/rfc6455): The WebSocket Protocol
* 5. The request MUST contain an |Upgrade| header field whose value MUST include the "websocket" keyword.
*/
private boolean isWebsocketRequest(HttpServletRequest request) {
String upgradeHeader = request.getHeader("Upgrade");
return upgradeHeader != null && upgradeHeader.toLowerCase().contains("websocket");
}

}
29 changes: 25 additions & 4 deletions vraptor-core/src/test/java/br/com/caelum/vraptor/VRaptorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
*/
package br.com.caelum.vraptor;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import javax.inject.Inject;
import javax.servlet.FilterChain;
Expand All @@ -39,8 +42,10 @@ public class VRaptorTest {
@Rule
public ExpectedException exception = ExpectedException.none();

@Inject private VRaptor vRaptor;
@Inject private MockStaticContentHandler handler;
@Inject
private VRaptor vRaptor;
@Inject
private MockStaticContentHandler handler;

@Test
public void shoudlComplainIfNotInAServletEnviroment() throws Exception {
Expand All @@ -52,12 +57,28 @@ public void shoudlComplainIfNotInAServletEnviroment() throws Exception {
}

@Test
public void shouldDeferToContainerIfStaticFile() throws Exception{
public void shouldDeferToContainerIfStaticFile() throws Exception {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
FilterChain chain = mock(FilterChain.class);
handler.setRequestingStaticFile(true);
vRaptor.doFilter(request, response, chain);
assertThat(handler.isDeferProcessingToContainerCalled(), is(true));
}

@Test
public void shouldBypassWebsocketRequests() throws Exception {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
FilterChain chain = mock(FilterChain.class);

when(request.getHeader("Upgrade")).thenReturn("Websocket");

vRaptor.doFilter(request, response, chain);
verify(request).getHeader("Upgrade");
verify(chain).doFilter(request, response);

verifyNoMoreInteractions(request, response);
}

}

0 comments on commit 5192556

Please sign in to comment.