410175 - WebSocketSession#isSecure() doesn't return true for SSL session on the server side
+ Fixing server side support for Session.isSecure() + Standardizing the WSURI translation into new org.eclipse.jetty.websocket.api.util.WSURI class + Adding testcase for SSL on server side
This commit is contained in:
parent
9abed8e85d
commit
e61c161ebd
|
@ -42,6 +42,7 @@ public class UpgradeRequest
|
||||||
private String httpVersion;
|
private String httpVersion;
|
||||||
private String method;
|
private String method;
|
||||||
private String host;
|
private String host;
|
||||||
|
private boolean secure = false;
|
||||||
|
|
||||||
protected UpgradeRequest()
|
protected UpgradeRequest()
|
||||||
{
|
{
|
||||||
|
@ -225,6 +226,11 @@ public class UpgradeRequest
|
||||||
return test.equalsIgnoreCase(getOrigin());
|
return test.equalsIgnoreCase(getOrigin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSecure()
|
||||||
|
{
|
||||||
|
return secure;
|
||||||
|
}
|
||||||
|
|
||||||
public void setCookies(List<HttpCookie> cookies)
|
public void setCookies(List<HttpCookie> cookies)
|
||||||
{
|
{
|
||||||
this.cookies = cookies;
|
this.cookies = cookies;
|
||||||
|
@ -261,6 +267,19 @@ public class UpgradeRequest
|
||||||
public void setRequestURI(URI uri)
|
public void setRequestURI(URI uri)
|
||||||
{
|
{
|
||||||
this.requestURI = uri;
|
this.requestURI = uri;
|
||||||
|
String scheme = uri.getScheme();
|
||||||
|
if ("ws".equalsIgnoreCase(scheme))
|
||||||
|
{
|
||||||
|
secure = false;
|
||||||
|
}
|
||||||
|
else if ("wss".equalsIgnoreCase(scheme))
|
||||||
|
{
|
||||||
|
secure = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("URI scheme must be 'ws' or 'wss'");
|
||||||
|
}
|
||||||
this.host = this.requestURI.getHost();
|
this.host = this.requestURI.getHost();
|
||||||
this.parameters.clear();
|
this.parameters.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.eclipse.jetty.websocket.api.util;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for converting a {@link URI} between a HTTP(S) and WS(S) URI.
|
||||||
|
*/
|
||||||
|
public final class WSURI
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Convert to HTTP <code>http</code> or <code>https</code> scheme URIs.
|
||||||
|
* <p>
|
||||||
|
* Converting <code>ws</code> and <code>wss</code> URIs to their HTTP equivalent
|
||||||
|
*
|
||||||
|
* @param inputUri
|
||||||
|
* the input URI
|
||||||
|
* @return the HTTP scheme URI for the input URI.
|
||||||
|
* @throws URISyntaxException
|
||||||
|
* if unable to convert the input URI
|
||||||
|
*/
|
||||||
|
public static URI toHttp(final URI inputUri) throws URISyntaxException
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(inputUri,"Input URI must not be null");
|
||||||
|
String wsScheme = inputUri.getScheme();
|
||||||
|
String httpScheme = null;
|
||||||
|
if ("http".equalsIgnoreCase(wsScheme) || "https".equalsIgnoreCase(wsScheme))
|
||||||
|
{
|
||||||
|
// leave alone
|
||||||
|
httpScheme = wsScheme;
|
||||||
|
}
|
||||||
|
else if ("ws".equalsIgnoreCase(wsScheme))
|
||||||
|
{
|
||||||
|
// convert to http
|
||||||
|
httpScheme = "http";
|
||||||
|
}
|
||||||
|
else if ("wss".equalsIgnoreCase(wsScheme))
|
||||||
|
{
|
||||||
|
// convert to https
|
||||||
|
httpScheme = "https";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new URISyntaxException(inputUri.toString(),"Unrecognized WebSocket scheme");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new URI(httpScheme,inputUri.getUserInfo(),inputUri.getHost(),inputUri.getPort(),inputUri.getPath(),inputUri.getQuery(),inputUri.getFragment());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to WebSocket <code>ws</code> or <code>wss</code> scheme URIs
|
||||||
|
* <p>
|
||||||
|
* Converting <code>http</code> and <code>https</code> URIs to their WebSocket equivalent
|
||||||
|
*
|
||||||
|
* @param inputUrl
|
||||||
|
* the input URI
|
||||||
|
* @return the WebSocket scheme URI for the input URI.
|
||||||
|
* @throws URISyntaxException
|
||||||
|
* if unable to convert the input URI
|
||||||
|
*/
|
||||||
|
public static URI toWebsocket(CharSequence inputUrl) throws URISyntaxException
|
||||||
|
{
|
||||||
|
return toWebsocket(new URI(inputUrl.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to WebSocket <code>ws</code> or <code>wss</code> scheme URIs
|
||||||
|
* <p>
|
||||||
|
* Converting <code>http</code> and <code>https</code> URIs to their WebSocket equivalent
|
||||||
|
*
|
||||||
|
* @param inputUrl
|
||||||
|
* the input URI
|
||||||
|
* @param query
|
||||||
|
* the optional query string
|
||||||
|
* @return the WebSocket scheme URI for the input URI.
|
||||||
|
* @throws URISyntaxException
|
||||||
|
* if unable to convert the input URI
|
||||||
|
*/
|
||||||
|
public static URI toWebsocket(CharSequence inputUrl, String query) throws URISyntaxException
|
||||||
|
{
|
||||||
|
if (query == null)
|
||||||
|
{
|
||||||
|
return toWebsocket(new URI(inputUrl.toString()));
|
||||||
|
}
|
||||||
|
return toWebsocket(new URI(inputUrl.toString() + '?' + query));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to WebSocket <code>ws</code> or <code>wss</code> scheme URIs
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Converting <code>http</code> and <code>https</code> URIs to their WebSocket equivalent
|
||||||
|
*
|
||||||
|
* @param inputUri
|
||||||
|
* the input URI
|
||||||
|
* @return the WebSocket scheme URI for the input URI.
|
||||||
|
* @throws URISyntaxException
|
||||||
|
* if unable to convert the input URI
|
||||||
|
*/
|
||||||
|
public static URI toWebsocket(final URI inputUri) throws URISyntaxException
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(inputUri,"Input URI must not be null");
|
||||||
|
String httpScheme = inputUri.getScheme();
|
||||||
|
String wsScheme = null;
|
||||||
|
if ("ws".equalsIgnoreCase(httpScheme) || "wss".equalsIgnoreCase(httpScheme))
|
||||||
|
{
|
||||||
|
// keep as-is
|
||||||
|
wsScheme = httpScheme;
|
||||||
|
}
|
||||||
|
else if ("http".equalsIgnoreCase(httpScheme))
|
||||||
|
{
|
||||||
|
// convert to ws
|
||||||
|
wsScheme = "ws";
|
||||||
|
}
|
||||||
|
else if ("https".equalsIgnoreCase(httpScheme))
|
||||||
|
{
|
||||||
|
// convert to wss
|
||||||
|
wsScheme = "wss";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new URISyntaxException(inputUri.toString(),"Unrecognized HTTP scheme");
|
||||||
|
}
|
||||||
|
return new URI(wsScheme,inputUri.getUserInfo(),inputUri.getHost(),inputUri.getPort(),inputUri.getPath(),inputUri.getQuery(),inputUri.getFragment());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.eclipse.jetty.websocket.api.util;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class WSURITest
|
||||||
|
{
|
||||||
|
private void assertURI(URI actual, URI expected)
|
||||||
|
{
|
||||||
|
Assert.assertThat(actual.toASCIIString(),is(expected.toASCIIString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpsToHttps() throws URISyntaxException
|
||||||
|
{
|
||||||
|
assertURI(WSURI.toHttp(URI.create("https://localhost/")),URI.create("https://localhost/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpsToWss() throws URISyntaxException
|
||||||
|
{
|
||||||
|
assertURI(WSURI.toWebsocket(URI.create("https://localhost/")),URI.create("wss://localhost/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpToHttp() throws URISyntaxException
|
||||||
|
{
|
||||||
|
assertURI(WSURI.toHttp(URI.create("http://localhost/")),URI.create("http://localhost/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpToWs() throws URISyntaxException
|
||||||
|
{
|
||||||
|
assertURI(WSURI.toWebsocket(URI.create("http://localhost/")),URI.create("ws://localhost/"));
|
||||||
|
assertURI(WSURI.toWebsocket(URI.create("http://localhost:8080/deeper/")),URI.create("ws://localhost:8080/deeper/"));
|
||||||
|
assertURI(WSURI.toWebsocket("http://localhost/"),URI.create("ws://localhost/"));
|
||||||
|
assertURI(WSURI.toWebsocket("http://localhost/",null),URI.create("ws://localhost/"));
|
||||||
|
assertURI(WSURI.toWebsocket("http://localhost/","a=b"),URI.create("ws://localhost/?a=b"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWssToHttps() throws URISyntaxException
|
||||||
|
{
|
||||||
|
assertURI(WSURI.toHttp(URI.create("wss://localhost/")),URI.create("https://localhost/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWssToWss() throws URISyntaxException
|
||||||
|
{
|
||||||
|
assertURI(WSURI.toWebsocket(URI.create("wss://localhost/")),URI.create("wss://localhost/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWsToHttp() throws URISyntaxException
|
||||||
|
{
|
||||||
|
assertURI(WSURI.toHttp(URI.create("ws://localhost/")),URI.create("http://localhost/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWsToWs() throws URISyntaxException
|
||||||
|
{
|
||||||
|
assertURI(WSURI.toWebsocket(URI.create("ws://localhost/")),URI.create("ws://localhost/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,6 +37,11 @@
|
||||||
<artifactId>websocket-common</artifactId>
|
<artifactId>websocket-common</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||||
|
<artifactId>websocket-client</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||||
<artifactId>websocket-servlet</artifactId>
|
<artifactId>websocket-servlet</artifactId>
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
import java.net.HttpCookie;
|
import java.net.HttpCookie;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -36,14 +37,15 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.util.QuoteUtil;
|
import org.eclipse.jetty.websocket.api.util.QuoteUtil;
|
||||||
|
import org.eclipse.jetty.websocket.api.util.WSURI;
|
||||||
|
|
||||||
public class ServletWebSocketRequest extends UpgradeRequest
|
public class ServletWebSocketRequest extends UpgradeRequest
|
||||||
{
|
{
|
||||||
private HttpServletRequest req;
|
private HttpServletRequest req;
|
||||||
|
|
||||||
public ServletWebSocketRequest(HttpServletRequest request)
|
public ServletWebSocketRequest(HttpServletRequest request) throws URISyntaxException
|
||||||
{
|
{
|
||||||
super(request.getRequestURI());
|
super(WSURI.toWebsocket(request.getRequestURL(),request.getQueryString()));
|
||||||
this.req = request;
|
this.req = request;
|
||||||
|
|
||||||
// Copy Request Line Details
|
// Copy Request Line Details
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.eclipse.jetty.websocket.server;
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -27,6 +28,7 @@ import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@ -133,6 +135,8 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptWebSocket(HttpServletRequest request, HttpServletResponse response) throws IOException
|
public boolean acceptWebSocket(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
ServletWebSocketRequest sockreq = new ServletWebSocketRequest(request);
|
ServletWebSocketRequest sockreq = new ServletWebSocketRequest(request);
|
||||||
ServletWebSocketResponse sockresp = new ServletWebSocketResponse(response);
|
ServletWebSocketResponse sockresp = new ServletWebSocketResponse(response);
|
||||||
|
@ -167,6 +171,11 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
EventDriver driver = eventDriverFactory.wrap(websocketPojo);
|
EventDriver driver = eventDriverFactory.wrap(websocketPojo);
|
||||||
return upgrade(sockreq,sockresp,driver);
|
return upgrade(sockreq,sockresp,driver);
|
||||||
}
|
}
|
||||||
|
catch (URISyntaxException e)
|
||||||
|
{
|
||||||
|
throw new IOException("Unable to accept websocket due to mangled URI",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanup()
|
public void cleanup()
|
||||||
|
|
|
@ -19,35 +19,95 @@
|
||||||
package org.eclipse.jetty.websocket.server;
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.HttpConfiguration;
|
||||||
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
|
import org.eclipse.jetty.server.SecureRequestCustomizer;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
|
import org.eclipse.jetty.server.SslConnectionFactory;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
|
|
||||||
public class SimpleServletServer
|
public class SimpleServletServer
|
||||||
{
|
{
|
||||||
|
private static final Logger LOG = Log.getLogger(SimpleServletServer.class);
|
||||||
private Server server;
|
private Server server;
|
||||||
private ServerConnector connector;
|
private ServerConnector connector;
|
||||||
private URI serverUri;
|
private URI serverUri;
|
||||||
private HttpServlet servlet;
|
private HttpServlet servlet;
|
||||||
|
private boolean ssl = false;
|
||||||
|
private SslContextFactory sslContextFactory;
|
||||||
|
|
||||||
public SimpleServletServer(HttpServlet servlet)
|
public SimpleServletServer(HttpServlet servlet)
|
||||||
{
|
{
|
||||||
this.servlet = servlet;
|
this.servlet = servlet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void enableSsl(boolean ssl)
|
||||||
|
{
|
||||||
|
this.ssl = ssl;
|
||||||
|
}
|
||||||
|
|
||||||
public URI getServerUri()
|
public URI getServerUri()
|
||||||
{
|
{
|
||||||
return serverUri;
|
return serverUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SslContextFactory getSslContextFactory()
|
||||||
|
{
|
||||||
|
return sslContextFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSslEnabled()
|
||||||
|
{
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
public void start() throws Exception
|
public void start() throws Exception
|
||||||
{
|
{
|
||||||
// Configure Server
|
// Configure Server
|
||||||
server = new Server();
|
server = new Server();
|
||||||
|
if (ssl)
|
||||||
|
{
|
||||||
|
// HTTP Configuration
|
||||||
|
HttpConfiguration http_config = new HttpConfiguration();
|
||||||
|
http_config.setSecureScheme("https");
|
||||||
|
http_config.setSecurePort(0);
|
||||||
|
http_config.setOutputBufferSize(32768);
|
||||||
|
http_config.setRequestHeaderSize(8192);
|
||||||
|
http_config.setResponseHeaderSize(8192);
|
||||||
|
http_config.setSendServerVersion(true);
|
||||||
|
http_config.setSendDateHeader(false);
|
||||||
|
|
||||||
|
sslContextFactory = new SslContextFactory();
|
||||||
|
sslContextFactory.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath());
|
||||||
|
sslContextFactory.setKeyStorePassword("storepwd");
|
||||||
|
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||||
|
sslContextFactory.setExcludeCipherSuites("SSL_RSA_WITH_DES_CBC_SHA","SSL_DHE_RSA_WITH_DES_CBC_SHA","SSL_DHE_DSS_WITH_DES_CBC_SHA",
|
||||||
|
"SSL_RSA_EXPORT_WITH_RC4_40_MD5","SSL_RSA_EXPORT_WITH_DES40_CBC_SHA","SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
||||||
|
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
|
||||||
|
|
||||||
|
// SSL HTTP Configuration
|
||||||
|
HttpConfiguration https_config = new HttpConfiguration(http_config);
|
||||||
|
https_config.addCustomizer(new SecureRequestCustomizer());
|
||||||
|
|
||||||
|
// SSL Connector
|
||||||
|
connector = new ServerConnector(server,new SslConnectionFactory(sslContextFactory,"http/1.1"),new HttpConnectionFactory(https_config));
|
||||||
|
connector.setPort(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Basic HTTP connector
|
||||||
connector = new ServerConnector(server);
|
connector = new ServerConnector(server);
|
||||||
|
connector.setPort(0);
|
||||||
|
}
|
||||||
server.addConnector(connector);
|
server.addConnector(connector);
|
||||||
|
|
||||||
ServletContextHandler context = new ServletContextHandler();
|
ServletContextHandler context = new ServletContextHandler();
|
||||||
|
@ -60,13 +120,20 @@ public class SimpleServletServer
|
||||||
// Start Server
|
// Start Server
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
|
// Establish the Server URI
|
||||||
String host = connector.getHost();
|
String host = connector.getHost();
|
||||||
if (host == null)
|
if (host == null)
|
||||||
{
|
{
|
||||||
host = "localhost";
|
host = "localhost";
|
||||||
}
|
}
|
||||||
int port = connector.getLocalPort();
|
int port = connector.getLocalPort();
|
||||||
serverUri = new URI(String.format("ws://%s:%d/",host,port));
|
serverUri = new URI(String.format("%s://%s:%d/",ssl?"wss":"ws",host,port));
|
||||||
|
|
||||||
|
// Some debugging
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
{
|
||||||
|
LOG.debug(server.dump());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop()
|
public void stop()
|
||||||
|
|
|
@ -1,222 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// All rights reserved. This program and the accompanying materials
|
|
||||||
// are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
// and Apache License v2.0 which accompanies this distribution.
|
|
||||||
//
|
|
||||||
// The Eclipse Public License is available at
|
|
||||||
// http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
//
|
|
||||||
// The Apache License v2.0 is available at
|
|
||||||
// http://www.opensource.org/licenses/apache2.0.php
|
|
||||||
//
|
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.server;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
|
||||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
|
||||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
|
||||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketException;
|
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
|
||||||
import org.eclipse.jetty.websocket.common.Generator;
|
|
||||||
import org.eclipse.jetty.websocket.common.Parser;
|
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
|
||||||
import org.eclipse.jetty.websocket.server.examples.MyEchoSocket;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class WebSocketLoadRFC6455Test
|
|
||||||
{
|
|
||||||
private class WebSocketClient implements Runnable
|
|
||||||
{
|
|
||||||
private final Socket socket;
|
|
||||||
private final BufferedWriter output;
|
|
||||||
private final BufferedReader input;
|
|
||||||
private final int iterations;
|
|
||||||
private final CountDownLatch latch;
|
|
||||||
private/* final */EndPoint _endp;
|
|
||||||
private final Generator _generator;
|
|
||||||
private final Parser _parser;
|
|
||||||
private final IncomingFrames _handler = new IncomingFrames()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void incomingError(WebSocketException e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void incomingFrame(Frame frame)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private volatile ByteBuffer _response;
|
|
||||||
|
|
||||||
public WebSocketClient(String host, int port, int readTimeout, CountDownLatch latch, int iterations) throws IOException
|
|
||||||
{
|
|
||||||
this.latch = latch;
|
|
||||||
socket = new Socket(host,port);
|
|
||||||
socket.setSoTimeout(readTimeout);
|
|
||||||
output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"ISO-8859-1"));
|
|
||||||
input = new BufferedReader(new InputStreamReader(socket.getInputStream(),"ISO-8859-1"));
|
|
||||||
this.iterations = iterations;
|
|
||||||
|
|
||||||
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
|
||||||
|
|
||||||
// _endp=new SocketEndPoint(socket);
|
|
||||||
ByteBufferPool bufferPool = new MappedByteBufferPool();
|
|
||||||
_generator = new Generator(policy,bufferPool);
|
|
||||||
_parser = new Parser(policy,bufferPool);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws IOException
|
|
||||||
{
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void open() throws IOException
|
|
||||||
{
|
|
||||||
output.write("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n"
|
|
||||||
+ "Sec-WebSocket-Protocol: onConnect\r\n" + "Sec-WebSocket-Version: 7\r\n" + "\r\n");
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
String responseLine = input.readLine();
|
|
||||||
assertTrue(responseLine.startsWith("HTTP/1.1 101 Switching Protocols"));
|
|
||||||
// Read until we find an empty line, which signals the end of the http response
|
|
||||||
String line;
|
|
||||||
while ((line = input.readLine()) != null)
|
|
||||||
{
|
|
||||||
if (line.length() == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
String message = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
|
|
||||||
for (int i = 0; i < iterations; ++i)
|
|
||||||
{
|
|
||||||
WebSocketFrame txt = WebSocketFrame.text(message);
|
|
||||||
ByteBuffer buf = _generator.generate(txt);
|
|
||||||
|
|
||||||
// TODO: Send it
|
|
||||||
// TODO: Receive response
|
|
||||||
|
|
||||||
Assert.assertEquals(message,_response.toString());
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Throwable x)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Server _server;
|
|
||||||
|
|
||||||
private static ServerConnector _connector;
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void startServer() throws Exception
|
|
||||||
{
|
|
||||||
QueuedThreadPool threadPool = new QueuedThreadPool(200);
|
|
||||||
threadPool.setStopTimeout(1000);
|
|
||||||
_server = new Server(threadPool);
|
|
||||||
_server.manage(threadPool);
|
|
||||||
|
|
||||||
_connector = new ServerConnector(_server);
|
|
||||||
_server.addConnector(_connector);
|
|
||||||
|
|
||||||
WebSocketHandler wsHandler = new WebSocketHandler.Simple(MyEchoSocket.class);
|
|
||||||
wsHandler.setHandler(new DefaultHandler());
|
|
||||||
_server.setHandler(wsHandler);
|
|
||||||
|
|
||||||
_server.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void stopServer() throws Exception
|
|
||||||
{
|
|
||||||
_server.stop();
|
|
||||||
_server.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Ignore("Not yet converted to new jetty-9 structure")
|
|
||||||
public void testLoad() throws Exception
|
|
||||||
{
|
|
||||||
int count = 50;
|
|
||||||
int iterations = 100;
|
|
||||||
|
|
||||||
ExecutorService threadPool = Executors.newCachedThreadPool();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CountDownLatch latch = new CountDownLatch(count * iterations);
|
|
||||||
WebSocketClient[] clients = new WebSocketClient[count];
|
|
||||||
for (int i = 0; i < clients.length; ++i)
|
|
||||||
{
|
|
||||||
clients[i] = new WebSocketClient("localhost",_connector.getLocalPort(),1000,latch,iterations);
|
|
||||||
clients[i].open();
|
|
||||||
}
|
|
||||||
|
|
||||||
// long start = System.nanoTime();
|
|
||||||
for (WebSocketClient client : clients)
|
|
||||||
{
|
|
||||||
threadPool.execute(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
int parallelism = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
|
|
||||||
long maxTimePerIteration = 5;
|
|
||||||
assertTrue(latch.await(iterations * ((count / parallelism) + 1) * maxTimePerIteration,TimeUnit.MILLISECONDS));
|
|
||||||
// long end = System.nanoTime();
|
|
||||||
// System.err.println("Elapsed: " + TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
|
|
||||||
|
|
||||||
for (WebSocketClient client : clients)
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
threadPool.shutdown();
|
|
||||||
assertTrue(threadPool.awaitTermination(2,TimeUnit.SECONDS));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,155 +18,111 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.server;
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import static org.hamcrest.Matchers.*;
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|
||||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
import org.eclipse.jetty.websocket.server.examples.MyEchoSocket;
|
import org.eclipse.jetty.websocket.server.helper.CaptureSocket;
|
||||||
import org.junit.After;
|
import org.eclipse.jetty.websocket.server.helper.SessionServlet;
|
||||||
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Ignore;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class WebSocketOverSSLTest
|
public class WebSocketOverSSLTest
|
||||||
{
|
{
|
||||||
private Server _server;
|
private static SimpleServletServer server;
|
||||||
private int _port;
|
|
||||||
private QueuedThreadPool _threadPool;
|
|
||||||
|
|
||||||
private Session _session;
|
@BeforeClass
|
||||||
|
public static void startServer() throws Exception
|
||||||
@After
|
|
||||||
public void destroy() throws Exception
|
|
||||||
{
|
{
|
||||||
if (_session != null)
|
server = new SimpleServletServer(new SessionServlet());
|
||||||
{
|
server.enableSsl(true);
|
||||||
_session.close();
|
server.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (_wsFactory != null)
|
@AfterClass
|
||||||
// _wsFactory.stop();
|
public static void stopServer()
|
||||||
|
|
||||||
if (_threadPool != null)
|
|
||||||
{
|
{
|
||||||
_threadPool.stop();
|
server.stop();
|
||||||
}
|
|
||||||
|
|
||||||
if (_server != null)
|
|
||||||
{
|
|
||||||
_server.stop();
|
|
||||||
_server.join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startClient(final Object webSocket) throws Exception
|
|
||||||
{
|
|
||||||
Assert.assertTrue(_server.isStarted());
|
|
||||||
|
|
||||||
_threadPool = new QueuedThreadPool();
|
|
||||||
_threadPool.setName("wsc-" + _threadPool.getName());
|
|
||||||
_threadPool.start();
|
|
||||||
|
|
||||||
// _wsFactory = new WebSocketClientFactory(_threadPool, new ZeroMasker());
|
|
||||||
// SslContextFactory cf = _wsFactory.getSslContextFactory();
|
|
||||||
// cf.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath());
|
|
||||||
// cf.setKeyStorePassword("storepwd");
|
|
||||||
// cf.setKeyManagerPassword("keypwd");
|
|
||||||
// _wsFactory.start();
|
|
||||||
|
|
||||||
// WebSocketClient client = new WebSocketClient(_wsFactory);
|
|
||||||
// _connection = client.open(new URI("wss://localhost:" + _port), webSocket).get(5, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startServer(final Object websocket) throws Exception
|
|
||||||
{
|
|
||||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
|
||||||
sslContextFactory.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath());
|
|
||||||
sslContextFactory.setKeyStorePassword("storepwd");
|
|
||||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
|
||||||
_server = new Server();
|
|
||||||
ServerConnector connector = new ServerConnector(_server,sslContextFactory);
|
|
||||||
_server.addConnector(connector);
|
|
||||||
_server.setHandler(new WebSocketHandler.Simple(websocket.getClass()));
|
|
||||||
_server.start();
|
|
||||||
_port = connector.getLocalPort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the requirement of issuing socket and receiving echo response
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore("SSL Not yet implemented")
|
public void testEcho() throws Exception
|
||||||
public void testManyMessages() throws Exception
|
|
||||||
{
|
{
|
||||||
startServer(MyEchoSocket.class);
|
Assert.assertThat("server scheme",server.getServerUri().getScheme(),is("wss"));
|
||||||
int count = 1000;
|
WebSocketClient client = new WebSocketClient(server.getSslContextFactory());
|
||||||
final CountDownLatch clientLatch = new CountDownLatch(count);
|
try
|
||||||
startClient(new WebSocketAdapter()
|
|
||||||
{
|
{
|
||||||
@Override
|
client.start();
|
||||||
public void onWebSocketText(String message)
|
|
||||||
{
|
|
||||||
clientLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
char[] chars = new char[256];
|
CaptureSocket clientSocket = new CaptureSocket();
|
||||||
Arrays.fill(chars,'x');
|
Future<Session> fut = client.connect(clientSocket,server.getServerUri());
|
||||||
String message = new String(chars);
|
|
||||||
for (int i = 0; i < count; ++i)
|
// wait for connect
|
||||||
|
Session session = fut.get(1,TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
// Ask server socket
|
||||||
|
|
||||||
|
// Generate text frame
|
||||||
|
String msg = "this is an echo ... cho ... ho ... o";
|
||||||
|
session.getRemote().sendString(msg);
|
||||||
|
|
||||||
|
// Read frame (hopefully text frame)
|
||||||
|
clientSocket.messages.awaitEventCount(1,500,TimeUnit.MILLISECONDS);
|
||||||
|
EventQueue<String> captured = clientSocket.messages;
|
||||||
|
Assert.assertThat("Text Message",captured.poll(),is(msg));
|
||||||
|
|
||||||
|
// Shutdown the socket
|
||||||
|
clientSocket.close();
|
||||||
|
}
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
_session.getRemote().sendStringByFuture(message);
|
client.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.assertTrue(clientLatch.await(20,TimeUnit.SECONDS));
|
|
||||||
|
|
||||||
// While messages may have all arrived, the SSL close alert
|
|
||||||
// may be in the way so give some time for it to be processed.
|
|
||||||
TimeUnit.SECONDS.sleep(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that server session reports as secure
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore("SSL Not yet implemented")
|
public void testServerSessionIsSecure() throws Exception
|
||||||
public void testWebSocketOverSSL() throws Exception
|
|
||||||
{
|
{
|
||||||
final String message = "message";
|
Assert.assertThat("server scheme",server.getServerUri().getScheme(),is("wss"));
|
||||||
final CountDownLatch serverLatch = new CountDownLatch(1);
|
WebSocketClient client = new WebSocketClient(server.getSslContextFactory());
|
||||||
startServer(new WebSocketAdapter()
|
try
|
||||||
{
|
{
|
||||||
private Session session;
|
client.start();
|
||||||
|
|
||||||
@Override
|
CaptureSocket clientSocket = new CaptureSocket();
|
||||||
public void onWebSocketConnect(Session session)
|
Future<Session> fut = client.connect(clientSocket,server.getServerUri());
|
||||||
{
|
|
||||||
this.session = session;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
// wait for connect
|
||||||
public void onWebSocketText(String message)
|
Session session = fut.get(1,TimeUnit.SECONDS);
|
||||||
{
|
|
||||||
Assert.assertEquals(message,message);
|
|
||||||
session.getRemote().sendStringByFuture(message);
|
|
||||||
serverLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
final CountDownLatch clientLatch = new CountDownLatch(1);
|
|
||||||
startClient(new WebSocketAdapter()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onWebSocketText(String data)
|
|
||||||
{
|
|
||||||
Assert.assertEquals(message,data);
|
|
||||||
clientLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
_session.getRemote().sendStringByFuture(message);
|
|
||||||
|
|
||||||
Assert.assertTrue(serverLatch.await(5,TimeUnit.SECONDS));
|
// Ask server socket
|
||||||
Assert.assertTrue(clientLatch.await(5,TimeUnit.SECONDS));
|
|
||||||
|
// Generate text frame
|
||||||
|
session.getRemote().sendString("session.isSecure");
|
||||||
|
|
||||||
|
// Read frame (hopefully text frame)
|
||||||
|
clientSocket.messages.awaitEventCount(1,500,TimeUnit.MILLISECONDS);
|
||||||
|
EventQueue<String> captured = clientSocket.messages;
|
||||||
|
Assert.assertThat("Server.session.isSecure",captured.poll(),is("session.isSecure=true"));
|
||||||
|
|
||||||
|
// Shutdown the socket
|
||||||
|
clientSocket.close();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
client.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ public class WebSocketServletRFCTest
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the requirement of issuing
|
* Test the requirement of issuing socket and receiving echo response
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testEcho() throws Exception
|
public void testEcho() throws Exception
|
||||||
|
|
|
@ -55,6 +55,7 @@ import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
|
import org.eclipse.jetty.websocket.api.util.WSURI;
|
||||||
import org.eclipse.jetty.websocket.common.AcceptHash;
|
import org.eclipse.jetty.websocket.common.AcceptHash;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
import org.eclipse.jetty.websocket.common.ConnectionState;
|
import org.eclipse.jetty.websocket.common.ConnectionState;
|
||||||
|
@ -128,9 +129,12 @@ public class BlockheadClient implements IncomingFrames, OutgoingFrames, Connecti
|
||||||
if (destWebsocketURI.getScheme().equals("wss"))
|
if (destWebsocketURI.getScheme().equals("wss"))
|
||||||
{
|
{
|
||||||
scheme = "https";
|
scheme = "https";
|
||||||
|
throw new RuntimeException("Sorry, BlockheadClient does not support SSL");
|
||||||
}
|
}
|
||||||
this.destHttpURI = new URI(scheme,destWebsocketURI.getUserInfo(),destWebsocketURI.getHost(),destWebsocketURI.getPort(),destWebsocketURI.getPath(),
|
this.destHttpURI = WSURI.toHttp(destWebsocketURI);
|
||||||
destWebsocketURI.getQuery(),destWebsocketURI.getFragment());
|
|
||||||
|
LOG.debug("WebSocket URI: {}",destWebsocketURI);
|
||||||
|
LOG.debug(" HTTP URI: {}",destHttpURI);
|
||||||
|
|
||||||
this.bufferPool = new MappedByteBufferPool(8192);
|
this.bufferPool = new MappedByteBufferPool(8192);
|
||||||
this.generator = new Generator(policy,bufferPool);
|
this.generator = new Generator(policy,bufferPool);
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.server.blockhead;
|
package org.eclipse.jetty.websocket.server.blockhead;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -30,8 +32,6 @@ import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
import org.junit.runners.Parameterized.Parameters;
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gotta test some basic constructors of the BlockheadClient.
|
* Gotta test some basic constructors of the BlockheadClient.
|
||||||
*/
|
*/
|
||||||
|
@ -47,7 +47,6 @@ public class BlockheadClientConstructionTest
|
||||||
data.add(new Object[] { "ws://localhost:8080/", "http://localhost:8080/" });
|
data.add(new Object[] { "ws://localhost:8080/", "http://localhost:8080/" });
|
||||||
data.add(new Object[] { "ws://webtide.com/", "http://webtide.com/" });
|
data.add(new Object[] { "ws://webtide.com/", "http://webtide.com/" });
|
||||||
data.add(new Object[] { "ws://www.webtide.com/sockets/chat", "http://www.webtide.com/sockets/chat" });
|
data.add(new Object[] { "ws://www.webtide.com/sockets/chat", "http://www.webtide.com/sockets/chat" });
|
||||||
data.add(new Object[] { "wss://dummy.eclipse.org:5454/", "https://dummy.eclipse.org:5454/" });
|
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,22 +18,22 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.server.helper;
|
package org.eclipse.jetty.websocket.server.helper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||||
|
|
||||||
public class CaptureSocket extends WebSocketAdapter
|
public class CaptureSocket extends WebSocketAdapter
|
||||||
{
|
{
|
||||||
private final CountDownLatch latch = new CountDownLatch(1);
|
private final CountDownLatch latch = new CountDownLatch(1);
|
||||||
public List<String> messages;
|
public EventQueue<String> messages;
|
||||||
|
|
||||||
public CaptureSocket()
|
public CaptureSocket()
|
||||||
{
|
{
|
||||||
messages = new ArrayList<String>();
|
messages = new EventQueue<String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean awaitConnected(long timeout) throws InterruptedException
|
public boolean awaitConnected(long timeout) throws InterruptedException
|
||||||
|
@ -41,6 +41,18 @@ public class CaptureSocket extends WebSocketAdapter
|
||||||
return latch.await(timeout,TimeUnit.MILLISECONDS);
|
return latch.await(timeout,TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
getSession().close();
|
||||||
|
}
|
||||||
|
catch (IOException ignore)
|
||||||
|
{
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onClose(int closeCode, String message)
|
public void onClose(int closeCode, String message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,20 @@ public class SessionSocket
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("session.isSecure".equals(message))
|
||||||
|
{
|
||||||
|
String issecure = String.format("session.isSecure=%b",session.isSecure());
|
||||||
|
session.getRemote().sendStringByFuture(issecure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("getRequestURI".equals(message))
|
||||||
|
{
|
||||||
|
String requestURI = session.getUpgradeRequest().getRequestURI().toASCIIString();
|
||||||
|
session.getRemote().sendStringByFuture(requestURI);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ("harsh-disconnect".equals(message))
|
if ("harsh-disconnect".equals(message))
|
||||||
{
|
{
|
||||||
session.disconnect();
|
session.disconnect();
|
||||||
|
|
Loading…
Reference in New Issue