JSR-356 adding support for ClientEndpointConfig.Configurator
This commit is contained in:
parent
598ecd7d7f
commit
97854b6c5b
|
@ -37,6 +37,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.eclipse.jetty.websocket.client.io.UpgradeListener;
|
||||
import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.ConfiguredEndpoint;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.JsrClientMetadata;
|
||||
|
@ -64,6 +65,8 @@ public class ClientContainer implements ContainerService
|
|||
}
|
||||
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(websocket,cec);
|
||||
ClientUpgradeRequest req = new ClientUpgradeRequest();
|
||||
UpgradeListener upgradeListener = null;
|
||||
|
||||
if (cec != null)
|
||||
{
|
||||
for (Extension ext : cec.getExtensions())
|
||||
|
@ -75,8 +78,14 @@ public class ClientContainer implements ContainerService
|
|||
{
|
||||
req.setSubProtocols(config.getPreferredSubprotocols());
|
||||
}
|
||||
|
||||
if (cec.getConfigurator() != null)
|
||||
{
|
||||
upgradeListener = new JsrUpgradeListener(cec.getConfigurator());
|
||||
}
|
||||
}
|
||||
Future<org.eclipse.jetty.websocket.api.Session> futSess = client.connect(endpoint,path,req);
|
||||
|
||||
Future<org.eclipse.jetty.websocket.api.Session> futSess = client.connect(endpoint,path,req,upgradeListener);
|
||||
try
|
||||
{
|
||||
return (JsrSession)futSess.get();
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.websocket.HandshakeResponse;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
||||
|
||||
public class JsrHandshakeResponse implements HandshakeResponse
|
||||
{
|
||||
private final Map<String, List<String>> headers;
|
||||
|
||||
public JsrHandshakeResponse(UpgradeResponse response)
|
||||
{
|
||||
this.headers = response.getHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getHeaders()
|
||||
{
|
||||
return this.headers;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.websocket.ClientEndpointConfig.Configurator;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.client.io.UpgradeListener;
|
||||
|
||||
public class JsrUpgradeListener implements UpgradeListener
|
||||
{
|
||||
private Configurator configurator;
|
||||
|
||||
public JsrUpgradeListener(Configurator configurator)
|
||||
{
|
||||
this.configurator = configurator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHandshakeRequest(UpgradeRequest request)
|
||||
{
|
||||
if (configurator == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, List<String>> headers = request.getHeaders();
|
||||
configurator.beforeRequest(headers);
|
||||
request.setHeaders(headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHandshakeResponse(UpgradeResponse response)
|
||||
{
|
||||
if (configurator == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JsrHandshakeResponse hr = new JsrHandshakeResponse(response);
|
||||
configurator.afterResponse(hr);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.websocket.ClientEndpointConfig;
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.HandshakeResponse;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests of {@link ClientEndpointConfig.Configurator}
|
||||
*/
|
||||
public class ConfiguratorTest
|
||||
{
|
||||
public class TrackingConfigurator extends ClientEndpointConfig.Configurator
|
||||
{
|
||||
public HandshakeResponse response;
|
||||
public Map<String, List<String>> request;
|
||||
|
||||
@Override
|
||||
public void afterResponse(HandshakeResponse hr)
|
||||
{
|
||||
this.response = hr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRequest(Map<String, List<String>> headers)
|
||||
{
|
||||
this.request = headers;
|
||||
}
|
||||
}
|
||||
|
||||
private static Server server;
|
||||
private static EchoHandler handler;
|
||||
private static URI serverUri;
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception
|
||||
{
|
||||
server = new Server();
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
server.addConnector(connector);
|
||||
|
||||
handler = new EchoHandler();
|
||||
|
||||
ContextHandler context = new ContextHandler();
|
||||
context.setContextPath("/");
|
||||
context.setHandler(handler);
|
||||
server.setHandler(context);
|
||||
|
||||
// Start Server
|
||||
server.start();
|
||||
|
||||
String host = connector.getHost();
|
||||
if (host == null)
|
||||
{
|
||||
host = "localhost";
|
||||
}
|
||||
int port = connector.getLocalPort();
|
||||
serverUri = new URI(String.format("ws://%s:%d/",host,port));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer()
|
||||
{
|
||||
try
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEndpointHandshakeInfo() throws Exception
|
||||
{
|
||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||
EndpointEchoClient echoer = new EndpointEchoClient();
|
||||
ClientEndpointConfig.Builder cfgbldr = ClientEndpointConfig.Builder.create();
|
||||
TrackingConfigurator configurator = new TrackingConfigurator();
|
||||
cfgbldr.configurator(configurator);
|
||||
ClientEndpointConfig config = cfgbldr.build();
|
||||
Session session = container.connectToServer(echoer,config,serverUri);
|
||||
session.getBasicRemote().sendText("Echo");
|
||||
echoer.textCapture.messageQueue.awaitMessages(1,1000,TimeUnit.MILLISECONDS);
|
||||
|
||||
Assert.assertThat("configurator.request",configurator.request,notNullValue());
|
||||
Assert.assertThat("configurator.response",configurator.response,notNullValue());
|
||||
}
|
||||
}
|
|
@ -75,6 +75,11 @@ public class UpgradeRequest
|
|||
}
|
||||
}
|
||||
|
||||
public void clearHeaders()
|
||||
{
|
||||
headers.clear();
|
||||
}
|
||||
|
||||
public List<HttpCookie> getCookies()
|
||||
{
|
||||
return cookies;
|
||||
|
@ -242,6 +247,18 @@ public class UpgradeRequest
|
|||
setHeader(name.toLowerCase(Locale.ENGLISH),values);
|
||||
}
|
||||
|
||||
public void setHeaders(Map<String, List<String>> headers)
|
||||
{
|
||||
clearHeaders();
|
||||
|
||||
for (Map.Entry<String, List<String>> entry : headers.entrySet())
|
||||
{
|
||||
String name = entry.getKey();
|
||||
List<String> values = entry.getValue();
|
||||
setHeader(name,values);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHttpVersion(String httpVersion)
|
||||
{
|
||||
this.httpVersion = httpVersion;
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
|||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||
import org.eclipse.jetty.websocket.client.io.ConnectPromise;
|
||||
import org.eclipse.jetty.websocket.client.io.ConnectionManager;
|
||||
import org.eclipse.jetty.websocket.client.io.UpgradeListener;
|
||||
import org.eclipse.jetty.websocket.client.masks.Masker;
|
||||
import org.eclipse.jetty.websocket.client.masks.RandomMasker;
|
||||
import org.eclipse.jetty.websocket.common.SessionFactory;
|
||||
|
@ -101,6 +102,11 @@ public class WebSocketClient extends ContainerLifeCycle
|
|||
}
|
||||
|
||||
public Future<Session> connect(Object websocket, URI toUri, ClientUpgradeRequest request) throws IOException
|
||||
{
|
||||
return connect(websocket,toUri,request,null);
|
||||
}
|
||||
|
||||
public Future<Session> connect(Object websocket, URI toUri, ClientUpgradeRequest request, UpgradeListener upgradeListener) throws IOException
|
||||
{
|
||||
if (!isStarted())
|
||||
{
|
||||
|
@ -163,6 +169,11 @@ public class WebSocketClient extends ContainerLifeCycle
|
|||
// Create the appropriate (physical vs virtual) connection task
|
||||
ConnectPromise promise = manager.connect(this,driver,request);
|
||||
|
||||
if (upgradeListener != null)
|
||||
{
|
||||
promise.setUpgradeListener(upgradeListener);
|
||||
}
|
||||
|
||||
LOG.debug("Connect Promise: {}",promise);
|
||||
|
||||
// Execute the connection on the executor thread
|
||||
|
|
|
@ -36,6 +36,7 @@ public abstract class ConnectPromise extends FuturePromise<Session> implements R
|
|||
private final EventDriver driver;
|
||||
private final ClientUpgradeRequest request;
|
||||
private final Masker masker;
|
||||
private UpgradeListener upgradeListener;
|
||||
private ClientUpgradeResponse response;
|
||||
|
||||
public ConnectPromise(WebSocketClient client, EventDriver driver, ClientUpgradeRequest request)
|
||||
|
@ -81,11 +82,21 @@ public abstract class ConnectPromise extends FuturePromise<Session> implements R
|
|||
return response;
|
||||
}
|
||||
|
||||
public UpgradeListener getUpgradeListener()
|
||||
{
|
||||
return upgradeListener;
|
||||
}
|
||||
|
||||
public void setResponse(ClientUpgradeResponse response)
|
||||
{
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public void setUpgradeListener(UpgradeListener upgradeListener)
|
||||
{
|
||||
this.upgradeListener = upgradeListener;
|
||||
}
|
||||
|
||||
public void succeeded(WebSocketSession session)
|
||||
{
|
||||
session.setUpgradeRequest(request);
|
||||
|
|
|
@ -203,7 +203,7 @@ public class ConnectionManager extends ContainerLifeCycle
|
|||
return Collections.unmodifiableCollection(sessions);
|
||||
}
|
||||
|
||||
private boolean isVirtualConnectionPossibleTo(String hostname)
|
||||
public boolean isVirtualConnectionPossibleTo(String hostname)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
|
|
|
@ -61,6 +61,13 @@ public class UpgradeConnection extends AbstractConnection
|
|||
{
|
||||
URI uri = connectPromise.getRequest().getRequestURI();
|
||||
request.setRequestURI(uri);
|
||||
|
||||
UpgradeListener handshakeListener = connectPromise.getUpgradeListener();
|
||||
if (handshakeListener != null)
|
||||
{
|
||||
handshakeListener.onHandshakeRequest(request);
|
||||
}
|
||||
|
||||
String rawRequest = request.generate();
|
||||
|
||||
ByteBuffer buf = BufferUtil.toBuffer(rawRequest,StringUtil.__UTF8_CHARSET);
|
||||
|
@ -114,6 +121,12 @@ public class UpgradeConnection extends AbstractConnection
|
|||
private void notifyConnect(ClientUpgradeResponse response)
|
||||
{
|
||||
connectPromise.setResponse(response);
|
||||
|
||||
UpgradeListener handshakeListener = connectPromise.getUpgradeListener();
|
||||
if (handshakeListener != null)
|
||||
{
|
||||
handshakeListener.onHandshakeResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -141,7 +154,6 @@ public class UpgradeConnection extends AbstractConnection
|
|||
public void onOpen()
|
||||
{
|
||||
super.onOpen();
|
||||
// TODO: handle timeout
|
||||
getExecutor().execute(new SendUpgradeRequest());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.client.io;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
||||
|
||||
/**
|
||||
* Listener for Handshake/Upgrade events.
|
||||
*/
|
||||
public interface UpgradeListener
|
||||
{
|
||||
public void onHandshakeRequest(UpgradeRequest request);
|
||||
|
||||
public void onHandshakeResponse(UpgradeResponse response);
|
||||
}
|
Loading…
Reference in New Issue