Skip to content

Commit

Permalink
Issue #7573 - fix support in websocket for class path param types
Browse files Browse the repository at this point in the history
Signed-off-by: Lachlan Roberts <[email protected]>
(cherry picked from commit 7081a77)
  • Loading branch information
lachlan-roberts authored and joakime committed Feb 25, 2022
1 parent 89845f2 commit ce8825b
Show file tree
Hide file tree
Showing 20 changed files with 601 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -536,49 +536,47 @@ public static MethodHandle bindTemplateVariables(MethodHandle target, String[] n
{
retHandle = MethodHandles.insertArguments(retHandle, IDX, strValue);
}
else if (Integer.TYPE.isAssignableFrom(type))
else if (Integer.class.isAssignableFrom(type) || Integer.TYPE.isAssignableFrom(type))
{
int intValue = Integer.parseInt(strValue);
Integer intValue = Integer.parseInt(strValue);
retHandle = MethodHandles.insertArguments(retHandle, IDX, intValue);
}
else if (Long.TYPE.isAssignableFrom(type))
else if (Long.class.isAssignableFrom(type) || Long.TYPE.isAssignableFrom(type))
{
long longValue = Long.parseLong(strValue);
Long longValue = Long.parseLong(strValue);
retHandle = MethodHandles.insertArguments(retHandle, IDX, longValue);
}
else if (Short.TYPE.isAssignableFrom(type))
else if (Short.class.isAssignableFrom(type) || Short.TYPE.isAssignableFrom(type))
{
short shortValue = Short.parseShort(strValue);
Short shortValue = Short.parseShort(strValue);
retHandle = MethodHandles.insertArguments(retHandle, IDX, shortValue);
}
else if (Float.TYPE.isAssignableFrom(type))
else if (Float.class.isAssignableFrom(type) || Float.TYPE.isAssignableFrom(type))
{
float floatValue = Float.parseFloat(strValue);
Float floatValue = Float.parseFloat(strValue);
retHandle = MethodHandles.insertArguments(retHandle, IDX, floatValue);
}
else if (Double.TYPE.isAssignableFrom(type))
else if (Double.class.isAssignableFrom(type) || Double.TYPE.isAssignableFrom(type))
{
double doubleValue = Double.parseDouble(strValue);
Double doubleValue = Double.parseDouble(strValue);
retHandle = MethodHandles.insertArguments(retHandle, IDX, doubleValue);
}
else if (Boolean.TYPE.isAssignableFrom(type))
else if (Boolean.class.isAssignableFrom(type) || Boolean.TYPE.isAssignableFrom(type))
{
boolean boolValue = Boolean.parseBoolean(strValue);
Boolean boolValue = Boolean.parseBoolean(strValue);
retHandle = MethodHandles.insertArguments(retHandle, IDX, boolValue);
}
else if (Character.TYPE.isAssignableFrom(type))
else if (Character.class.isAssignableFrom(type) || Character.TYPE.isAssignableFrom(type))
{
if (strValue.length() != 1)
throw new IllegalArgumentException("Invalid Size");
char charValue = strValue.charAt(0);
Character charValue = strValue.charAt(0);
retHandle = MethodHandles.insertArguments(retHandle, IDX, charValue);
}
else if (Byte.TYPE.isAssignableFrom(type))
else if (Byte.class.isAssignableFrom(type) || Byte.TYPE.isAssignableFrom(type))
{
byte[] buf = strValue.getBytes(UTF_8);
if (buf.length != 1)
throw new IllegalArgumentException("Invalid Size");
retHandle = MethodHandles.insertArguments(retHandle, IDX, buf[0]);
Byte b = Byte.parseByte(strValue);
retHandle = MethodHandles.insertArguments(retHandle, IDX, b);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,21 @@ public InvokerUtils.Arg getParamArg(Method method, Class<?> paramType, int idx)
public static void validateType(Class<?> type)
{
if (!String.class.isAssignableFrom(type) &&
!Integer.class.isAssignableFrom(type) &&
!Integer.TYPE.isAssignableFrom(type) &&
!Long.class.isAssignableFrom(type) &&
!Long.TYPE.isAssignableFrom(type) &&
!Short.class.isAssignableFrom(type) &&
!Short.TYPE.isAssignableFrom(type) &&
!Float.class.isAssignableFrom(type) &&
!Float.TYPE.isAssignableFrom(type) &&
!Double.class.isAssignableFrom(type) &&
!Double.TYPE.isAssignableFrom(type) &&
!Boolean.class.isAssignableFrom(type) &&
!Boolean.TYPE.isAssignableFrom(type) &&
!Character.class.isAssignableFrom(type) &&
!Character.TYPE.isAssignableFrom(type) &&
!Byte.class.isAssignableFrom(type) &&
!Byte.TYPE.isAssignableFrom(type))
throw new InvalidSignatureException("Unsupported PathParam Type: " + type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import java.net.URI;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import jakarta.websocket.ContainerProvider;
import jakarta.websocket.OnMessage;
Expand All @@ -27,12 +28,35 @@
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
import org.eclipse.jetty.websocket.jakarta.server.internal.JakartaWebSocketServerContainer;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.BooleanClassSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.BooleanTypeSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.ByteClassSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.ByteTypeSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.CharacterClassSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.CharacterTypeSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.DoubleClassSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.DoubleTypeSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.FloatClassSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.FloatTypeSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.IntegerClassSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.IntegerTypeSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.LongClassSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.LongTypeSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.ShortClassSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.ShortTypeSocket;
import org.eclipse.jetty.websocket.jakarta.tests.pathparam.StringClassSocket;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class PathParamTest
{
Expand Down Expand Up @@ -81,6 +105,48 @@ public void onMessage(String message, @PathParam("name") String name)
}
}

public static Stream<Arguments> pathParamEndpoints()
{
return Stream.of(
Arguments.of(BooleanClassSocket.class, "false"),
Arguments.of(BooleanTypeSocket.class, "true"),
Arguments.of(ByteClassSocket.class, "32"),
Arguments.of(ByteTypeSocket.class, "51"),
Arguments.of(CharacterClassSocket.class, "q"),
Arguments.of(CharacterTypeSocket.class, "&"),
Arguments.of(DoubleClassSocket.class, Double.toString(Double.MAX_VALUE)),
Arguments.of(DoubleTypeSocket.class, Double.toString(Double.MIN_VALUE)),
Arguments.of(FloatClassSocket.class, "0.00235"),
Arguments.of(FloatTypeSocket.class, "123.456"),
Arguments.of(IntegerClassSocket.class, Integer.toString(Integer.MIN_VALUE)),
Arguments.of(IntegerTypeSocket.class, Integer.toString(Integer.MAX_VALUE)),
Arguments.of(LongClassSocket.class, Long.toString(Long.MAX_VALUE)),
Arguments.of(LongTypeSocket.class, Long.toString(Long.MIN_VALUE)),
Arguments.of(ShortClassSocket.class, Short.toString(Short.MAX_VALUE)),
Arguments.of(ShortTypeSocket.class, Short.toString(Short.MIN_VALUE)),
Arguments.of(StringClassSocket.class, "this_is_a_String_ID")
);
}

@ParameterizedTest
@MethodSource("pathParamEndpoints")
public void testPathParamSignatures(Class<?> endpointClass, String id) throws Exception
{
JakartaWebSocketServerContainer serverContainer = JakartaWebSocketServerContainer.getContainer(_context.getServletContext());
assertNotNull(serverContainer);
serverContainer.addEndpoint(endpointClass);

WebSocketContainer container = ContainerProvider.getWebSocketContainer();
EventSocket clientEndpoint = new EventSocket();

URI serverUri = URI.create("ws://localhost:" + _connector.getLocalPort() + "/context/pathParam/id/" + id);
container.connectToServer(clientEndpoint, serverUri);

assertTrue(clientEndpoint.closeLatch.await(5, TimeUnit.SECONDS));
String resp = clientEndpoint.textMessages.poll(1, TimeUnit.SECONDS);
assertThat(resp, is("id: " + id));
}

@Test
public void testBasicPathParamSocket() throws Exception
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.websocket.jakarta.tests.pathparam;

import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;

@ServerEndpoint("/pathParam/id/{id}")
public class BooleanClassSocket
{
@OnOpen
public void onOpen(Session session, @PathParam("id") Boolean id) throws Exception
{
session.getBasicRemote().sendText("id: " + id);
session.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.websocket.jakarta.tests.pathparam;

import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;

@ServerEndpoint("/pathParam/id/{id}")
public class BooleanTypeSocket
{
@OnOpen
public void onOpen(Session session, @PathParam("id") boolean id) throws Exception
{
session.getBasicRemote().sendText("id: " + id);
session.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.websocket.jakarta.tests.pathparam;

import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;

@ServerEndpoint("/pathParam/id/{id}")
public class ByteClassSocket
{
@OnOpen
public void onOpen(Session session, @PathParam("id") Byte id) throws Exception
{
session.getBasicRemote().sendText("id: " + id);
session.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.websocket.jakarta.tests.pathparam;

import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;

@ServerEndpoint("/pathParam/id/{id}")
public class ByteTypeSocket
{
@OnOpen
public void onOpen(Session session, @PathParam("id") byte id) throws Exception
{
session.getBasicRemote().sendText("id: " + id);
session.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.websocket.jakarta.tests.pathparam;

import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;

@ServerEndpoint("/pathParam/id/{id}")
public class CharacterClassSocket
{
@OnOpen
public void onOpen(Session session, @PathParam("id") Character id) throws Exception
{
session.getBasicRemote().sendText("id: " + id);
session.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.websocket.jakarta.tests.pathparam;

import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;

@ServerEndpoint("/pathParam/id/{id}")
public class CharacterTypeSocket
{
@OnOpen
public void onOpen(Session session, @PathParam("id") char id) throws Exception
{
session.getBasicRemote().sendText("id: " + id);
session.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.websocket.jakarta.tests.pathparam;

import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;

@ServerEndpoint("/pathParam/id/{id}")
public class DoubleClassSocket
{
@OnOpen
public void onOpen(Session session, @PathParam("id") Double id) throws Exception
{
session.getBasicRemote().sendText("id: " + id);
session.close();
}
}
Loading

0 comments on commit ce8825b

Please sign in to comment.