aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryankee <yzeugs@cipher-code.de>2014-04-24 23:32:38 +0200
committeryankee <yzeugs@cipher-code.de>2014-04-24 23:34:40 +0200
commit44f52c7b241f235d887ab57bf0ffd97a8ce0f5c4 (patch)
treec49ae2ed4c3da14926255320c3dfe2bea892ed56
parent6aa9777e0f8337050acb378ed5ecbb24e467d85c (diff)
downloadnanohttpd-44f52c7b241f235d887ab57bf0ffd97a8ce0f5c4.tar.gz
Added basic test for websockets
-rw-r--r--core/src/main/java/fi/iki/elonen/NanoHTTPD.java4
-rw-r--r--websocket/pom.xml6
-rw-r--r--websocket/src/test/java/fi/iki/elonen/WebSocketResponseHandlerTest.java97
-rw-r--r--websocket/src/test/java/fi/iki/elonen/testutil/MockHttpSession.java64
4 files changed, 171 insertions, 0 deletions
diff --git a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java
index ba01443..2676a70 100644
--- a/core/src/main/java/fi/iki/elonen/NanoHTTPD.java
+++ b/core/src/main/java/fi/iki/elonen/NanoHTTPD.java
@@ -606,6 +606,10 @@ public abstract class NanoHTTPD {
public void addHeader(String name, String value) {
header.put(name, value);
}
+
+ public String getHeader(String name) {
+ return header.get(name);
+ }
/**
* Sends given response to the socket.
diff --git a/websocket/pom.xml b/websocket/pom.xml
index ca24ea2..7e8960f 100644
--- a/websocket/pom.xml
+++ b/websocket/pom.xml
@@ -12,6 +12,12 @@
<dependencies>
<dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>fi.iki.elonen</groupId>
<artifactId>nanohttpd</artifactId>
<version>2.1.0</version>
diff --git a/websocket/src/test/java/fi/iki/elonen/WebSocketResponseHandlerTest.java b/websocket/src/test/java/fi/iki/elonen/WebSocketResponseHandlerTest.java
new file mode 100644
index 0000000..c007fde
--- /dev/null
+++ b/websocket/src/test/java/fi/iki/elonen/WebSocketResponseHandlerTest.java
@@ -0,0 +1,97 @@
+package fi.iki.elonen;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import fi.iki.elonen.NanoHTTPD.IHTTPSession;
+import fi.iki.elonen.NanoHTTPD.Response;
+import fi.iki.elonen.WebSocketFrame.CloseCode;
+import fi.iki.elonen.testutil.MockHttpSession;
+import static junit.framework.Assert.*;
+
+public class WebSocketResponseHandlerTest {
+ private WebSocketResponseHandler responseHandler = new WebSocketResponseHandler(new DummyWebSocketFactory(
+ new WebSocketAdapter(new MockHttpSession())));
+
+ @Test
+ public void testHandshake_returnsExpectedHeaders() {
+ MockHttpSession session = createWebSocketHandshakeRequest();
+
+ Response handshakeResponse = responseHandler.serve(session);
+
+ assertNotNull(handshakeResponse);
+ assertEquals(101, handshakeResponse.getStatus().getRequestStatus());
+ assertEquals("101 Switching Protocols", handshakeResponse.getStatus().getDescription());
+ assertEquals("websocket", handshakeResponse.getHeader("upgrade"));
+ assertEquals("Upgrade", handshakeResponse.getHeader("connection"));
+ assertEquals("HSmrc0sMlYUkAGmm5OPpG2HaGWk=", handshakeResponse.getHeader("sec-websocket-accept"));
+ assertEquals("chat", handshakeResponse.getHeader("sec-websocket-protocol"));
+ }
+
+ @Test
+ public void testWrongWebsocketVersion_returnsErrorResponse() {
+ MockHttpSession session = createWebSocketHandshakeRequest();
+ session.getHeaders().put("sec-websocket-version", "12");
+
+ Response handshakeResponse = responseHandler.serve(session);
+
+ assertNotNull(handshakeResponse);
+ assertEquals(400, handshakeResponse.getStatus().getRequestStatus());
+ assertEquals("400 Bad Request", handshakeResponse.getStatus().getDescription());
+ }
+
+ private MockHttpSession createWebSocketHandshakeRequest() {
+ // Example headers copied from Wikipedia
+ MockHttpSession session = new MockHttpSession();
+ session.getHeaders().put("upgrade", "websocket");
+ session.getHeaders().put("connection", "Upgrade");
+ session.getHeaders().put("sec-websocket-key", "x3JJHMbDL1EzLkh9GBhXDw==");
+ session.getHeaders().put("sec-websocket-protocol", "chat, superchat");
+ session.getHeaders().put("sec-websocket-version", "13");
+ return session;
+ }
+
+ private static class DummyWebSocketFactory implements WebSocketFactory {
+ private final WebSocket webSocket;
+
+ private DummyWebSocketFactory(WebSocket webSocket) {
+ super();
+ this.webSocket = webSocket;
+ }
+
+ @Override
+ public WebSocket openWebSocket(IHTTPSession handshake) {
+ return webSocket;
+ }
+ }
+
+ private static class WebSocketAdapter extends WebSocket {
+
+ public WebSocketAdapter(IHTTPSession handshakeRequest) {
+ super(handshakeRequest);
+ }
+
+ @Override
+ protected void onPong(WebSocketFrame pongFrame) {
+ throw new Error("this method should not have been called");
+ }
+
+ @Override
+ protected void onMessage(WebSocketFrame messageFrame) {
+ throw new Error("this method should not have been called");
+ }
+
+ @Override
+ protected void onClose(CloseCode code, String reason,
+ boolean initiatedByRemote) {
+ throw new Error("this method should not have been called");
+ }
+
+ @Override
+ protected void onException(IOException e) {
+ throw new Error("this method should not have been called");
+ }
+
+ }
+}
diff --git a/websocket/src/test/java/fi/iki/elonen/testutil/MockHttpSession.java b/websocket/src/test/java/fi/iki/elonen/testutil/MockHttpSession.java
new file mode 100644
index 0000000..8d82218
--- /dev/null
+++ b/websocket/src/test/java/fi/iki/elonen/testutil/MockHttpSession.java
@@ -0,0 +1,64 @@
+package fi.iki.elonen.testutil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import fi.iki.elonen.NanoHTTPD.CookieHandler;
+import fi.iki.elonen.NanoHTTPD.IHTTPSession;
+import fi.iki.elonen.NanoHTTPD.Method;
+import fi.iki.elonen.NanoHTTPD.ResponseException;
+
+public class MockHttpSession implements IHTTPSession {
+
+ private Map<String, String> params = new HashMap<String, String>();
+ private Map<String, String> headers = new HashMap<String, String>();
+
+ @Override
+ public void execute() throws IOException {
+
+ }
+
+ @Override
+ public Map<String, String> getParms() {
+ return params;
+ }
+
+ @Override
+ public Map<String, String> getHeaders() {
+ return headers;
+ }
+
+ @Override
+ public String getUri() {
+ return null;
+ }
+
+ @Override
+ public String getQueryParameterString() {
+ return null;
+ }
+
+ @Override
+ public Method getMethod() {
+ return null;
+ }
+
+ @Override
+ public InputStream getInputStream() {
+ return null;
+ }
+
+ @Override
+ public CookieHandler getCookies() {
+ return null;
+ }
+
+ @Override
+ public void parseBody(Map<String, String> files) throws IOException,
+ ResponseException {
+
+ }
+
+}