diff --git a/NOTICE.md b/NOTICE.md
index 9ddb55c340..0846b571b5 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -96,7 +96,7 @@ KineticJS, v4.7.1
* Copyright: Eric Rowell
org.objectweb.asm Version 9.0
-* License: Modified BSD (http://asm.objectweb.org/license.html)
+* License: Modified BSD (https://asm.ow2.io/license.html)
* Copyright (c) 2000-2011 INRIA, France Telecom. All rights reserved.
org.osgi.core version 6.0.0
diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectionClosingStrategy.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectionClosingStrategy.java
index 8c248eae57..96c3ee0836 100644
--- a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectionClosingStrategy.java
+++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectionClosingStrategy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -63,12 +63,15 @@ void close(ClientRequest clientRequest, HttpUriRequest request, CloseableHttpRes
* Strategy that aborts Apache HttpRequests for the case of Chunked Stream, closes the stream, and response next.
*/
class GracefulClosingStrategy implements ApacheConnectionClosingStrategy {
+ private static final String UNIX_PROTOCOL = "unix";
+
static final GracefulClosingStrategy INSTANCE = new GracefulClosingStrategy();
@Override
public void close(ClientRequest clientRequest, HttpUriRequest request, CloseableHttpResponse response, InputStream stream)
throws IOException {
- if (response.getEntity() != null && response.getEntity().isChunked()) {
+ if (response.getEntity() != null && response.getEntity().isChunked()
+ && !request.getURI().getScheme().equals(UNIX_PROTOCOL)) {
request.abort();
}
try {
diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
index f45ae41ef5..dafd360849 100644
--- a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
+++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -509,7 +509,7 @@ public ClientResponse apply(final ClientRequest clientRequest) throws Processing
final HttpEntity entity = response.getEntity();
if (entity != null) {
- if (headers.get(HttpHeaders.CONTENT_LENGTH) == null) {
+ if (headers.get(HttpHeaders.CONTENT_LENGTH) == null && entity.getContentLength() >= 0) {
headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(entity.getContentLength()));
}
diff --git a/connectors/grizzly-connector/pom.xml b/connectors/grizzly-connector/pom.xml
index 670e7152ba..a9327a5488 100644
--- a/connectors/grizzly-connector/pom.xml
+++ b/connectors/grizzly-connector/pom.xml
@@ -1,7 +1,7 @@
+
+
+ 4.0.0
+
+
+ org.glassfish.jersey.tests.integration
+ project
+ 3.1.0-SNAPSHOT
+
+
+ jersey-4949
+ war
+ jersey-tests-integration-jersey-4949
+
+ Servlet integration test - JERSEY-4949 - Encoded Jetty Path
+
+
+
+ org.glassfish.jersey.containers
+ jersey-container-servlet-core
+
+
+ org.glassfish.jersey.test-framework.providers
+ jersey-test-framework-provider-external
+ test
+
+
+ org.glassfish.jersey.test-framework.providers
+ jersey-test-framework-provider-grizzly2
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+ org.eclipse.jetty
+ jetty-maven-plugin
+
+ 10
+
+ /c ntext
+
+
+
+
+
+
+
diff --git a/tests/integration/jersey-4949/src/main/java/org/glassfish/jersey/tests/integration/jersey4949/Issue4949Resource.java b/tests/integration/jersey-4949/src/main/java/org/glassfish/jersey/tests/integration/jersey4949/Issue4949Resource.java
new file mode 100644
index 0000000000..96bed00917
--- /dev/null
+++ b/tests/integration/jersey-4949/src/main/java/org/glassfish/jersey/tests/integration/jersey4949/Issue4949Resource.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.jersey4949;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.UriInfo;
+
+/**
+ * Test resource.
+ */
+@Path("/")
+public class Issue4949Resource {
+ public static final String PATH = "0.0.2%20-%20Market%20Data%20Import";
+ @GET
+ @Path(PATH)
+ public String get(@Context UriInfo uriInfo) {
+ return uriInfo.getRequestUri().toASCIIString();
+ }
+
+ @GET
+ @Path("echo")
+ public String echo(@Context UriInfo uriInfo) {
+ return uriInfo.getRequestUri().toASCIIString();
+ }
+}
diff --git a/tests/integration/jersey-4949/src/main/java/org/glassfish/jersey/tests/integration/jersey4949/Jersey4949.java b/tests/integration/jersey-4949/src/main/java/org/glassfish/jersey/tests/integration/jersey4949/Jersey4949.java
new file mode 100644
index 0000000000..6c625fc23e
--- /dev/null
+++ b/tests/integration/jersey-4949/src/main/java/org/glassfish/jersey/tests/integration/jersey4949/Jersey4949.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.jersey4949;
+
+import org.glassfish.jersey.server.ResourceConfig;
+
+/**
+ * JAX-RS application for the JERSEY-4949 reproducer test.
+ */
+public class Jersey4949 extends ResourceConfig {
+
+ public Jersey4949() {
+ register(Issue4949Resource.class);
+ }
+}
diff --git a/tests/integration/jersey-4949/src/main/webapp/WEB-INF/web.xml b/tests/integration/jersey-4949/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..32f1990a15
--- /dev/null
+++ b/tests/integration/jersey-4949/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+ jersey4949Servlet
+ org.glassfish.jersey.servlet.ServletContainer
+
+ jakarta.ws.rs.Application
+ org.glassfish.jersey.tests.integration.jersey4949.Jersey4949
+
+ 1
+
+
+ jersey4949Servlet
+ /A B/*
+
+
diff --git a/tests/integration/jersey-4949/src/test/java/org/glassfish/jersey/tests/integration/jersey4949/Jersey4949ITCase.java b/tests/integration/jersey-4949/src/test/java/org/glassfish/jersey/tests/integration/jersey4949/Jersey4949ITCase.java
new file mode 100644
index 0000000000..740f952167
--- /dev/null
+++ b/tests/integration/jersey-4949/src/test/java/org/glassfish/jersey/tests/integration/jersey4949/Jersey4949ITCase.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.jersey4949;
+
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.external.ExternalTestContainerFactory;
+import org.glassfish.jersey.test.spi.TestContainerException;
+import org.glassfish.jersey.test.spi.TestContainerFactory;
+
+import org.junit.Assert;
+import org.junit.Test;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * Reproducer tests for JERSEY-4949.
+ */
+public class Jersey4949ITCase extends JerseyTest {
+
+ private static final String CONTEXT_PATH = "c%20ntext";
+ private static final String SERVLET_PATH = "A%20B";
+
+ @Override
+ protected Application configure() {
+ return new Jersey4949();
+ }
+
+ @Override
+ protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
+ //return new org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory();
+ return new ExternalTestContainerFactory();
+ }
+
+ /**
+ * Reproducer method for JERSEY-4949.
+ */
+ @Test
+ public void testJersey4949Fix() {
+ try (Response response = target(CONTEXT_PATH).path(SERVLET_PATH).path(Issue4949Resource.PATH).request().get()) {
+ assertThat(response.getStatus(), is(200));
+
+ String entity = response.readEntity(String.class);
+ Assert.assertTrue(entity.contains(CONTEXT_PATH));
+ Assert.assertTrue(entity.contains(SERVLET_PATH));
+ Assert.assertTrue(entity.contains(Issue4949Resource.PATH));
+ }
+ }
+}
diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml
index c6e35a6204..19aa781494 100644
--- a/tests/integration/pom.xml
+++ b/tests/integration/pom.xml
@@ -1,7 +1,7 @@