Skip to content

Commit

Permalink
Updated TyrusSupport to correctly propagate query params from webserv…
Browse files Browse the repository at this point in the history
…er (#4624)

* Updated TyrusSupport to correctly propagate query params from webserver to Tyrus. Moved UriComponent over to common/http for sharing purposes. Updated tests to verify changes.

* Fixed checkstyle problems.

Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com>
  • Loading branch information
spericas authored Jul 28, 2022
1 parent 9d2dc1c commit 8c7949e
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021 Oracle and/or its affiliates.
* Copyright (c) 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,24 +14,18 @@
* limitations under the License.
*/

package io.helidon.webserver;
package io.helidon.common.http;

import java.net.URLDecoder;

import io.helidon.common.http.HashParameters;
import io.helidon.common.http.Parameters;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
* Extracted from Jersey
* <p>
* Utility class for validating, encoding and decoding components of a URI.
*
* @author Paul Sandoz
* @author Marek Potociar (marek.potociar at oracle.com)
*/
final class UriComponent {
public final class UriComponent {

private UriComponent() {
}
Expand All @@ -47,7 +41,7 @@ private UriComponent() {
* should be in decoded form.
* @return the multivalued map of query parameters.
*/
static Parameters decodeQuery(String query, boolean decode) {
public static Parameters decodeQuery(String query, boolean decode) {
return decodeQuery(query, true, decode);
}

Expand All @@ -64,7 +58,7 @@ static Parameters decodeQuery(String query, boolean decode) {
* should be in decoded form.
* @return the multivalued map of query parameters.
*/
static Parameters decodeQuery(String query, boolean decodeNames, boolean decodeValues) {
public static Parameters decodeQuery(String query, boolean decodeNames, boolean decodeValues) {
Parameters queryParameters = HashParameters.create();

if (query == null || query.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021 Oracle and/or its affiliates.
* Copyright (c) 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,14 +14,12 @@
* limitations under the License.
*/

package io.helidon.webserver;
package io.helidon.common.http;

import java.net.URI;
import java.net.URLEncoder;
import java.util.Optional;

import io.helidon.common.http.Parameters;

import org.junit.jupiter.api.Test;

import static java.nio.charset.StandardCharsets.US_ASCII;
Expand Down
4 changes: 4 additions & 0 deletions webserver/tyrus/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
<groupId>io.helidon.common</groupId>
<artifactId>helidon-common-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.common</groupId>
<artifactId>helidon-common-http</artifactId>
</dependency>
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021 Oracle and/or its affiliates.
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,7 +19,9 @@
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
Expand All @@ -31,6 +33,8 @@
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;

import io.helidon.common.http.Parameters;
import io.helidon.common.http.UriComponent;
import io.helidon.webserver.Handler;
import io.helidon.webserver.Routing;
import io.helidon.webserver.ServerRequest;
Expand Down Expand Up @@ -265,9 +269,14 @@ public void accept(ServerRequest req, ServerResponse res) {

LOGGER.fine("Initiating WebSocket handshake ...");

// Create Tyrus request context and copy request headers
// Create Tyrus request context, copying headers and query params
Map<String, String[]> paramsMap = new HashMap<>();
Parameters params = UriComponent.decodeQuery(req.uri().getRawQuery(), true);
params.toMap().forEach((key, value) -> paramsMap.put(key, value.toArray(new String[0])));
RequestContext requestContext = RequestContext.Builder.create()
.requestURI(URI.create(req.path().toString())) // excludes context path
.queryString(req.query())
.parameterMap(paramsMap)
.build();
req.headers().toMap().forEach((key, value) -> requestContext.getHeaders().put(key, value));

Expand Down
3 changes: 2 additions & 1 deletion webserver/tyrus/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -26,6 +26,7 @@
requires io.helidon.common.context;
requires io.helidon.common.mapper;
requires io.helidon.common.reactive;
requires io.helidon.common.http;

requires tyrus.core;
requires tyrus.server;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -62,6 +62,24 @@ private static void verifyRunningThread(Session session, Logger logger) throws I
}
}

/**
* Verify session includes expected query params.
*
* @param session Websocket session.
* @param logger A logger.
* @throws IOException Exception during close.
*/
private static void verifyQueryParams(Session session, Logger logger) throws IOException {
if (!"user=Helidon".equals(session.getQueryString())) {
logger.warning("Websocket session does not include required query params");
session.close();
}
if (!session.getRequestParameterMap().get("user").get(0).equals("Helidon")) {
logger.warning("Websocket session does not include required query parameter map");
session.close();
}
}

public static class ServerConfigurator extends ServerEndpointConfig.Configurator {

@Override
Expand All @@ -76,6 +94,7 @@ public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request,
public void onOpen(Session session) throws IOException {
LOGGER.info("OnOpen called");
verifyRunningThread(session, LOGGER);
verifyQueryParams(session, LOGGER);
if (!modifyHandshakeCalled.get()) {
session.close(); // unexpected
}
Expand All @@ -85,6 +104,7 @@ public void onOpen(Session session) throws IOException {
public void echo(Session session, String message) throws Exception {
LOGGER.info("Endpoint OnMessage called '" + message + "'");
verifyRunningThread(session, LOGGER);
verifyQueryParams(session, LOGGER);
if (!isDecoded(message)) {
throw new InternalError("Message has not been decoded");
}
Expand All @@ -101,6 +121,7 @@ public void onError(Throwable t) {
public void onClose(Session session) throws IOException {
LOGGER.info("OnClose called");
verifyRunningThread(session, LOGGER);
verifyQueryParams(session, LOGGER);
modifyHandshakeCalled.set(false);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,7 +36,7 @@ public static void startServer() throws Exception {
@Test
public void testEchoSingle() {
try {
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/echo");
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/echo?user=Helidon");
new EchoClient(uri).echo("One");
} catch (Exception e) {
fail("Unexpected exception " + e);
Expand All @@ -46,7 +46,7 @@ public void testEchoSingle() {
@Test
public void testEchoMultiple() {
try {
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/echo");
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/echo?user=Helidon");
new EchoClient(uri).echo("One", "Two", "Three");
} catch (Exception e) {
fail("Unexpected exception " + e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static void startServer() throws ExecutionException, InterruptedException, Timeo

@Test
void testJdkClient() throws ExecutionException, InterruptedException, TimeoutException {
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/echo");
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/echo?user=Helidon");
ClientListener listener = new ClientListener();

WebSocket webSocket = HttpClient.newHttpClient()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,7 +36,7 @@ public static void startServer() throws Exception {
@Test
public void testEcho() {
try {
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/echo");
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/echo?user=Helidon");
new EchoClient(uri).echo("One");
} catch (Exception e) {
fail("Unexpected exception " + e);
Expand All @@ -46,7 +46,7 @@ public void testEcho() {
@Test
public void testDoubleEcho() {
try {
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/doubleEcho");
URI uri = URI.create("ws://localhost:" + webServer().port() + "/tyrus/doubleEcho?user=Helidon");
new EchoClient(uri, (s1, s2) -> s2.equals(s1 + s1)).echo("One");
} catch (Exception e) {
fail("Unexpected exception " + e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021 Oracle and/or its affiliates.
* Copyright (c) 2017, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -33,6 +33,7 @@
import io.helidon.common.http.Http;
import io.helidon.common.http.MediaType;
import io.helidon.common.http.Parameters;
import io.helidon.common.http.UriComponent;
import io.helidon.common.reactive.Single;
import io.helidon.media.common.MessageBodyContext;
import io.helidon.media.common.MessageBodyReadableContent;
Expand Down

0 comments on commit 8c7949e

Please sign in to comment.