diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java index dac81b63102..f943b1d2ed4 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java @@ -22,9 +22,11 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; @@ -46,18 +48,33 @@ import org.eclipse.jetty.util.TypeUtil; */ public class DigestAuthentication extends AbstractAuthentication { + private final Random random; private final String user; private final String password; - /** + /** Construct a DigestAuthentication with a {@link SecureRandom} nonce. * @param uri the URI to match for the authentication * @param realm the realm to match for the authentication * @param user the user that wants to authenticate * @param password the password of the user */ public DigestAuthentication(URI uri, String realm, String user, String password) + { + this(uri, realm, user, password, new SecureRandom()); + } + + /** + * @param uri the URI to match for the authentication + * @param realm the realm to match for the authentication + * @param user the user that wants to authenticate + * @param password the password of the user + * @param random the Random generator to use for nonces. + */ + public DigestAuthentication(URI uri, String realm, String user, String password, Random random) { super(uri, realm); + Objects.requireNonNull(random); + this.random = random; this.user = user; this.password = password; } @@ -216,7 +233,6 @@ public class DigestAuthentication extends AbstractAuthentication private String newClientNonce() { - Random random = new Random(); byte[] bytes = new byte[8]; random.nextBytes(bytes); return toHexString(bytes); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java index 8f40c1217ad..3cddb02d3ba 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java @@ -27,7 +27,6 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; -import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jetty.client.AsyncContentProvider; @@ -102,15 +101,10 @@ public class MultiPartContentProvider extends AbstractTypedContentProvider imple private static String makeBoundary() { - Random random = new Random(); StringBuilder builder = new StringBuilder("JettyHttpClientBoundary"); - int length = builder.length(); - while (builder.length() < length + 16) - { - long rnd = random.nextLong(); - builder.append(Long.toString(rnd < 0 ? -rnd : rnd, 36)); - } - builder.setLength(length + 16); + builder.append(Long.toString(System.identityHashCode(builder), 36)); + builder.append(Long.toString(System.identityHashCode(Thread.currentThread()), 36)); + builder.append(Long.toString(System.nanoTime(), 36)); return builder.toString(); } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java index 650bfe8ebbc..4e71516896b 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/OSGiWebappClassLoader.java @@ -129,9 +129,11 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe public Enumeration getResources(String name) throws IOException { Enumeration osgiUrls = _osgiBundleClassLoader.getResources(name); + if (osgiUrls != null && osgiUrls.hasMoreElements()) + return osgiUrls; + Enumeration urls = super.getResources(name); - List resources = toList(osgiUrls, urls); - return Collections.enumeration(resources); + return urls; } @Override diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index d0dbb744702..e21fd537871 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -24,6 +24,7 @@ jetty-osgi-boot-warurl jetty-osgi-httpservice test-jetty-osgi-webapp + test-jetty-osgi-webapp-resources test-jetty-osgi-context test-jetty-osgi-fragment test-jetty-osgi-server diff --git a/jetty-osgi/test-jetty-osgi-webapp-resources/pom.xml b/jetty-osgi/test-jetty-osgi-webapp-resources/pom.xml new file mode 100644 index 00000000000..82ae68e296e --- /dev/null +++ b/jetty-osgi/test-jetty-osgi-webapp-resources/pom.xml @@ -0,0 +1,79 @@ + + + + org.eclipse.jetty.osgi + jetty-osgi-project + 11.0.0-SNAPSHOT + + 4.0.0 + test-jetty-osgi-webapp-resources + OSGi Test :: Webapp With Resources + http://www.eclipse.org/jetty + war + + ${project.groupId}.webapp.resources + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-resources + validate + + copy-resources + + + ${basedir}/target/classes + + + src/main/resources + + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + war + + + !com.acme* + / + + + + + + maven-war-plugin + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + + org.apache.maven.plugins + maven-deploy-plugin + + + false + + + + + + + org.eclipse.jetty.toolchain + jetty-jakarta-servlet-api + provided + + + diff --git a/jetty-osgi/test-jetty-osgi-webapp-resources/src/main/java/com/acme/HelloWorld.java b/jetty-osgi/test-jetty-osgi-webapp-resources/src/main/java/com/acme/HelloWorld.java new file mode 100644 index 00000000000..7bfa08227dc --- /dev/null +++ b/jetty-osgi/test-jetty-osgi-webapp-resources/src/main/java/com/acme/HelloWorld.java @@ -0,0 +1,68 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://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: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package com.acme; + +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; +import java.util.Set; + +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * Dump Servlet Request. + */ +@SuppressWarnings("serial") +public class HelloWorld extends HttpServlet +{ + + @Override + public void init(ServletConfig config) throws ServletException + { + super.init(config); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + doGet(request, response); + } + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + response.setContentType("text/html"); + ServletOutputStream out = response.getOutputStream(); + out.println(""); + out.println("

Hello World

"); + + Enumeration resources = Thread.currentThread().getContextClassLoader().getResources("fake.properties"); + + while (resources.hasMoreElements()) + out.println(resources.nextElement().toString()); + + out.println(""); + out.flush(); + } +} diff --git a/jetty-osgi/test-jetty-osgi-webapp-resources/src/main/resources/fake.properties b/jetty-osgi/test-jetty-osgi-webapp-resources/src/main/resources/fake.properties new file mode 100644 index 00000000000..e69de29bb2d diff --git a/jetty-osgi/test-jetty-osgi-webapp-resources/src/main/webapp/WEB-INF/web.xml b/jetty-osgi/test-jetty-osgi-webapp-resources/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..90efb1dceac --- /dev/null +++ b/jetty-osgi/test-jetty-osgi-webapp-resources/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + WebApp With Resources + + + Hello + com.acme.HelloWorld + 1 + + + + Hello + /hello/* + + + + + diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 561789f1634..9870789cb21 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -38,6 +38,12 @@ pax-exam-container-forked ${pax.exam.version} test + + + biz.aQute.bnd + bndlib + + org.ops4j.pax.swissbox @@ -69,17 +75,6 @@ ${pax.url.version} test - - org.ops4j.pax.tinybundles - tinybundles - 3.0.0 - - - biz.aQute.bnd - bnd - - - org.ops4j.pax.url pax-url-wrap @@ -407,6 +402,13 @@ ${project.version} test + + org.eclipse.jetty.osgi + test-jetty-osgi-webapp-resources + ${project.version} + war + test + org.eclipse.jetty.osgi test-jetty-osgi-fragment @@ -564,6 +566,23 @@ + + maven-dependency-plugin + + + copy + process-test-resources + + copy-dependencies + + + + + test-jetty-osgi-webapp-resources + target + true + + org.apache.servicemix.tooling depends-maven-plugin diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml new file mode 100644 index 00000000000..1030e0d3f85 --- /dev/null +++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-http-boot-with-resources.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + boot.resources.port + + + + + + + + + + + diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiClasspathResources.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiClasspathResources.java new file mode 100644 index 00000000000..b247476b167 --- /dev/null +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiClasspathResources.java @@ -0,0 +1,154 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://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: +// the Apache License v2.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.osgi.test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import javax.inject.Inject; + +import aQute.bnd.osgi.Constants; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.http.HttpStatus; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.ops4j.pax.exam.Configuration; +import org.ops4j.pax.exam.CoreOptions; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.junit.PaxExam; +import org.ops4j.pax.tinybundles.core.TinyBundle; +import org.ops4j.pax.tinybundles.core.TinyBundles; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; +import static org.ops4j.pax.exam.CoreOptions.mavenBundle; +import static org.ops4j.pax.exam.CoreOptions.systemProperty; + +/** + * TestJettyOSGiClasspathResources + * + */ + +@RunWith(PaxExam.class) +public class TestJettyOSGiClasspathResources +{ + @Inject + BundleContext bundleContext = null; + + @Configuration + public static Option[] configure() + { + ArrayList