Skip to content

Commit

Permalink
Merge pull request #7000 from eclipse/jetty-10.0.x-1087-WellKnown
Browse files Browse the repository at this point in the history
Issue #1087 - add module for a .well-known handler
  • Loading branch information
lachlan-roberts authored Nov 16, 2021
2 parents edaead4 + 1d88a52 commit dd06131
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//

[[og-module-alpn]]
==== Module `alpn`
===== Module `alpn`

The `alpn` module enables support for the ALPN negotiation mechanism of the TLS protocol.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// ========================================================================
// Copyright (c) 1995-2021 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
// ========================================================================
//

[[og-module-well-known]]
===== Module `well-known`

The `well-known` Jetty module creates a `ResourceHandler` deployed at the `/.well-known` context path which serves files from a directory.
By default, the directory created at `$JETTY_BASE/.well-known` is used, but it can be configured from `well-known.ini` to anywhere in the filesystem.
Note that the `.well-known` directory may be seen as a hidden directory by the filesystem.

The concept of well-known URIs has been defined in link:https://datatracker.ietf.org/doc/html/rfc5785[RFC5785].
This module can be used for things like the automatic renewal of link:https://letsencrypt.org/[Let's Encrypt] certificates.
See link:https://www.iana.org/assignments/well-known-uris/well-known-uris.xhtml[IANA Well-Known URIs] for more possible examples of how this can be used.

The module properties are:

----
include::{JETTY_HOME}/modules/well-known.mod[tags=documentation]
----
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ include::module-ssl-reload.adoc[]
include::module-test-keystore.adoc[]
include::module-threadpool.adoc[]
include::module-console-capture.adoc[]
include::module-well-known.adoc[]
24 changes: 24 additions & 0 deletions jetty-server/src/main/config/etc/well-known.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">

<Configure id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
<New id="WellKnownHandler" class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/.well-known</Set>
<Set name="handler">
<New class="org.eclipse.jetty.server.handler.ResourceHandler">
<Set name="resourceBase">
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.wellknown.dir" default=".well-known"/></Arg>
</Call>
</Set>
<Set name="directoriesListed">false</Set>
</New>
</Set>
</New>

<Call name="addHandler">
<Arg><Ref refid="WellKnownHandler"/></Arg>
</Call>
</Configure>

22 changes: 22 additions & 0 deletions jetty-server/src/main/config/modules/well-known.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[description]
Serve static files from a directory for the "/.well-known" context path.

[tags]
handler

[depend]
server

[xml]
etc/well-known.xml

[files]
.well-known/

[ini-template]
# tag::documentation[]
## Well Known Directory (relative to $JETTY_BASE if relative path, otherwise it is an absolute path).
# jetty.wellknown.dir=.well-known
# end::documentation[]
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
Expand All @@ -24,6 +25,7 @@
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

Expand All @@ -35,6 +37,7 @@
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.start.FS;
import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets;
import org.eclipse.jetty.unixsocket.server.UnixSocketConnector;
import org.eclipse.jetty.util.BlockingArrayQueue;
Expand Down Expand Up @@ -964,4 +967,53 @@ public void testModuleWithExecEmitsWarning() throws Exception
}
}
}

@Test
public void testWellKnownModule() throws Exception
{
String jettyVersion = System.getProperty("jettyVersion");
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
.jettyVersion(jettyVersion)
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
.build();
String[] args1 = {
"--approve-all-licenses",
"--add-modules=http,well-known"
};
try (JettyHomeTester.Run run1 = distribution.start(args1))
{
assertTrue(run1.awaitFor(10, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());

// Ensure .well-known directory exists.
Path wellKnown = distribution.getJettyBase().resolve(".well-known");
assertTrue(FS.exists(wellKnown));

// Write content to a file in the .well-known directory.
String testFileContent = "hello world " + UUID.randomUUID();
File testFile = wellKnown.resolve("testFile").toFile();
assertTrue(testFile.createNewFile());
testFile.deleteOnExit();
FileWriter fileWriter = new FileWriter(testFile);
fileWriter.write(testFileContent);
fileWriter.close();

int port = distribution.freePort();
String[] args2 = {
"jetty.http.port=" + port
//"jetty.server.dumpAfterStart=true"
};

try (JettyHomeTester.Run run2 = distribution.start(args2))
{
assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS));

// Test we can access the file in the .well-known directory.
startHttpClient();
ContentResponse response = client.GET("http://localhost:" + port + "/.well-known/testFile");
assertThat(response.getStatus(), is(HttpStatus.OK_200));
assertThat(response.getContentAsString(), is(testFileContent));
}
}
}
}

0 comments on commit dd06131

Please sign in to comment.