diff --git a/VERSION.txt b/VERSION.txt index cec130a98e9..26aa117d822 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -40,6 +40,56 @@ jetty-12.0.1 - 29 August 2023 + 10411 Review deployment of Jetty Context XML files + 10416 EE9 Copies HttpFields in response +jetty-11.0.16 - 25 August 2023 + + 6140 Report total number of keys in SelectorManager + + 7091 Add SOCKS5 support + + 8405 Servlet 3.1 ReadListener.onAllDataRead() is called twice under h2 or + h2c if the server doesn't respond within 30s + + 8556 ServletContext.getSessionTimeout() incorrectly throws + IllegalStateException + + 8694 Make QuicServerConnector respect configured key store instances + + 8926 HttpClient GZIPContentDecoder should remove Content-Length and + Content-Encoding: gzip + + 9150 jetty-http-spi: Jetty's implementation of HttpExchange.setStreams + method faulty + + 9386 SSL reports deprecated setting, but ssl.ini still uses it + + 9397 HTTP/3 encryption configuration + + 9476 onCompleteFailure called multiple times + + 9524 InputStreamResponseListener's InputStream creates an exception on + close() + + 9554 Move (qpack/hpack) HuffmanDecoder / HuffmanEncoder / NBitInteger* to + common location + + 9682 RetainableByteBuffer buffer release bug in WebSocket + + 9685 Jetty doesn't set the date header on error responses + + 9720 Http2Session.streamIdleTimeout should permit being disabled from + AbstractHTTP2ServerConnectionFactory + + 9772 Improve Quiche certificates deployment + + 9777 CrossOriginFilter does not return Vary header on no-cors mode + + 9795 http3-server is leaking the Jetty logging service to web applications + + 9887 Deprecate CGI Servlet + + 9895 A MessageTooLargeException doesn't close a WebSocket connection + + 9947 Cannot invoke "org.eclipse.jetty.io.ManagedSelector.getTotalKeys()" + because "selector" is null + + 9990 Server rejects certain sizes of streamed request bodies + + 10066 Allow `SAXParserFactory` or `SAXParser` to be configured in Jetty's + `XmlParser` class + + 10086 Revisiting ProxyConfiguration.getProxies() + + 10105 Document that Request objects are not reusable + + 10120 OutOfMemoryError caused by CyclicTimeouts + + 10135 Websocket: Using PerMessageDeflateExtension and flush in batchMode + send FLUSH_FRAME to client. + + 10143 Startup fails due to IllegalArgumentException: Comparison method + violates its general contract + + 10145 WritePendingException over HTTP/2 tunnel + + 10160 Verify PROXY_AUTHENTICATION is sent to forward proxies + + 10211 NPE in ArrayByteBufferPool.findOldestEntry() + + 10312 Remove jetty-home-with-docs to eliminate build time cyclic + dependencies + + 10350 Support Java 21 virtual threads + + 10352 various cleanups in `HttpParser` + + 10388 Jetty10 inetaccess mod started error + + 10397 Iso88591StringBuilder.append seems to have a logic error + jetty-12.0.0 - 07 August 2023 + 8405 Servlet 3.1 ReadListener.onAllDataRead() is called twice under h2 or h2c if the server doesn't respond within 30s @@ -343,6 +393,58 @@ jetty-11.0.15 - 11 April 2023 + 9517 Jetty 10.0.14 uses wrong pathSpec for request + 9556 Password Util does not ask for password +jetty-10.0.16 - 25 August 2023 + + 6140 Report total number of keys in SelectorManager + + 7091 Add SOCKS5 support + + 8405 Servlet 3.1 ReadListener.onAllDataRead() is called twice under h2 or + h2c if the server doesn't respond within 30s + + 8556 ServletContext.getSessionTimeout() incorrectly throws + IllegalStateException + + 8694 Make QuicServerConnector respect configured key store instances + + 8926 HttpClient GZIPContentDecoder should remove Content-Length and + Content-Encoding: gzip + + 9150 jetty-http-spi: Jetty's implementation of HttpExchange.setStreams + method faulty + + 9386 SSL reports deprecated setting, but ssl.ini still uses it + + 9397 HTTP/3 encryption configuration + + 9476 onCompleteFailure called multiple times + + 9524 InputStreamResponseListener's InputStream creates an exception on + close() + + 9554 Move (qpack/hpack) HuffmanDecoder / HuffmanEncoder / NBitInteger* to + common location + + 9682 RetainableByteBuffer buffer release bug in WebSocket + + 9685 Jetty doesn't set the date header on error responses + + 9720 Http2Session.streamIdleTimeout should permit being disabled from + AbstractHTTP2ServerConnectionFactory + + 9772 Improve Quiche certificates deployment + + 9777 CrossOriginFilter does not return Vary header on no-cors mode + + 9795 http3-server is leaking the Jetty logging service to web applications + + 9887 Deprecate CGI Servlet + + 9895 A MessageTooLargeException doesn't close a WebSocket connection + + 9947 Cannot invoke "org.eclipse.jetty.io.ManagedSelector.getTotalKeys()" + because "selector" is null + + 9990 Server rejects certain sizes of streamed request bodies + + 10055 Deployment of static files does not work with --dry-run Jetty-12 + + 10066 Allow `SAXParserFactory` or `SAXParser` to be configured in Jetty's + `XmlParser` class + + 10086 Revisiting ProxyConfiguration.getProxies() + + 10105 Document that Request objects are not reusable + + 10120 OutOfMemoryError caused by CyclicTimeouts + + 10135 Websocket: Using PerMessageDeflateExtension and flush in batchMode + send FLUSH_FRAME to client. + + 10143 Startup fails due to IllegalArgumentException: Comparison method + violates its general contract + + 10145 WritePendingException over HTTP/2 tunnel + + 10160 Verify PROXY_AUTHENTICATION is sent to forward proxies + + 10211 NPE in ArrayByteBufferPool.findOldestEntry() + + 10271 jetty.sh does not stop jetty anymore + + 10312 Remove jetty-home-with-docs to eliminate build time cyclic + dependencies + + 10350 Support Java 21 virtual threads + + 10352 various cleanups in `HttpParser` + + 10388 Jetty10 inetaccess mod started error + + 10397 Iso88591StringBuilder.append seems to have a logic error + jetty-10.0.15 - 11 April 2023 + 6184 JEP-411 will deprecate/remove the SecurityManager from the JVM + 6483 Jetty http client SSL connectivity over CNTLM proxy fails @@ -1445,7 +1547,7 @@ jetty-11.0.0.beta1 - 10 July 2020 SETTINGS Frame. + 4903 Give better errors for non public Websocket Endpoints + 4904 WebsocketClient creates more connections than needed - + 4907 + + 4907 org.eclipse.jetty.websocket.tests.SuspendResumeTest#testSuspendAfterClose + 4920 Restore ability to delete sessions on stop + 4921 Quickstart run improperly runs dynamically added context initializers diff --git a/jetty-core/jetty-server/src/main/config/etc/jetty-state.xml b/jetty-core/jetty-server/src/main/config/etc/jetty-state.xml new file mode 100644 index 00000000000..f2ab5c98f80 --- /dev/null +++ b/jetty-core/jetty-server/src/main/config/etc/jetty-state.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jetty-core/jetty-server/src/main/config/modules/state.mod b/jetty-core/jetty-server/src/main/config/modules/state.mod new file mode 100644 index 00000000000..5a4e09de420 --- /dev/null +++ b/jetty-core/jetty-server/src/main/config/modules/state.mod @@ -0,0 +1,17 @@ +# DO NOT EDIT THIS FILE - See: https://eclipse.dev/jetty/documentation/ + +[description] +Creates and updates state file used by jetty.sh + +[tags] +start + +[depends] +server + +[xml] +etc/jetty-state.xml + +[ini-template] +## State file path +# jetty.state=${jetty.base}/jetty.state \ No newline at end of file diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/StateLifeCycleListener.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/StateLifeCycleListener.java new file mode 100644 index 00000000000..bf7fcdb2f3b --- /dev/null +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/StateLifeCycleListener.java @@ -0,0 +1,89 @@ +// +// ======================================================================== +// 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.server; + +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.eclipse.jetty.util.component.LifeCycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.nio.file.StandardOpenOption.APPEND; +import static java.nio.file.StandardOpenOption.CREATE; +import static java.nio.file.StandardOpenOption.WRITE; + +/** + * A LifeCycle Listener that writes state changes to a file. + *

This can be used with the jetty.sh script to wait for successful startup. + */ +public class StateLifeCycleListener implements LifeCycle.Listener +{ + private static final Logger LOG = LoggerFactory.getLogger(StateLifeCycleListener.class); + + private final Path _filename; + + public StateLifeCycleListener(String filename) + { + _filename = Paths.get(filename).toAbsolutePath(); + + if (LOG.isDebugEnabled()) + LOG.debug("State File: {}", _filename); + } + + private void writeState(String action, LifeCycle lifecycle) + { + try (Writer out = Files.newBufferedWriter(_filename, UTF_8, WRITE, CREATE, APPEND)) + { + out.append(action).append(" ").append(lifecycle.toString()).append("\n"); + } + catch (Exception e) + { + LOG.warn("Unable to write state", e); + } + } + + @Override + public void lifeCycleStarting(LifeCycle event) + { + writeState("STARTING", event); + } + + @Override + public void lifeCycleStarted(LifeCycle event) + { + writeState("STARTED", event); + } + + @Override + public void lifeCycleFailure(LifeCycle event, Throwable cause) + { + writeState("FAILED", event); + } + + @Override + public void lifeCycleStopping(LifeCycle event) + { + writeState("STOPPING", event); + } + + @Override + public void lifeCycleStopped(LifeCycle event) + { + writeState("STOPPED", event); + } +} diff --git a/jetty-core/jetty-util/src/main/config/etc/jetty-pid.xml b/jetty-core/jetty-util/src/main/config/etc/jetty-pid.xml new file mode 100644 index 00000000000..7ca3084a28c --- /dev/null +++ b/jetty-core/jetty-util/src/main/config/etc/jetty-pid.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/jetty-core/jetty-util/src/main/config/modules/pid.mod b/jetty-core/jetty-util/src/main/config/modules/pid.mod new file mode 100644 index 00000000000..3e08fc545a9 --- /dev/null +++ b/jetty-core/jetty-util/src/main/config/modules/pid.mod @@ -0,0 +1,19 @@ +# DO NOT EDIT THIS FILE - See: https://eclipse.dev/jetty/documentation/ + +[description] +Creates the PID file for the Jetty process + +[tags] +start + +[before] +server +threadpool +jvm + +[xml] +etc/jetty-pid.xml + +[ini-template] +## PID file path +# jetty.pid=${jetty.base}/jetty.pid \ No newline at end of file diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/PidFile.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/PidFile.java new file mode 100644 index 00000000000..8abaca626bc --- /dev/null +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/PidFile.java @@ -0,0 +1,83 @@ +// +// ======================================================================== +// 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.util; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.jetty.util.annotation.Name; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.nio.file.StandardOpenOption.CREATE; +import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; +import static java.nio.file.StandardOpenOption.WRITE; + +/** + * Create a PID file for the running process. + * + *

+ * Will register itself in a {@link Runtime#addShutdownHook(Thread)} + * to cleanup the PID file it created during normal JVM shutdown. + *

+ */ +public class PidFile extends Thread +{ + private static final Logger LOG = LoggerFactory.getLogger(PidFile.class); + private static final Set activeFiles = ConcurrentHashMap.newKeySet(); + + public static void create(@Name("file") String filename) throws IOException + { + Path pidFile = Paths.get(filename).toAbsolutePath(); + + if (activeFiles.add(pidFile)) + { + Runtime.getRuntime().addShutdownHook(new PidFile(pidFile)); + + if (Files.exists(pidFile)) + LOG.info("Overwriting existing PID file: {}", pidFile); + + // Create the PID file as soon as possible. + long pid = ProcessHandle.current().pid(); + Files.writeString(pidFile, Long.toString(pid), UTF_8, CREATE, WRITE, TRUNCATE_EXISTING); + if (LOG.isDebugEnabled()) + LOG.debug("PID file: {}", pidFile); + } + } + + private final Path pidFile; + + private PidFile(Path pidFile) + { + this.pidFile = pidFile; + } + + @Override + public void run() + { + try + { + Files.deleteIfExists(pidFile); + } + catch (Throwable t) + { + LOG.info("Unable to remove PID file: {}", pidFile, t); + } + } +} diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/FileNoticeLifeCycleListener.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/FileNoticeLifeCycleListener.java index 98b07afaf63..93ee1e16f82 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/FileNoticeLifeCycleListener.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/FileNoticeLifeCycleListener.java @@ -22,7 +22,9 @@ import org.slf4j.LoggerFactory; /** * A LifeCycle Listener that writes state changes to a file. *

This can be used with the jetty.sh script to wait for successful startup. + * @deprecated use {@code org.eclipse.jetty.server.StateLifeCycleListener} instead */ +@Deprecated public class FileNoticeLifeCycleListener implements LifeCycle.Listener { private static final Logger LOG = LoggerFactory.getLogger(FileNoticeLifeCycleListener.class); diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java index a73cda177c6..fe4ef9b81fd 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java @@ -1469,6 +1469,16 @@ public class Request implements HttpServletRequest _secure = secure; } + /** + *

Get the nanoTime at which the request arrived to a connector, obtained via {@link System#nanoTime()}. + * This method can be used when measuring latencies.

+ * @return The nanoTime at which the request was received/created in nanoseconds + */ + public long getBeginNanoTime() + { + return _metaData.getBeginNanoTime(); + } + @Override public boolean isUserInRole(String role) { diff --git a/jetty-home/src/main/resources/bin/jetty.sh b/jetty-home/src/main/resources/bin/jetty.sh index a3ac045fc98..08278d16128 100755 --- a/jetty-home/src/main/resources/bin/jetty.sh +++ b/jetty-home/src/main/resources/bin/jetty.sh @@ -330,7 +330,7 @@ CYGWIN*) JETTY_STATE="`cygpath -w $JETTY_STATE`";; esac -JETTY_ARGS=(${JETTY_ARGS[*]} "jetty.state=$JETTY_STATE") +JETTY_ARGS=(${JETTY_ARGS[*]} "jetty.state=$JETTY_STATE" "jetty.pid=$JETTY_PID") ################################################## # Get the list of config.xml files from jetty.conf @@ -457,6 +457,7 @@ case "$ACTION" in exit fi + # Startup from a service file if [ $UID -eq 0 ] && type start-stop-daemon > /dev/null 2>&1 then unset CH_USER @@ -482,6 +483,7 @@ case "$ACTION" in exit 1 fi + # Startup if switching users (not as a service, or from root) if [ -n "$JETTY_USER" ] && [ `whoami` != "$JETTY_USER" ] then unset SU_SHELL @@ -492,16 +494,14 @@ case "$ACTION" in touch "$JETTY_PID" chown "$JETTY_USER" "$JETTY_PID" - su - "$JETTY_USER" $SU_SHELL -c " cd \"$JETTY_BASE\" echo ${RUN_ARGS[*]} start-log-file=\"$JETTY_START_LOG\" | xargs ${JAVA} > /dev/null & - disown \$! - echo \$! > \"$JETTY_PID\"" + disown $(pgrep -P $!)" else + # Startup if not switching users echo ${RUN_ARGS[*]} | xargs ${JAVA} > /dev/null & - disown $! - echo $! > "$JETTY_PID" + disown $(pgrep -P $!) fi fi @@ -523,6 +523,7 @@ case "$ACTION" in stop) echo -n "Stopping Jetty: " + # Stop from a service file if [ $UID -eq 0 ] && type start-stop-daemon > /dev/null 2>&1; then start-stop-daemon -K -p"$JETTY_PID" -d"$JETTY_HOME" -a "$JAVA" -s HUP @@ -535,6 +536,7 @@ case "$ACTION" in sleep 1 done else + # Stop from a non-service path if [ ! -f "$JETTY_PID" ] ; then echo "ERROR: no pid found at $JETTY_PID" exit 1 diff --git a/jetty-home/src/main/resources/etc/jetty-started.xml b/jetty-home/src/main/resources/etc/jetty-started.xml deleted file mode 100644 index 11a2e151795..00000000000 --- a/jetty-home/src/main/resources/etc/jetty-started.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/jetty-home/src/main/resources/etc/jetty.conf b/jetty-home/src/main/resources/etc/jetty.conf index d4ceba4d2f3..1dfe2076ced 100644 --- a/jetty-home/src/main/resources/etc/jetty.conf +++ b/jetty-home/src/main/resources/etc/jetty.conf @@ -8,4 +8,4 @@ # Each line in this file becomes an argument to start.jar # in addition to those found in the start.ini file # ======================================================= -jetty-started.xml +--module=pid,state