444771 - JSR356 / EndPointConfig.userProperties are not unique per
endpoint upgrade + Adding testcase & implementation which honors the ServerEndpointConfig.userProperties copy at an earlier point.
This commit is contained in:
parent
65cae13b1e
commit
e93247de42
|
@ -54,14 +54,14 @@ public class BasicServerEndpointConfig implements ServerEndpointConfig
|
|||
|
||||
public BasicServerEndpointConfig(ServerEndpointConfig copy)
|
||||
{
|
||||
// immutable concepts
|
||||
this.endpointClass = copy.getEndpointClass();
|
||||
this.path = copy.getPath();
|
||||
|
||||
this.decoders = new ArrayList<>(copy.getDecoders());
|
||||
this.encoders = new ArrayList<>(copy.getEncoders());
|
||||
this.subprotocols = new ArrayList<>(copy.getSubprotocols());
|
||||
this.extensions = new ArrayList<>(copy.getExtensions());
|
||||
this.userProperties = new HashMap<>(copy.getUserProperties());
|
||||
this.decoders = copy.getDecoders();
|
||||
this.encoders = copy.getEncoders();
|
||||
this.subprotocols = copy.getSubprotocols();
|
||||
this.extensions = copy.getExtensions();
|
||||
if (copy.getConfigurator() != null)
|
||||
{
|
||||
this.configurator = copy.getConfigurator();
|
||||
|
@ -70,6 +70,9 @@ public class BasicServerEndpointConfig implements ServerEndpointConfig
|
|||
{
|
||||
this.configurator = BasicServerEndpointConfigurator.INSTANCE;
|
||||
}
|
||||
|
||||
// mutable concepts
|
||||
this.userProperties = new HashMap<>(copy.getUserProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -56,8 +56,14 @@ public class JsrCreator implements WebSocketCreator
|
|||
JsrHandshakeRequest hsreq = new JsrHandshakeRequest(req);
|
||||
JsrHandshakeResponse hsresp = new JsrHandshakeResponse(resp);
|
||||
|
||||
// Get raw config, as defined when the endpoint was added to the container
|
||||
ServerEndpointConfig config = metadata.getConfig();
|
||||
|
||||
// Establish a copy of the config, so that the UserProperties are unique
|
||||
// per upgrade request.
|
||||
config = new BasicServerEndpointConfig(config);
|
||||
|
||||
// Get Configurator from config object (not guaranteed to be unique per endpoint upgrade)
|
||||
ServerEndpointConfig.Configurator configurator = config.getConfigurator();
|
||||
|
||||
// modify handshake
|
||||
|
|
|
@ -18,12 +18,16 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.jsr356.server;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.websocket.Extension;
|
||||
import javax.websocket.HandshakeResponse;
|
||||
import javax.websocket.OnMessage;
|
||||
|
@ -49,9 +53,6 @@ import org.junit.Assert;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
public class ConfiguratorTest
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(ConfiguratorTest.class);
|
||||
|
@ -162,6 +163,48 @@ public class ConfiguratorTest
|
|||
}
|
||||
}
|
||||
|
||||
public static class UniqueUserPropsConfigurator extends ServerEndpointConfig.Configurator
|
||||
{
|
||||
private AtomicInteger upgradeCount = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response)
|
||||
{
|
||||
int upgradeNum = upgradeCount.addAndGet(1);
|
||||
LOG.debug("Upgrade Num: {}", upgradeNum);
|
||||
sec.getUserProperties().put("upgradeNum",Integer.toString(upgradeNum));
|
||||
switch(upgradeNum) {
|
||||
case 1: sec.getUserProperties().put("apple", "fruit from tree"); break;
|
||||
case 2: sec.getUserProperties().put("blueberry", "fruit from bush"); break;
|
||||
case 3: sec.getUserProperties().put("strawberry", "fruit from annual"); break;
|
||||
default: sec.getUserProperties().put("fruit"+upgradeNum, "placeholder"); break;
|
||||
}
|
||||
|
||||
super.modifyHandshake(sec,request,response);
|
||||
}
|
||||
}
|
||||
|
||||
@ServerEndpoint(value = "/unique-user-props", configurator = UniqueUserPropsConfigurator.class)
|
||||
public static class UniqueUserPropsSocket
|
||||
{
|
||||
@OnMessage
|
||||
public String onMessage(Session session, String msg)
|
||||
{
|
||||
String value = (String)session.getUserProperties().get(msg);
|
||||
StringBuilder response = new StringBuilder();
|
||||
response.append("Requested User Property: [").append(msg).append("] = ");
|
||||
if (value == null)
|
||||
{
|
||||
response.append("<null>");
|
||||
}
|
||||
else
|
||||
{
|
||||
response.append('"').append(value).append('"');
|
||||
}
|
||||
return response.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static Server server;
|
||||
private static URI baseServerUri;
|
||||
|
||||
|
@ -182,6 +225,7 @@ public class ConfiguratorTest
|
|||
container.addEndpoint(EmptySocket.class);
|
||||
container.addEndpoint(NoExtensionsSocket.class);
|
||||
container.addEndpoint(ProtocolsSocket.class);
|
||||
container.addEndpoint(UniqueUserPropsSocket.class);
|
||||
|
||||
server.start();
|
||||
String host = connector.getHost();
|
||||
|
@ -250,6 +294,43 @@ public class ConfiguratorTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUniqueUserPropsConfigurator() throws Exception
|
||||
{
|
||||
URI uri = baseServerUri.resolve("/unique-user-props");
|
||||
|
||||
// First request
|
||||
try (BlockheadClient client = new BlockheadClient(uri))
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
client.write(new TextFrame().setPayload("apple"));
|
||||
EventQueue<WebSocketFrame> frames = client.readFrames(1,1,TimeUnit.SECONDS);
|
||||
WebSocketFrame frame = frames.poll();
|
||||
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = \"fruit from tree\""));
|
||||
}
|
||||
|
||||
// Second request
|
||||
try (BlockheadClient client = new BlockheadClient(uri))
|
||||
{
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
client.expectUpgradeResponse();
|
||||
|
||||
client.write(new TextFrame().setPayload("apple"));
|
||||
client.write(new TextFrame().setPayload("blueberry"));
|
||||
EventQueue<WebSocketFrame> frames = client.readFrames(2,1,TimeUnit.SECONDS);
|
||||
WebSocketFrame frame = frames.poll();
|
||||
// should have no value
|
||||
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = <null>"));
|
||||
|
||||
frame = frames.poll();
|
||||
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [blueberry] = \"fruit from bush\""));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of Sec-WebSocket-Protocol, as seen in RFC-6455, 1 protocol
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue