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 @@