Allow POSTing with a URL not ending with '/' to jax-ws endpoints (#10710)

* #10699 allow POSTing with a URL not ending with '/' to jax-ws endpoints

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
Ludovic Orban 2023-10-17 14:18:29 +02:00 committed by GitHub
parent 4ed22a7a71
commit 674a1acf06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 133 additions and 1 deletions

View File

@ -11,6 +11,8 @@
<properties>
<bundle-symbolic-name>${project.groupId}.http.spi</bundle-symbolic-name>
<jacoco.skip>true</jacoco.skip>
<jakarta.ws.rs.api.version>3.1.0</jakarta.ws.rs.api.version>
<jakarta.xml.jaxws.impl.version>4.0.1</jakarta.xml.jaxws.impl.version>
<spotbugs.onlyAnalyze>org.eclipse.jetty.http.spi.*</spotbugs.onlyAnalyze>
</properties>
<dependencies>
@ -24,6 +26,18 @@
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>${jakarta.xml.jaxws.impl.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>${jakarta.ws.rs.api.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
@ -82,7 +96,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--add-opens java.base/jdk.internal.misc=ALL-UNNAMED</argLine>
<argLine>--add-opens java.base/jdk.internal.misc=ALL-UNNAMED
--add-reads org.eclipse.jetty.http.spi=org.eclipse.jetty.logging</argLine>
</configuration>
</plugin>
</plugins>

View File

@ -45,6 +45,9 @@ public class HttpSpiContextHandler extends ContextHandler
{
this._httpContext = httpContext;
this._httpHandler = httpHandler;
// The default jax-ws web server allows posting to URLs that do not end
// with a trailing '/'; allow it too to be a drop-in replacement.
setAllowNullPathInContext(true);
super.setHandler(new Handler.Abstract()
{
@Override

View File

@ -0,0 +1,109 @@
//
// ========================================================================
// Copyright (c) 1995 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.http.spi;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import jakarta.jws.WebMethod;
import jakarta.jws.WebService;
import jakarta.xml.ws.Endpoint;
import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.logging.StacklessLogging;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
public class JaxWsEndpointTest
{
private StacklessLogging stacklessLogging;
private String urlPrefix;
private Server server;
private HttpClient client;
@Test
public void testPostToURLWithoutTrailingSlash() throws Exception
{
Endpoint.publish(urlPrefix + "/add", new AddService());
ContentResponse response = client.newRequest(urlPrefix)
.method(HttpMethod.POST)
.path("/add")
.send();
assertThat(response.getStatus(), is(500));
assertThat(response.getContentAsString(), containsString("Couldn't create SOAP message due to exception"));
}
@WebService
public static class AddService
{
@WebMethod
public int add(int a, int b)
{
return a + b;
}
}
@BeforeEach
public void setUp() throws Exception
{
LoggingUtil.init();
stacklessLogging = new StacklessLogging(com.sun.xml.ws.transport.http.HttpAdapter.class);
int port;
try (ServerSocket serverSocket = new ServerSocket())
{
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress("localhost", 0));
port = serverSocket.getLocalPort();
urlPrefix = "http://localhost:" + port;
}
server = new Server(new DelegatingThreadPool(new QueuedThreadPool()));
ServerConnector connector = new ServerConnector(server);
connector.setPort(port);
server.addConnector(connector);
server.setHandler(new ContextHandlerCollection());
server.start();
JettyHttpServerProvider.setServer(server);
System.setProperty("com.sun.net.httpserver.HttpServerProvider", JettyHttpServerProvider.class.getName());
client = new HttpClient();
client.start();
}
@AfterEach
public void tearDown()
{
LifeCycle.stop(client);
LifeCycle.stop(server);
JettyHttpServerProvider.setServer(null);
System.clearProperty("com.sun.net.httpserver.HttpServerProvider");
stacklessLogging.close();
LoggingUtil.end();
}
}

View File

@ -26,4 +26,9 @@ public final class LoggingUtil
org.slf4j.bridge.SLF4JBridgeHandler.removeHandlersForRootLogger();
org.slf4j.bridge.SLF4JBridgeHandler.install();
}
public static void end()
{
org.slf4j.bridge.SLF4JBridgeHandler.uninstall();
}
}