You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2015/04/10 15:51:53 UTC
[6/6] wicket git commit: WICKET-5860 Cross-Site Websocket Hijacking
protection
WICKET-5860 Cross-Site Websocket Hijacking protection
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/4f7c7b35
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/4f7c7b35
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/4f7c7b35
Branch: refs/heads/master
Commit: 4f7c7b351b89fad5c49b8e71ab5489ac5f2c1a29
Parents: f6ddba3
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Fri Apr 10 16:44:45 2015 +0300
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Fri Apr 10 16:51:35 2015 +0300
----------------------------------------------------------------------
.../wicket/protocol/ws/WebSocketSettings.java | 110 +++------
.../ws/api/AbstractWebSocketProcessor.java | 56 +++--
.../protocol/ws/api/ConnectionRejected.java | 48 ++++
.../ws/api/ConnectionRejectedException.java | 38 ---
.../protocol/ws/api/FilterCollection.java | 80 -------
.../ws/api/IWebSocketConnectionFilter.java | 4 +-
.../protocol/ws/api/ServletRequestCopy.java | 34 ++-
.../protocol/ws/api/WebSocketBehavior.java | 14 +-
.../WebSocketConnectionFilterCollection.java | 24 +-
.../ws/api/WebSocketConnectionOriginFilter.java | 138 +++++++----
.../protocol/ws/api/WebSocketResource.java | 12 +-
.../ws/api/event/WebSocketAbortedPayload.java | 23 +-
.../protocol/ws/api/message/AbortedMessage.java | 40 +---
.../ws/api/message/AbstractClientMessage.java | 54 +++++
.../protocol/ws/api/message/ClosedMessage.java | 26 +-
.../ws/api/message/ConnectedMessage.java | 26 +-
.../ws/util/tester/TestWebSocketProcessor.java | 26 +-
.../ws/util/tester/TestWebSocketResource.java | 10 +-
.../tester/WebSocketTesterBehaviorTest.java | 2 +-
.../tester/WebSocketTesterProcessorTest.java | 235 ++++++++++---------
20 files changed, 480 insertions(+), 520 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java
index 5a13374..87bde1c 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/WebSocketSettings.java
@@ -16,15 +16,14 @@
*/
package org.apache.wicket.protocol.ws;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
import java.util.concurrent.Callable;
import org.apache.wicket.Application;
import org.apache.wicket.MetaDataKey;
import org.apache.wicket.Page;
import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
+import org.apache.wicket.protocol.ws.api.IWebSocketConnectionFilter;
+import org.apache.wicket.protocol.ws.api.WebSocketConnectionFilterCollection;
import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
import org.apache.wicket.protocol.ws.api.WebSocketResponse;
import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
@@ -45,7 +44,7 @@ public class WebSocketSettings
};
/**
- * Holds this IWebSocketSettings in the Application's metadata.
+ * Holds this WebSocketSettings in the Application's metadata.
* This way wicket-core module doesn't have reference to wicket-native-websocket.
*/
public static final class Holder
@@ -90,14 +89,9 @@ public class WebSocketSettings
private IWebSocketConnectionRegistry connectionRegistry = new SimpleWebSocketConnectionRegistry();
/**
- * The whitelist of allowed domains where the client can connect to the application from
+ * A filter that may reject an incoming connection
*/
- private final List<String> allowedDomains = new ArrayList<String>();
-
- /**
- * Flag which indicates whether connection filtering should be active or not
- */
- private boolean protectionNeeded = false;
+ private IWebSocketConnectionFilter connectionFilter;
/**
* Set the executor for processing websocket push messages broadcasted to all sessions.
@@ -115,16 +109,28 @@ public class WebSocketSettings
}
/**
- * The executor for processing websocket push messages broadcasted to all sessions.
- *
- * @return
- * The executor used for processing push messages.
+ * @return the executor for processing websocket push messages broadcasted to all sessions.
+ */
+ public Executor getWebSocketPushMessageExecutor()
+ {
+ return webSocketPushMessageExecutor;
+ }
+
+ /**
+ * @return The registry that tracks all currently connected WebSocket clients
*/
public IWebSocketConnectionRegistry getConnectionRegistry()
{
return connectionRegistry;
}
+ /**
+ * Sets the connection registry
+ *
+ * @param connectionRegistry
+ * The registry that tracks all currently connected WebSocket clients
+ * @return {@code this}, for method chaining
+ */
public WebSocketSettings setConnectionRegistry(IWebSocketConnectionRegistry connectionRegistry)
{
Args.notNull(connectionRegistry, "connectionRegistry");
@@ -132,11 +138,6 @@ public class WebSocketSettings
return this;
}
- public Executor getWebSocketPushMessageExecutor()
- {
- return webSocketPushMessageExecutor;
- }
-
/**
* The executor that broadcasts the {@link org.apache.wicket.protocol.ws.api.event.WebSocketPayload}
* via Wicket's event bus.
@@ -165,60 +166,27 @@ public class WebSocketSettings
*/
public Executor getSendPayloadExecutor()
{
- return sendPayloadExecutor;
+ return sendPayloadExecutor;
}
- /**
- * Flag that controls whether hijacking protection should be turned on or not
- *
- * @param protectionNeeded
- * True if protection needed
- */
- public void setHijackingProtectionEnabled(boolean protectionNeeded) {
- this.protectionNeeded = protectionNeeded;
- }
-
- /**
- * Flag that shows whether hijacking protection is turned on or not
- *
- * @param protectionNeeded
- * True if protection turned on
- */
- public boolean isHijackingProtectionEnabled() {
- return this.protectionNeeded;
- }
-
- /**
- * The list of whitelisted domains which are allowed to initiate a websocket connection. This
- * list will be eventually used by the
- * {@link org.apache.wicket.protocol.ws.api.IWebSocketConnectionFilter} to abort potentially
- * unsafe connections. Example domain names might be:
- *
- * <pre>
- * http://www.example.com
- * http://ww2.example.com
- * </pre>
- *
- * @param domains
- * The collection of domains
- */
- public void setAllowedDomains(Collection<String> domains) {
- this.allowedDomains.clear();
- this.allowedDomains.addAll(domains);
- }
+ /**
+ * Sets the filter for checking the incoming connections
+ * @param connectionFilter
+ * the filter for checking the incoming connections
+ * @see WebSocketConnectionFilterCollection
+ */
+ public void setConnectionFilter(IWebSocketConnectionFilter connectionFilter)
+ {
+ this.connectionFilter = connectionFilter;
+ }
- /**
- * The list of whitelisted domains which are allowed to initiate a websocket connection. This
- * list will be eventually used by the
- * {@link org.apache.wicket.protocol.ws.api.IWebSocketConnectionFilter} to abort potentially
- * unsafe connections
- *
- * @param domains
- * The collection of domains if or an empty list when no domains were added
- */
- public List<String> getAllowedDomains() {
- return this.allowedDomains;
- }
+ /**
+ * @return the filter for checking the incoming connections
+ * @see WebSocketConnectionFilterCollection
+ */
+ public IWebSocketConnectionFilter getConnectionFilter() {
+ return this.connectionFilter;
+ }
/**
* A factory method for the {@link org.apache.wicket.request.http.WebResponse}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
index 5d0e829..7126ee1 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/AbstractWebSocketProcessor.java
@@ -16,8 +16,6 @@
*/
package org.apache.wicket.protocol.ws.api;
-import java.util.Collection;
-
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.Application;
@@ -88,8 +86,8 @@ public abstract class AbstractWebSocketProcessor implements IWebSocketProcessor
private final String sessionId;
private final WebSocketSettings webSocketSettings;
private final IWebSocketConnectionRegistry connectionRegistry;
- private final WebSocketConnectionFilterCollection connectionFilters;
- private final HttpServletRequest servletRequest;
+ private final IWebSocketConnectionFilter connectionFilter;
+ private final HttpServletRequest servletRequest;
/**
* Constructor.
@@ -133,8 +131,7 @@ public abstract class AbstractWebSocketProcessor implements IWebSocketProcessor
this.connectionRegistry = webSocketSettings.getConnectionRegistry();
- this.connectionFilters = new WebSocketConnectionFilterCollection();
- connectionFilters.add(new WebSocketConnectionOriginFilter(webSocketSettings));
+ this.connectionFilter = webSocketSettings.getConnectionFilter();
}
@Override
@@ -150,25 +147,31 @@ public abstract class AbstractWebSocketProcessor implements IWebSocketProcessor
broadcastMessage(binaryMessage);
}
- /**
- * A helper that registers the opened connection in the application-level registry.
- *
- * @param connection
- * the web socket connection to use to communicate with the client
- * @see #onOpen(Object)
- */
- protected final void onConnect(final IWebSocketConnection connection) {
- IKey key = getRegistryKey();
- try {
- connectionRegistry.setConnection(getApplication(), getSessionId(), key, connection);
- connectionFilters.doFilter(servletRequest);
- broadcastMessage(new ConnectedMessage(getApplication(), getSessionId(), key));
- } catch (ConnectionRejectedException e) {
- broadcastMessage(new AbortedMessage(getApplication(), getSessionId(), key));
- connectionRegistry.removeConnection(getApplication(), getSessionId(), key);
- connection.close(e.getCode(), e.getReason());
- }
- }
+ /**
+ * A helper that registers the opened connection in the application-level registry.
+ *
+ * @param connection
+ * the web socket connection to use to communicate with the client
+ * @see #onOpen(Object)
+ */
+ protected final void onConnect(final IWebSocketConnection connection) {
+ IKey key = getRegistryKey();
+ connectionRegistry.setConnection(getApplication(), getSessionId(), key, connection);
+
+ if (connectionFilter != null)
+ {
+ ConnectionRejected connectionRejected = connectionFilter.doFilter(servletRequest);
+ if (connectionRejected != null)
+ {
+ broadcastMessage(new AbortedMessage(getApplication(), getSessionId(), key));
+ connectionRegistry.removeConnection(getApplication(), getSessionId(), key);
+ connection.close(connectionRejected.getCode(), connectionRejected.getReason());
+ return;
+ }
+ }
+
+ broadcastMessage(new ConnectedMessage(getApplication(), getSessionId(), key));
+ }
@Override
public void onClose(int closeCode, String message)
@@ -332,7 +335,8 @@ public abstract class AbstractWebSocketProcessor implements IWebSocketProcessor
{
payload = new WebSocketClosedPayload((ClosedMessage) message, handler);
}
- else if (message instanceof AbortedMessage) {
+ else if (message instanceof AbortedMessage)
+ {
payload = new WebSocketAbortedPayload((AbortedMessage) message, handler);
}
else if (message instanceof IWebSocketPushMessage)
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ConnectionRejected.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ConnectionRejected.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ConnectionRejected.java
new file mode 100644
index 0000000..90af93d
--- /dev/null
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ConnectionRejected.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.protocol.ws.api;
+
+/**
+ * A class used by {@link IWebSocketConnectionFilter}s when they need to reject a connection
+ */
+public class ConnectionRejected
+{
+ private final int code;
+ private final String reason;
+
+ /**
+ * Constructor
+ *
+ * @param code
+ * The error code
+ * @param reason
+ * The reason to reject the connection
+ */
+ public ConnectionRejected(int code, String reason)
+ {
+ this.code = code;
+ this.reason = reason;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ConnectionRejectedException.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ConnectionRejectedException.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ConnectionRejectedException.java
deleted file mode 100644
index 16834f4..0000000
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ConnectionRejectedException.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.protocol.ws.api;
-
-public class ConnectionRejectedException extends RuntimeException {
-
- private static final long serialVersionUID = 4552012810343573564L;
-
- private final int code;
- private final String reason;
-
- public ConnectionRejectedException(int code, String reason) {
- this.code = code;
- this.reason = reason;
- }
-
- public int getCode() {
- return code;
- }
-
- public String getReason() {
- return reason;
- }
-}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/FilterCollection.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/FilterCollection.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/FilterCollection.java
deleted file mode 100644
index 8b08d89..0000000
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/FilterCollection.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.protocol.ws.api;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Represents a collection of filters. Facilitates invocation of filtering on each filter.
- *
- * @author Gergely Nagy
- *
- * @param <T>
- * type of filters
- */
-public class FilterCollection<T> implements Serializable, Iterable<T> {
-
- private static final long serialVersionUID = -7389583130277632264L;
-
- /** list of listeners */
- private final List<T> filters = new CopyOnWriteArrayList<>();
-
- /**
- * Adds a filter to this set of filters.
- *
- * @param filter
- * The filter to add
- * @return {@code true} if the filter was added
- */
- public boolean add(final T filter)
- {
- if (filter == null)
- {
- return false;
- }
- filters.add(filter);
- return true;
- }
-
- /**
- * Removes a filter from this set.
- *
- * @param filter
- * The filter to remove
- */
- public void remove(final T filter)
- {
- filters.remove(filter);
- }
-
- /**
- * Returns an iterator that can iterate the filter.
- *
- * @return an iterator that can iterate the filters.
- */
- @Override
- public Iterator<T> iterator() {
- return filters.iterator();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/IWebSocketConnectionFilter.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/IWebSocketConnectionFilter.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/IWebSocketConnectionFilter.java
index a43c7c1..afd0f2e 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/IWebSocketConnectionFilter.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/IWebSocketConnectionFilter.java
@@ -23,8 +23,8 @@ import javax.servlet.http.HttpServletRequest;
* One example might be when the connection 'Origin' header does not match the origin of the
* application host
*
+ * @see WebSocketConnectionFilterCollection
* @author Gergely Nagy
- *
*/
public interface IWebSocketConnectionFilter {
@@ -34,5 +34,5 @@ public interface IWebSocketConnectionFilter {
* @param servletRequest
* The servlet request holding the request headers
*/
- public void doFilter(HttpServletRequest servletRequest);
+ ConnectionRejected doFilter(HttpServletRequest servletRequest);
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ServletRequestCopy.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ServletRequestCopy.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ServletRequestCopy.java
index bffc301..218b1f7 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ServletRequestCopy.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/ServletRequestCopy.java
@@ -58,7 +58,7 @@ public class ServletRequestCopy implements HttpServletRequest
private final HttpSessionCopy httpSession;
private final StringBuffer requestURL;
private final Map<String, Object> attributes = new HashMap<>();
- private final Map<String, String> headers = new HashMap<>();
+ private final Map<String, Enumeration<String>> headers = new HashMap<>();
private final Map<String, String[]> parameters = new HashMap<>();
private final String method;
private final String serverName;
@@ -81,7 +81,8 @@ public class ServletRequestCopy implements HttpServletRequest
Enumeration<String> e = request.getHeaderNames();
while (e != null && e.hasMoreElements()) {
s = e.nextElement();
- headers.put(s, request.getHeader(s));
+ Enumeration<String> headerValues = request.getHeaders(s);
+ this.headers.put(s, headerValues);
}
e = request.getAttributeNames();
@@ -154,27 +155,20 @@ public class ServletRequestCopy implements HttpServletRequest
}
@Override
- public String getHeader(String name) {
- return headers.get(name);
+ public String getHeader(String name)
+ {
+ Enumeration<String> values = headers.get(name);
+ if (values != null && values.hasMoreElements())
+ {
+ return values.nextElement();
+ }
+ return null;
}
@Override
- public Enumeration<String> getHeaders(final String name) {
- return new Enumeration<String>() {
-
- boolean hasNext = true;
-
- @Override
- public boolean hasMoreElements() {
- return hasNext && headers.get(name) != null;
- }
-
- @Override
- public String nextElement() {
- hasNext = false;
- return headers.get(name);
- }
- };
+ public Enumeration<String> getHeaders(final String name)
+ {
+ return headers.get(name);
}
@Override
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java
index 803246d..50cb5f0 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketBehavior.java
@@ -79,12 +79,12 @@ public abstract class WebSocketBehavior extends BaseWebSocketBehavior
ClosedMessage message = closedPayload.getMessage();
onClose(message);
}
- else if (wsPayload instanceof WebSocketAbortedPayload)
- {
- WebSocketAbortedPayload abortedPayload = (WebSocketAbortedPayload) wsPayload;
- AbortedMessage message = abortedPayload.getMessage();
- onAbort(message);
- }
+ else if (wsPayload instanceof WebSocketAbortedPayload)
+ {
+ WebSocketAbortedPayload abortedPayload = (WebSocketAbortedPayload) wsPayload;
+ AbortedMessage message = abortedPayload.getMessage();
+ onAbort(message);
+ }
else if (wsPayload instanceof WebSocketPushPayload)
{
WebSocketPushPayload pushPayload = (WebSocketPushPayload) wsPayload;
@@ -133,7 +133,7 @@ public abstract class WebSocketBehavior extends BaseWebSocketBehavior
* A callback method called when the server has aborted the connection
*
* @param message
- * the aborted message with the info about the server
+ * the aborted message with the info about the client
*/
protected void onAbort(AbortedMessage message) {
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionFilterCollection.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionFilterCollection.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionFilterCollection.java
index 63a9bc6..4257edd 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionFilterCollection.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionFilterCollection.java
@@ -16,19 +16,27 @@
*/
package org.apache.wicket.protocol.ws.api;
-import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
-public class WebSocketConnectionFilterCollection extends
- FilterCollection<IWebSocketConnectionFilter> implements
- IWebSocketConnectionFilter {
+import javax.servlet.http.HttpServletRequest;
- private static final long serialVersionUID = 3953951891780895469L;
+public class WebSocketConnectionFilterCollection extends ArrayList<IWebSocketConnectionFilter>
+ implements IWebSocketConnectionFilter
+{
+ private static final long serialVersionUID = 1L;
@Override
- public void doFilter(HttpServletRequest servletRequest) {
- for (IWebSocketConnectionFilter filter : this) {
- filter.doFilter(servletRequest);
+ public ConnectionRejected doFilter(final HttpServletRequest servletRequest)
+ {
+ for (IWebSocketConnectionFilter filter : this)
+ {
+ ConnectionRejected connectionRejected = filter.doFilter(servletRequest);
+ if (connectionRejected != null)
+ {
+ return connectionRejected;
+ }
}
+ return null;
}
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionOriginFilter.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionOriginFilter.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionOriginFilter.java
index bc08c98..fdf0ef2 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionOriginFilter.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketConnectionOriginFilter.java
@@ -16,13 +16,14 @@
*/
package org.apache.wicket.protocol.ws.api;
-import java.util.ArrayList;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
-import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.util.lang.Args;
+import org.apache.wicket.util.string.Strings;
/**
* This filter will reject those requests which contain 'Origin' header that does not match the origin of the
@@ -32,57 +33,104 @@ import org.apache.wicket.protocol.ws.WebSocketSettings;
* @see <a href="http://www.christian-schneider.net/CrossSiteWebSocketHijacking.html">http://www.christian-schneider.net/CrossSiteWebSocketHijacking.html</a>
*
* @author Gergely Nagy
- *
*/
-public class WebSocketConnectionOriginFilter implements IWebSocketConnectionFilter {
+public class WebSocketConnectionOriginFilter implements IWebSocketConnectionFilter
+{
+
+ /**
+ * Error code 1008 indicates that an endpoint is terminating the connection because it has received a message that
+ * violates its policy. This is a generic status code that can be returned when there is no other more suitable
+ * status code (e.g., 1003 or 1009) or if there is a need to hide specific details about the policy.
+ * <p>
+ * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
+ */
+ public static final int POLICY_VIOLATION_ERROR_CODE = 1008;
+
+ /**
+ * Explanatory text for the client to explain why the connection is getting aborted
+ */
+ public static final String ORIGIN_MISMATCH = "Origin mismatch";
- /**
- * 1008 indicates that an endpoint is terminating the connection because it has received a message that violates its policy. This is a generic status code
- * that can be returned when there is no other more suitable status code (e.g., 1003 or 1009) or if there is a need to hide specific details about the
- * policy.
- * <p>
- * See <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455, Section 7.4.1 Defined Status Codes</a>.
- */
- public static final int POLICY_VIOLATION = 1008;
+ private final List<String> allowedDomains;
- /**
- * Explanatory text for the client to explain why the connection is getting aborted
- */
- public static final String ORIGIN_MISMATCH = "Origin mismatch";
+ public WebSocketConnectionOriginFilter(final List<String> allowedDomains)
+ {
+ this.allowedDomains = Args.notNull(allowedDomains, "allowedDomains");
+ }
- private final WebSocketSettings webSocketSettings;
+ @Override
+ public ConnectionRejected doFilter(HttpServletRequest servletRequest)
+ {
+ if (allowedDomains != null && !allowedDomains.isEmpty())
+ {
+ String oUrl = getOriginUrl(servletRequest);
+ if (invalid(oUrl, allowedDomains))
+ {
+ return new ConnectionRejected(POLICY_VIOLATION_ERROR_CODE, ORIGIN_MISMATCH);
+ }
+ }
- public WebSocketConnectionOriginFilter(WebSocketSettings webSocketSettings) {
- this.webSocketSettings = webSocketSettings;
- }
+ return null;
+ }
- @Override
- public void doFilter(HttpServletRequest servletRequest) {
- if (webSocketSettings.isHijackingProtectionEnabled()) {
- String oUrl = getOriginUrl(servletRequest);
- if (invalid(oUrl))
- throw new ConnectionRejectedException(POLICY_VIOLATION, ORIGIN_MISMATCH);
- }
- }
+ /**
+ * The list of whitelisted domains which are allowed to initiate a websocket connection. This
+ * list will be eventually used by the
+ * {@link org.apache.wicket.protocol.ws.api.IWebSocketConnectionFilter} to abort potentially
+ * unsafe connections. Example domain names might be:
+ *
+ * <pre>
+ * http://www.example.com
+ * http://ww2.example.com
+ * </pre>
+ *
+ * @param domains
+ * The collection of domains
+ */
+ public void setAllowedDomains(Iterable<String> domains) {
+ this.allowedDomains.clear();
+ if (domains != null)
+ {
+ for (String domain : domains)
+ {
+ this.allowedDomains.add(domain);
+ }
+ }
+ }
- private boolean invalid(String oUrl) {
- if (originMismatch(oUrl))
- return true;
- if (oUrl == null || "".equals(oUrl))
- return true;
- return false;
- }
+ /**
+ * The list of whitelisted domains which are allowed to initiate a websocket connection. This
+ * list will be eventually used by the
+ * {@link org.apache.wicket.protocol.ws.api.IWebSocketConnectionFilter} to abort potentially
+ * unsafe connections
+ */
+ public List<String> getAllowedDomains()
+ {
+ return allowedDomains;
+ }
- private boolean originMismatch(String oUrl) {
- List<String> allowedDomains = webSocketSettings.getAllowedDomains();
- return !allowedDomains.contains(oUrl);
- }
+ private boolean invalid(String oUrl, List<String> allowedDomains)
+ {
+ return Strings.isEmpty(oUrl) || !allowedDomains.contains(oUrl);
+ }
- private String getOriginUrl(HttpServletRequest servletRequest) {
- ArrayList<String> origins = Collections.list(servletRequest.getHeaders("Origin"));
- if (origins.size() != 1)
- return null;
- return origins.get(0);
- }
+ private String getOriginUrl(final HttpServletRequest servletRequest)
+ {
+ Enumeration<String> originHeaderValues = servletRequest.getHeaders("Origin");
+ List<String> origins;
+ if (originHeaderValues != null)
+ {
+ origins = Collections.list(originHeaderValues);
+ }
+ else
+ {
+ origins = Collections.emptyList();
+ }
+ if (origins.size() != 1)
+ {
+ return null;
+ }
+ return origins.get(0);
+ }
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketResource.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketResource.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketResource.java
index 95aed1d..a49fc2b 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketResource.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/WebSocketResource.java
@@ -64,12 +64,12 @@ public abstract class WebSocketResource implements IResource
ClosedMessage message = connectedPayload.getMessage();
onClose(message);
}
- else if (payload instanceof WebSocketAbortedPayload)
- {
- WebSocketAbortedPayload abortedPayload = (WebSocketAbortedPayload) payload;
- AbortedMessage message = abortedPayload.getMessage();
- onAbort(message);
- }
+ else if (payload instanceof WebSocketAbortedPayload)
+ {
+ WebSocketAbortedPayload abortedPayload = (WebSocketAbortedPayload) payload;
+ AbortedMessage message = abortedPayload.getMessage();
+ onAbort(message);
+ }
else if (payload instanceof WebSocketPushPayload)
{
WebSocketPushPayload pushPayload = (WebSocketPushPayload) payload;
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/event/WebSocketAbortedPayload.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/event/WebSocketAbortedPayload.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/event/WebSocketAbortedPayload.java
index f19aa95..399b959 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/event/WebSocketAbortedPayload.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/event/WebSocketAbortedPayload.java
@@ -24,19 +24,18 @@ import org.apache.wicket.protocol.ws.api.message.AbortedMessage;
*
* @since 7.0.0-M5
*/
-public class WebSocketAbortedPayload extends WebSocketPayload<AbortedMessage> {
+public class WebSocketAbortedPayload extends WebSocketPayload<AbortedMessage>
+{
+ private final AbortedMessage message;
- private final AbortedMessage message;
+ public WebSocketAbortedPayload(AbortedMessage message, WebSocketRequestHandler handler) {
+ super(handler);
- public WebSocketAbortedPayload(AbortedMessage message, WebSocketRequestHandler handler) {
- super(handler);
-
- this.message = message;
- }
-
- @Override
- public AbortedMessage getMessage() {
- return message;
- }
+ this.message = message;
+ }
+ @Override
+ public AbortedMessage getMessage() {
+ return message;
+ }
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/AbortedMessage.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/AbortedMessage.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/AbortedMessage.java
index 2040554..61cc13e 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/AbortedMessage.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/AbortedMessage.java
@@ -18,39 +18,21 @@ package org.apache.wicket.protocol.ws.api.message;
import org.apache.wicket.Application;
import org.apache.wicket.protocol.ws.api.registry.IKey;
-import org.apache.wicket.util.lang.Args;
/**
* A {@link IWebSocketMessage message} sent when the web socket connection is aborted.
*
* @since 7.0.0-M5
*/
-public class AbortedMessage implements IWebSocketMessage {
-
- private final Application application;
- private final String sessionId;
- private final IKey key;
-
- public AbortedMessage(Application application, String sessionId, IKey key) {
- this.application = Args.notNull(application, "application");
- this.sessionId = Args.notNull(sessionId, "sessionId");
- this.key = Args.notNull(key, "key");
- }
-
- public Application getApplication() {
- return application;
- }
-
- public String getSessionId() {
- return sessionId;
- }
-
- public IKey getKey() {
- return key;
- }
-
- @Override
- public final String toString() {
- return "The server aborted the client connection";
- }
+public class AbortedMessage extends AbstractClientMessage
+{
+ public AbortedMessage(Application application, String sessionId, IKey key)
+ {
+ super(application, sessionId, key);
+ }
+
+ @Override
+ public final String toString() {
+ return "The server aborted the client connection";
+ }
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/AbstractClientMessage.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/AbstractClientMessage.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/AbstractClientMessage.java
new file mode 100644
index 0000000..7e3234c
--- /dev/null
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/AbstractClientMessage.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.protocol.ws.api.message;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.protocol.ws.api.registry.IKey;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * A base message for all messages with information about the client
+ */
+public abstract class AbstractClientMessage implements IWebSocketMessage
+{
+ private final Application application;
+ private final String sessionId;
+ private final IKey key;
+
+ public AbstractClientMessage(Application application, String sessionId, IKey key)
+ {
+ this.application = Args.notNull(application, "application");
+ this.sessionId = Args.notNull(sessionId, "sessionId");
+ this.key = Args.notNull(key, "key");
+ }
+
+ public Application getApplication()
+ {
+ return application;
+ }
+
+ public String getSessionId()
+ {
+ return sessionId;
+ }
+
+ public IKey getKey()
+ {
+ return key;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ClosedMessage.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ClosedMessage.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ClosedMessage.java
index 43046c0..9dad746 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ClosedMessage.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ClosedMessage.java
@@ -18,7 +18,6 @@ package org.apache.wicket.protocol.ws.api.message;
import org.apache.wicket.Application;
import org.apache.wicket.protocol.ws.api.registry.IKey;
-import org.apache.wicket.util.lang.Args;
/**
* A {@link IWebSocketMessage message} sent when the web socket connection
@@ -26,32 +25,11 @@ import org.apache.wicket.util.lang.Args;
*
* @since 6.0
*/
-public class ClosedMessage implements IWebSocketMessage
+public class ClosedMessage extends AbstractClientMessage
{
- private final Application application;
- private final String sessionId;
- private final IKey key;
-
public ClosedMessage(Application application, String sessionId, IKey key)
{
- this.application = Args.notNull(application, "application");
- this.sessionId = Args.notNull(sessionId, "sessionId");
- this.key = Args.notNull(key, "key");
- }
-
- public Application getApplication()
- {
- return application;
- }
-
- public String getSessionId()
- {
- return sessionId;
- }
-
- public IKey getKey()
- {
- return key;
+ super(application, sessionId, key);
}
@Override
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ConnectedMessage.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ConnectedMessage.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ConnectedMessage.java
index ab085ce..8e0485f 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ConnectedMessage.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/api/message/ConnectedMessage.java
@@ -18,7 +18,6 @@ package org.apache.wicket.protocol.ws.api.message;
import org.apache.wicket.Application;
import org.apache.wicket.protocol.ws.api.registry.IKey;
-import org.apache.wicket.util.lang.Args;
/**
* A {@link IWebSocketMessage message} when a client creates web socket
@@ -26,32 +25,11 @@ import org.apache.wicket.util.lang.Args;
*
* @since 6.0
*/
-public class ConnectedMessage implements IWebSocketMessage
+public class ConnectedMessage extends AbstractClientMessage
{
- private final Application application;
- private final String sessionId;
- private final IKey key;
-
public ConnectedMessage(Application application, String sessionId, IKey key)
{
- this.application = Args.notNull(application, "application");
- this.sessionId = Args.notNull(sessionId, "sessionId");
- this.key = Args.notNull(key, "key");
- }
-
- public Application getApplication()
- {
- return application;
- }
-
- public String getSessionId()
- {
- return sessionId;
- }
-
- public IKey getKey()
- {
- return key;
+ super(application, sessionId, key);
}
@Override
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketProcessor.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketProcessor.java b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketProcessor.java
index 1ae8789..f7b55e1 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketProcessor.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/main/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketProcessor.java
@@ -36,19 +36,19 @@ import org.apache.wicket.util.tester.WicketTester;
*/
abstract class TestWebSocketProcessor extends AbstractWebSocketProcessor
{
- /**
- *
- * Constructor.
- *
- * @param request
- * the http request that was used to create the TomcatWebSocketProcessor
- * @param application
- * the current Wicket Application
- */
- public TestWebSocketProcessor(final HttpServletRequest request, final WebApplication application)
- {
- super(request, application);
- }
+ /**
+ *
+ * Constructor.
+ *
+ * @param request
+ * the http request that was used to create the IWebSocketProcessor
+ * @param application
+ * the current Wicket Application
+ */
+ public TestWebSocketProcessor(final HttpServletRequest request, final WebApplication application)
+ {
+ super(request, application);
+ }
/**
* Constructor.
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketResource.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketResource.java b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketResource.java
index 942889d..276c566 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketResource.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/TestWebSocketResource.java
@@ -78,11 +78,11 @@ public class TestWebSocketResource extends WebSocketResource
super.onClose(message);
}
- @Override
- protected void onAbort(AbortedMessage message) {
- ON_ABORT_CALLED.set(true);
- super.onAbort(message);
- }
+ @Override
+ protected void onAbort(AbortedMessage message) {
+ ON_ABORT_CALLED.set(true);
+ super.onAbort(message);
+ }
@Override
protected void onMessage(WebSocketRequestHandler handler, TextMessage message)
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterBehaviorTest.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterBehaviorTest.java b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterBehaviorTest.java
index c6516cb..241047e 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterBehaviorTest.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterBehaviorTest.java
@@ -137,7 +137,7 @@ public class WebSocketTesterBehaviorTest extends Assert
webSocketTester.broadcast(tester.getApplication(), tester.getHttpSession().getId(),
new PageIdKey(page.getPageId()), broadcastMessage);
- assertEquals(true, messageReceived.get());
+ assertTrue(messageReceived.get());
webSocketTester.destroy();
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/4f7c7b35/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterProcessorTest.java
----------------------------------------------------------------------
diff --git a/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterProcessorTest.java b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterProcessorTest.java
index cf9fa80..5956299 100644
--- a/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterProcessorTest.java
+++ b/wicket-native-websocket/wicket-native-websocket-core/src/test/java/org/apache/wicket/protocol/ws/util/tester/WebSocketTesterProcessorTest.java
@@ -25,119 +25,136 @@ import org.apache.wicket.mock.MockApplication;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.protocol.http.mock.MockHttpServletRequest;
import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.WebSocketConnectionOriginFilter;
import org.apache.wicket.request.http.WebRequest;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
-public class WebSocketTesterProcessorTest extends Assert {
-
- final static AtomicBoolean messageReceived = new AtomicBoolean(false);
-
- private static class TestProcessor extends TestWebSocketProcessor {
- private TestProcessor(HttpServletRequest request, WebApplication application) {
- super(request, application);
- }
-
- @Override
- protected void onOutMessage(String message) {
- messageReceived.set(true);
- }
-
- @Override
- protected void onOutMessage(byte[] message, int offset, int length) {
- messageReceived.set(true);
- }
- }
-
- WicketTester tester;
- WebApplication application = new MockApplication() {
- @Override
- protected void init() {
- super.init();
-
- getSharedResources().add(TestWebSocketResource.TEXT, new TestWebSocketResource("expected"));
- }
- };
-
- @Before
- public void before() {
- tester = new WicketTester(application);
- application.getWicketFilter().setFilterPath("");
- }
-
- @After
- public void after() {
- tester.destroy();
- TestWebSocketResource.ON_ABORT_CALLED.set(false);
- }
-
- @Test
- public void onConnectNoOrigin() throws Exception {
- // Given header 'Origin' is missing
- configureRequest(true, new String[] { "http://www.example.com" }, new String[] {});
-
- // When we open a connection
- TestWebSocketProcessor processor = new TestProcessor(tester.getRequest(), tester.getApplication());
- processor.onOpen(new Object());
-
- // Then it fails
- assertEquals(true, TestWebSocketResource.ON_ABORT_CALLED.get());
- }
-
- @Ignore
- @Test
- public void onConnectMultipleOrigins() throws Exception {
- // Given the request contains multiple header 'Origin's
- configureRequest(true, new String[] { "http://www.example.com" }, new String[] { "http://www.example.com", "http://ww2.example.com" });
-
- // When we open a connection
- TestWebSocketProcessor processor = new TestProcessor(tester.getRequest(), tester.getApplication());
- processor.onOpen(new Object());
-
- // Then it fails
- assertEquals(true, TestWebSocketResource.ON_ABORT_CALLED.get());
- }
-
- @Test
- public void onConnectMatchingOrigin() throws Exception {
- // Given header 'Origin' matches the host origin
- configureRequest(true, new String[] { "http://www.example.com" }, new String[] { "http://www.example.com" });
-
- // When we open a connection
- TestWebSocketProcessor processor = new TestProcessor(tester.getRequest(), tester.getApplication());
- processor.onOpen(new Object());
-
- // Then it succeeds
- assertEquals(false, TestWebSocketResource.ON_ABORT_CALLED.get());
- }
-
- @Test
- public void onConnectMismatchingOrigin() throws Exception {
- // Given header 'Origin' does not match the host origin
- configureRequest(true, new String[] { "http://www.example.com" }, new String[] { "http://ww2.example.com" });
-
- // When we open a connection
- TestWebSocketProcessor processor = new TestProcessor(tester.getRequest(), tester.getApplication());
- processor.onOpen(new Object());
-
- // Then it fails
- assertEquals(true, TestWebSocketResource.ON_ABORT_CALLED.get());
- }
-
- protected void configureRequest(boolean protectionNeeded, String[] allowedDomains, String[] origins) {
- WebSocketSettings webSocketSettings = WebSocketSettings.Holder.get(application);
- webSocketSettings.setHijackingProtectionEnabled(protectionNeeded);
- webSocketSettings.setAllowedDomains(Arrays.asList(allowedDomains));
- MockHttpServletRequest request = tester.getRequest();
- for (String origin : origins) {
- request.addHeader("Origin", origin);
- }
- request.addParameter("resourceName", TestWebSocketResource.TEXT);
- request.addParameter(WebRequest.PARAM_AJAX_BASE_URL, ".");
- }
-
-}
\ No newline at end of file
+/**
+ * Tests for https://issues.apache.org/jira/browse/WICKET-5860
+ */
+public class WebSocketTesterProcessorTest extends Assert
+{
+ final static AtomicBoolean messageReceived = new AtomicBoolean(false);
+
+ private static class TestProcessor extends TestWebSocketProcessor
+ {
+ private TestProcessor(HttpServletRequest request, WebApplication application)
+ {
+ super(request, application);
+ }
+
+ @Override
+ protected void onOutMessage(String message)
+ {
+ messageReceived.set(true);
+ }
+
+ @Override
+ protected void onOutMessage(byte[] message, int offset, int length)
+ {
+ messageReceived.set(true);
+ }
+ }
+
+ WicketTester tester;
+ WebApplication application = new MockApplication()
+ {
+ @Override
+ protected void init()
+ {
+ super.init();
+
+ getSharedResources().add(TestWebSocketResource.TEXT, new TestWebSocketResource("expected"));
+ }
+ };
+
+ @Before
+ public void before()
+ {
+ tester = new WicketTester(application);
+ application.getWicketFilter().setFilterPath("");
+ }
+
+ @After
+ public void after()
+ {
+ tester.destroy();
+ TestWebSocketResource.ON_ABORT_CALLED.set(false);
+ }
+
+ @Test
+ public void onConnectNoOrigin()
+ {
+ // Given header 'Origin' is missing
+ configureRequest(new String[] { "http://www.example.com" }, new String[] {});
+
+ // When we open a connection
+ TestWebSocketProcessor processor = new TestProcessor(tester.getRequest(), tester.getApplication());
+ processor.onOpen(new Object());
+
+ // Then it fails
+ assertTrue(TestWebSocketResource.ON_ABORT_CALLED.get());
+ }
+
+// @Ignore
+ @Test
+ public void onConnectMultipleOrigins()
+ {
+ // Given the request contains multiple header 'Origin's
+ configureRequest(new String[] { "http://www.example.com" }, new String[] { "http://www.example.com", "http://ww2.example.com" });
+
+ // When we open a connection
+ TestWebSocketProcessor processor = new TestProcessor(tester.getRequest(), tester.getApplication());
+ processor.onOpen(new Object());
+
+ // Then it fails
+ assertTrue(TestWebSocketResource.ON_ABORT_CALLED.get());
+ }
+
+ @Test
+ public void onConnectMatchingOrigin()
+ {
+ // Given header 'Origin' matches the host origin
+ configureRequest(new String[] { "http://www.example.com" }, new String[] { "http://www.example.com" });
+
+ // When we open a connection
+ TestWebSocketProcessor processor = new TestProcessor(tester.getRequest(), tester.getApplication());
+ processor.onOpen(new Object());
+
+ // Then it succeeds
+ assertFalse(TestWebSocketResource.ON_ABORT_CALLED.get());
+ }
+
+ @Test
+ public void onConnectMismatchingOrigin()
+ {
+ // Given header 'Origin' does not match the host origin
+ configureRequest(new String[] { "http://www.example.com" }, new String[] { "http://ww2.example.com" });
+
+ // When we open a connection
+ TestWebSocketProcessor processor = new TestProcessor(tester.getRequest(), tester.getApplication());
+ processor.onOpen(new Object());
+
+ // Then it fails
+ assertTrue(TestWebSocketResource.ON_ABORT_CALLED.get());
+ }
+
+ protected void configureRequest(String[] allowedDomains, String[] origins)
+ {
+ WebSocketSettings webSocketSettings = WebSocketSettings.Holder.get(application);
+ WebSocketConnectionOriginFilter connectionFilter = new WebSocketConnectionOriginFilter(Arrays.asList(allowedDomains));
+ webSocketSettings.setConnectionFilter(connectionFilter);
+ MockHttpServletRequest request = tester.getRequest();
+ for (String origin : origins)
+ {
+ request.addHeader("Origin", origin);
+ }
+ request.addParameter("resourceName", TestWebSocketResource.TEXT);
+ request.addParameter(WebRequest.PARAM_AJAX_BASE_URL, ".");
+ }
+
+}