mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-22 09:09:01 +00:00
Add nullability annotations to module/spring-boot-undertow
See gh-46587
This commit is contained in:
+9
-10
@@ -25,13 +25,12 @@ import io.undertow.Undertow;
|
||||
import io.undertow.server.HttpHandler;
|
||||
import io.undertow.server.handlers.accesslog.AccessLogHandler;
|
||||
import io.undertow.server.handlers.accesslog.DefaultAccessLogReceiver;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.xnio.OptionMap;
|
||||
import org.xnio.Options;
|
||||
import org.xnio.Xnio;
|
||||
import org.xnio.XnioWorker;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An {@link HttpHandlerFactory} for an {@link AccessLogHandler}.
|
||||
*
|
||||
@@ -41,15 +40,16 @@ class AccessLogHttpHandlerFactory implements HttpHandlerFactory {
|
||||
|
||||
private final File directory;
|
||||
|
||||
private final String pattern;
|
||||
private final @Nullable String pattern;
|
||||
|
||||
private final String prefix;
|
||||
private final @Nullable String prefix;
|
||||
|
||||
private final String suffix;
|
||||
private final @Nullable String suffix;
|
||||
|
||||
private final boolean rotate;
|
||||
|
||||
AccessLogHttpHandlerFactory(File directory, String pattern, String prefix, String suffix, boolean rotate) {
|
||||
AccessLogHttpHandlerFactory(File directory, @Nullable String pattern, @Nullable String prefix,
|
||||
@Nullable String suffix, boolean rotate) {
|
||||
this.directory = directory;
|
||||
this.pattern = pattern;
|
||||
this.prefix = prefix;
|
||||
@@ -58,7 +58,7 @@ class AccessLogHttpHandlerFactory implements HttpHandlerFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHandler getHandler(HttpHandler next) {
|
||||
public HttpHandler getHandler(@Nullable HttpHandler next) {
|
||||
try {
|
||||
createAccessLogDirectoryIfNecessary();
|
||||
XnioWorker worker = createWorker();
|
||||
@@ -74,7 +74,6 @@ class AccessLogHttpHandlerFactory implements HttpHandlerFactory {
|
||||
}
|
||||
|
||||
private void createAccessLogDirectoryIfNecessary() {
|
||||
Assert.state(this.directory != null, "Access log directory is not set");
|
||||
if (!this.directory.isDirectory() && !this.directory.mkdirs()) {
|
||||
throw new IllegalStateException("Failed to create access log directory '" + this.directory + "'");
|
||||
}
|
||||
@@ -94,8 +93,8 @@ class AccessLogHttpHandlerFactory implements HttpHandlerFactory {
|
||||
|
||||
private final XnioWorker worker;
|
||||
|
||||
ClosableAccessLogHandler(HttpHandler next, XnioWorker worker, DefaultAccessLogReceiver accessLogReceiver,
|
||||
String formatString) {
|
||||
ClosableAccessLogHandler(@Nullable HttpHandler next, XnioWorker worker,
|
||||
DefaultAccessLogReceiver accessLogReceiver, String formatString) {
|
||||
super(next, accessLogReceiver, formatString, Undertow.class.getClassLoader());
|
||||
this.worker = worker;
|
||||
this.accessLogReceiver = accessLogReceiver;
|
||||
|
||||
+2
-1
@@ -29,6 +29,7 @@ import io.undertow.server.handlers.encoding.EncodingHandler;
|
||||
import io.undertow.server.handlers.encoding.GzipEncodingProvider;
|
||||
import io.undertow.util.Headers;
|
||||
import io.undertow.util.HttpString;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.web.server.Compression;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -51,7 +52,7 @@ class CompressionHttpHandlerFactory implements HttpHandlerFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHandler getHandler(HttpHandler next) {
|
||||
public @Nullable HttpHandler getHandler(@Nullable HttpHandler next) {
|
||||
if (!this.compression.getEnabled()) {
|
||||
return next;
|
||||
}
|
||||
|
||||
+9
-8
@@ -20,6 +20,7 @@ import java.io.File;
|
||||
import java.util.Collection;
|
||||
|
||||
import io.undertow.Undertow.Builder;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
|
||||
|
||||
@@ -50,49 +51,49 @@ public interface ConfigurableUndertowWebServerFactory extends ConfigurableWebSer
|
||||
* Set the buffer size.
|
||||
* @param bufferSize buffer size
|
||||
*/
|
||||
void setBufferSize(Integer bufferSize);
|
||||
void setBufferSize(@Nullable Integer bufferSize);
|
||||
|
||||
/**
|
||||
* Set the number of IO Threads.
|
||||
* @param ioThreads number of IO Threads
|
||||
*/
|
||||
void setIoThreads(Integer ioThreads);
|
||||
void setIoThreads(@Nullable Integer ioThreads);
|
||||
|
||||
/**
|
||||
* Set the number of Worker Threads.
|
||||
* @param workerThreads number of Worker Threads
|
||||
*/
|
||||
void setWorkerThreads(Integer workerThreads);
|
||||
void setWorkerThreads(@Nullable Integer workerThreads);
|
||||
|
||||
/**
|
||||
* Set whether direct buffers should be used.
|
||||
* @param useDirectBuffers whether direct buffers should be used
|
||||
*/
|
||||
void setUseDirectBuffers(Boolean useDirectBuffers);
|
||||
void setUseDirectBuffers(@Nullable Boolean useDirectBuffers);
|
||||
|
||||
/**
|
||||
* Set the access log directory.
|
||||
* @param accessLogDirectory access log directory
|
||||
*/
|
||||
void setAccessLogDirectory(File accessLogDirectory);
|
||||
void setAccessLogDirectory(@Nullable File accessLogDirectory);
|
||||
|
||||
/**
|
||||
* Set the access log pattern.
|
||||
* @param accessLogPattern access log pattern
|
||||
*/
|
||||
void setAccessLogPattern(String accessLogPattern);
|
||||
void setAccessLogPattern(@Nullable String accessLogPattern);
|
||||
|
||||
/**
|
||||
* Set the access log prefix.
|
||||
* @param accessLogPrefix log prefix
|
||||
*/
|
||||
void setAccessLogPrefix(String accessLogPrefix);
|
||||
void setAccessLogPrefix(@Nullable String accessLogPrefix);
|
||||
|
||||
/**
|
||||
* Set the access log suffix.
|
||||
* @param accessLogSuffix access log suffix
|
||||
*/
|
||||
void setAccessLogSuffix(String accessLogSuffix);
|
||||
void setAccessLogSuffix(@Nullable String accessLogSuffix);
|
||||
|
||||
/**
|
||||
* Set whether access logs are enabled.
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ import java.io.Closeable;
|
||||
|
||||
import io.undertow.server.HttpHandler;
|
||||
import io.undertow.server.handlers.GracefulShutdownHandler;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.undertow.servlet.UndertowServletWebServer;
|
||||
|
||||
@@ -43,6 +44,6 @@ public interface HttpHandlerFactory {
|
||||
* @param next the next handler in the chain
|
||||
* @return the new HTTP handler instance
|
||||
*/
|
||||
HttpHandler getHandler(HttpHandler next);
|
||||
@Nullable HttpHandler getHandler(@Nullable HttpHandler next);
|
||||
|
||||
}
|
||||
|
||||
+4
-3
@@ -24,6 +24,7 @@ import javax.net.ssl.SSLContext;
|
||||
import io.undertow.Undertow;
|
||||
import io.undertow.protocols.ssl.SNIContextMatcher;
|
||||
import io.undertow.protocols.ssl.SNISSLContext;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.xnio.Options;
|
||||
import org.xnio.Sequence;
|
||||
import org.xnio.SslClientAuthMode;
|
||||
@@ -44,15 +45,15 @@ class SslBuilderCustomizer implements UndertowBuilderCustomizer {
|
||||
|
||||
private final int port;
|
||||
|
||||
private final InetAddress address;
|
||||
private final @Nullable InetAddress address;
|
||||
|
||||
private final ClientAuth clientAuth;
|
||||
private final @Nullable ClientAuth clientAuth;
|
||||
|
||||
private final SslBundle sslBundle;
|
||||
|
||||
private final Map<String, SslBundle> serverNameSslBundles;
|
||||
|
||||
SslBuilderCustomizer(int port, InetAddress address, ClientAuth clientAuth, SslBundle sslBundle,
|
||||
SslBuilderCustomizer(int port, @Nullable InetAddress address, @Nullable ClientAuth clientAuth, SslBundle sslBundle,
|
||||
Map<String, SslBundle> serverNameSslBundles) {
|
||||
this.port = port;
|
||||
this.address = address;
|
||||
|
||||
+52
-23
@@ -32,6 +32,7 @@ import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.server.handlers.GracefulShutdownHandler;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.xnio.channels.BoundChannel;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
@@ -61,7 +62,7 @@ public class UndertowWebServer implements WebServer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(UndertowWebServer.class);
|
||||
|
||||
private final AtomicReference<GracefulShutdownCallback> gracefulShutdownCallback = new AtomicReference<>();
|
||||
private final AtomicReference<@Nullable GracefulShutdownCallback> gracefulShutdownCallback = new AtomicReference<>();
|
||||
|
||||
private final Object monitor = new Object();
|
||||
|
||||
@@ -71,13 +72,13 @@ public class UndertowWebServer implements WebServer {
|
||||
|
||||
private final boolean autoStart;
|
||||
|
||||
private Undertow undertow;
|
||||
private @Nullable Undertow undertow;
|
||||
|
||||
private volatile boolean started = false;
|
||||
|
||||
private volatile GracefulShutdownHandler gracefulShutdown;
|
||||
private volatile @Nullable GracefulShutdownHandler gracefulShutdown;
|
||||
|
||||
private volatile List<Closeable> closeables;
|
||||
private volatile @Nullable List<Closeable> closeables;
|
||||
|
||||
/**
|
||||
* Create a new {@link UndertowWebServer} instance.
|
||||
@@ -142,6 +143,7 @@ public class UndertowWebServer implements WebServer {
|
||||
try {
|
||||
if (this.undertow != null) {
|
||||
this.undertow.stop();
|
||||
Assert.state(this.closeables != null, "'closeables' must not be null");
|
||||
this.closeables.forEach(this::closeSilently);
|
||||
}
|
||||
}
|
||||
@@ -167,11 +169,12 @@ public class UndertowWebServer implements WebServer {
|
||||
return this.builder.build();
|
||||
}
|
||||
|
||||
protected HttpHandler createHttpHandler() {
|
||||
protected @Nullable HttpHandler createHttpHandler() {
|
||||
HttpHandler handler = null;
|
||||
for (HttpHandlerFactory factory : this.httpHandlerFactories) {
|
||||
handler = factory.getHandler(handler);
|
||||
if (handler instanceof Closeable closeable) {
|
||||
Assert.state(this.closeables != null, "'closeables' must not be null");
|
||||
this.closeables.add(closeable);
|
||||
}
|
||||
if (handler instanceof GracefulShutdownHandler shutdownHandler) {
|
||||
@@ -220,11 +223,14 @@ public class UndertowWebServer implements WebServer {
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<BoundChannel> extractChannels() {
|
||||
Field channelsField = ReflectionUtils.findField(Undertow.class, "channels");
|
||||
Assert.state(channelsField != null, "'channelsField' must not be null");
|
||||
ReflectionUtils.makeAccessible(channelsField);
|
||||
return (List<BoundChannel>) ReflectionUtils.getField(channelsField, this.undertow);
|
||||
List<BoundChannel> channels = (List<BoundChannel>) ReflectionUtils.getField(channelsField, this.undertow);
|
||||
Assert.state(channels != null, "'channels' must not be null");
|
||||
return channels;
|
||||
}
|
||||
|
||||
private UndertowWebServer.Port getPortFromChannel(BoundChannel channel) {
|
||||
private UndertowWebServer.@Nullable Port getPortFromChannel(BoundChannel channel) {
|
||||
SocketAddress socketAddress = channel.getLocalAddress();
|
||||
if (socketAddress instanceof InetSocketAddress inetSocketAddress) {
|
||||
Field sslField = ReflectionUtils.findField(channel.getClass(), "ssl");
|
||||
@@ -253,20 +259,37 @@ public class UndertowWebServer implements WebServer {
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Object> extractListeners() {
|
||||
Field listenersField = ReflectionUtils.findField(Undertow.class, "listeners");
|
||||
Assert.state(listenersField != null, "'listenersField' must not be null");
|
||||
ReflectionUtils.makeAccessible(listenersField);
|
||||
return (List<Object>) ReflectionUtils.getField(listenersField, this.undertow);
|
||||
List<Object> listeners = (List<Object>) ReflectionUtils.getField(listenersField, this.undertow);
|
||||
Assert.state(listeners != null, "'listeners' must not be null");
|
||||
return listeners;
|
||||
}
|
||||
|
||||
private UndertowWebServer.Port getPortFromListener(Object listener) {
|
||||
Field typeField = ReflectionUtils.findField(listener.getClass(), "type");
|
||||
ReflectionUtils.makeAccessible(typeField);
|
||||
String protocol = ReflectionUtils.getField(typeField, listener).toString();
|
||||
Assert.state(typeField != null, "'typeField' must not be null");
|
||||
String protocol = getProtocol(listener, typeField);
|
||||
Field portField = ReflectionUtils.findField(listener.getClass(), "port");
|
||||
ReflectionUtils.makeAccessible(portField);
|
||||
int port = (Integer) ReflectionUtils.getField(portField, listener);
|
||||
Assert.state(portField != null, "'portField' must not be null");
|
||||
int port = getPort(listener, portField);
|
||||
return new UndertowWebServer.Port(port, protocol);
|
||||
}
|
||||
|
||||
private static Integer getPort(Object listener, Field portField) {
|
||||
ReflectionUtils.makeAccessible(portField);
|
||||
Integer value = (Integer) ReflectionUtils.getField(portField, listener);
|
||||
Assert.state(value != null, "'value' must not be null");
|
||||
return value;
|
||||
}
|
||||
|
||||
private String getProtocol(Object listener, Field typeField) {
|
||||
ReflectionUtils.makeAccessible(typeField);
|
||||
Object value = ReflectionUtils.getField(typeField, listener);
|
||||
Assert.state(value != null, "'value' must not be null");
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws WebServerException {
|
||||
synchronized (this.monitor) {
|
||||
@@ -278,9 +301,12 @@ public class UndertowWebServer implements WebServer {
|
||||
notifyGracefulCallback(false);
|
||||
}
|
||||
try {
|
||||
this.undertow.stop();
|
||||
for (Closeable closeable : this.closeables) {
|
||||
closeable.close();
|
||||
if (this.undertow != null) {
|
||||
this.undertow.stop();
|
||||
Assert.state(this.closeables != null, "'closeables' must not be null");
|
||||
for (Closeable closeable : this.closeables) {
|
||||
closeable.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
@@ -304,7 +330,7 @@ public class UndertowWebServer implements WebServer {
|
||||
* @return the Undertow server or {@code null} if the server hasn't been started yet
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public Undertow getUndertow() {
|
||||
public @Nullable Undertow getUndertow() {
|
||||
return this.undertow;
|
||||
}
|
||||
|
||||
@@ -396,27 +422,30 @@ public class UndertowWebServer implements WebServer {
|
||||
*/
|
||||
private static final class CloseableHttpHandlerFactory implements HttpHandlerFactory {
|
||||
|
||||
private final Closeable closeable;
|
||||
private final @Nullable Closeable closeable;
|
||||
|
||||
private CloseableHttpHandlerFactory(Closeable closeable) {
|
||||
private CloseableHttpHandlerFactory(@Nullable Closeable closeable) {
|
||||
this.closeable = closeable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHandler getHandler(HttpHandler next) {
|
||||
if (this.closeable == null) {
|
||||
public @Nullable HttpHandler getHandler(@Nullable HttpHandler next) {
|
||||
Closeable closeable = this.closeable;
|
||||
if (closeable == null) {
|
||||
return next;
|
||||
}
|
||||
return new CloseableHttpHandler() {
|
||||
|
||||
@Override
|
||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
||||
next.handleRequest(exchange);
|
||||
if (next != null) {
|
||||
next.handleRequest(exchange);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
CloseableHttpHandlerFactory.this.closeable.close();
|
||||
closeable.close();
|
||||
}
|
||||
|
||||
};
|
||||
@@ -438,7 +467,7 @@ public class UndertowWebServer implements WebServer {
|
||||
static class UndertowWebServerRuntimeHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
|
||||
hints.reflection()
|
||||
.registerTypeIfPresent(classLoader, "io.undertow.Undertow",
|
||||
(hint) -> hint.withField("listeners").withField("channels"));
|
||||
|
||||
+22
-19
@@ -31,6 +31,7 @@ import io.undertow.Handlers;
|
||||
import io.undertow.Undertow;
|
||||
import io.undertow.Undertow.Builder;
|
||||
import io.undertow.UndertowOptions;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.ssl.SslBundle;
|
||||
import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory;
|
||||
@@ -52,21 +53,21 @@ public abstract class UndertowWebServerFactory extends AbstractConfigurableWebSe
|
||||
|
||||
private Set<UndertowBuilderCustomizer> builderCustomizers = new LinkedHashSet<>();
|
||||
|
||||
private Integer bufferSize;
|
||||
private @Nullable Integer bufferSize;
|
||||
|
||||
private Integer ioThreads;
|
||||
private @Nullable Integer ioThreads;
|
||||
|
||||
private Integer workerThreads;
|
||||
private @Nullable Integer workerThreads;
|
||||
|
||||
private Boolean directBuffers;
|
||||
private @Nullable Boolean directBuffers;
|
||||
|
||||
private File accessLogDirectory;
|
||||
private @Nullable File accessLogDirectory;
|
||||
|
||||
private String accessLogPattern;
|
||||
private @Nullable String accessLogPattern;
|
||||
|
||||
private String accessLogPrefix;
|
||||
private @Nullable String accessLogPrefix;
|
||||
|
||||
private String accessLogSuffix;
|
||||
private @Nullable String accessLogSuffix;
|
||||
|
||||
private boolean accessLogEnabled;
|
||||
|
||||
@@ -98,46 +99,46 @@ public abstract class UndertowWebServerFactory extends AbstractConfigurableWebSe
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBufferSize(Integer bufferSize) {
|
||||
public void setBufferSize(@Nullable Integer bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIoThreads(Integer ioThreads) {
|
||||
public void setIoThreads(@Nullable Integer ioThreads) {
|
||||
this.ioThreads = ioThreads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWorkerThreads(Integer workerThreads) {
|
||||
public void setWorkerThreads(@Nullable Integer workerThreads) {
|
||||
this.workerThreads = workerThreads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUseDirectBuffers(Boolean directBuffers) {
|
||||
public void setUseDirectBuffers(@Nullable Boolean directBuffers) {
|
||||
this.directBuffers = directBuffers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessLogDirectory(File accessLogDirectory) {
|
||||
public void setAccessLogDirectory(@Nullable File accessLogDirectory) {
|
||||
this.accessLogDirectory = accessLogDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessLogPattern(String accessLogPattern) {
|
||||
public void setAccessLogPattern(@Nullable String accessLogPattern) {
|
||||
this.accessLogPattern = accessLogPattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessLogPrefix(String accessLogPrefix) {
|
||||
public void setAccessLogPrefix(@Nullable String accessLogPrefix) {
|
||||
this.accessLogPrefix = accessLogPrefix;
|
||||
}
|
||||
|
||||
public String getAccessLogPrefix() {
|
||||
public @Nullable String getAccessLogPrefix() {
|
||||
return this.accessLogPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccessLogSuffix(String accessLogSuffix) {
|
||||
public void setAccessLogSuffix(@Nullable String accessLogSuffix) {
|
||||
this.accessLogSuffix = accessLogSuffix;
|
||||
}
|
||||
|
||||
@@ -207,14 +208,16 @@ public abstract class UndertowWebServerFactory extends AbstractConfigurableWebSe
|
||||
this.useForwardHeaders, webServerFactory.getServerHeader(), webServerFactory.getShutdown(),
|
||||
initialHttpHandlerFactories);
|
||||
if (isAccessLogEnabled()) {
|
||||
Assert.state(this.accessLogDirectory != null, "Access log directory is not set");
|
||||
factories.add(new AccessLogHttpHandlerFactory(this.accessLogDirectory, this.accessLogPattern,
|
||||
this.accessLogPrefix, this.accessLogSuffix, this.accessLogRotate));
|
||||
}
|
||||
return factories;
|
||||
}
|
||||
|
||||
static List<HttpHandlerFactory> createHttpHandlerFactories(Compression compression, boolean useForwardHeaders,
|
||||
String serverHeader, Shutdown shutdown, HttpHandlerFactory... initialHttpHandlerFactories) {
|
||||
static List<HttpHandlerFactory> createHttpHandlerFactories(@Nullable Compression compression,
|
||||
boolean useForwardHeaders, @Nullable String serverHeader, Shutdown shutdown,
|
||||
HttpHandlerFactory... initialHttpHandlerFactories) {
|
||||
List<HttpHandlerFactory> factories = new ArrayList<>(Arrays.asList(initialHttpHandlerFactories));
|
||||
if (compression != null && compression.getEnabled()) {
|
||||
factories.add(new CompressionHttpHandlerFactory(compression));
|
||||
|
||||
+19
-18
@@ -24,6 +24,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.undertow.UndertowOptions;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
@@ -69,13 +70,13 @@ public class UndertowServerProperties {
|
||||
* Size of each buffer. The default is derived from the maximum amount of memory that
|
||||
* is available to the JVM.
|
||||
*/
|
||||
private DataSize bufferSize;
|
||||
private @Nullable DataSize bufferSize;
|
||||
|
||||
/**
|
||||
* Whether to allocate buffers outside the Java heap. The default is derived from the
|
||||
* maximum amount of memory that is available to the JVM.
|
||||
*/
|
||||
private Boolean directBuffers;
|
||||
private @Nullable Boolean directBuffers;
|
||||
|
||||
/**
|
||||
* Whether servlet filters should be initialized on startup.
|
||||
@@ -106,7 +107,7 @@ public class UndertowServerProperties {
|
||||
* enable this if you have a legacy application that requires it. When set,
|
||||
* server.undertow.allow-encoded-slash has no effect.
|
||||
*/
|
||||
private Boolean decodeSlash;
|
||||
private @Nullable Boolean decodeSlash;
|
||||
|
||||
/**
|
||||
* Whether the URL should be decoded. When disabled, percent-encoded characters in the
|
||||
@@ -129,7 +130,7 @@ public class UndertowServerProperties {
|
||||
* Amount of time a connection can sit idle without processing a request, before it is
|
||||
* closed by the server.
|
||||
*/
|
||||
private Duration noRequestTimeout;
|
||||
private @Nullable Duration noRequestTimeout;
|
||||
|
||||
/**
|
||||
* Whether to preserve the path of a request when it is forwarded.
|
||||
@@ -153,19 +154,19 @@ public class UndertowServerProperties {
|
||||
this.maxHttpPostSize = maxHttpPostSize;
|
||||
}
|
||||
|
||||
public DataSize getBufferSize() {
|
||||
public @Nullable DataSize getBufferSize() {
|
||||
return this.bufferSize;
|
||||
}
|
||||
|
||||
public void setBufferSize(DataSize bufferSize) {
|
||||
public void setBufferSize(@Nullable DataSize bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public Boolean getDirectBuffers() {
|
||||
public @Nullable Boolean getDirectBuffers() {
|
||||
return this.directBuffers;
|
||||
}
|
||||
|
||||
public void setDirectBuffers(Boolean directBuffers) {
|
||||
public void setDirectBuffers(@Nullable Boolean directBuffers) {
|
||||
this.directBuffers = directBuffers;
|
||||
}
|
||||
|
||||
@@ -201,11 +202,11 @@ public class UndertowServerProperties {
|
||||
this.maxCookies = maxCookies;
|
||||
}
|
||||
|
||||
public Boolean getDecodeSlash() {
|
||||
public @Nullable Boolean getDecodeSlash() {
|
||||
return this.decodeSlash;
|
||||
}
|
||||
|
||||
public void setDecodeSlash(Boolean decodeSlash) {
|
||||
public void setDecodeSlash(@Nullable Boolean decodeSlash) {
|
||||
this.decodeSlash = decodeSlash;
|
||||
}
|
||||
|
||||
@@ -233,11 +234,11 @@ public class UndertowServerProperties {
|
||||
this.alwaysSetKeepAlive = alwaysSetKeepAlive;
|
||||
}
|
||||
|
||||
public Duration getNoRequestTimeout() {
|
||||
public @Nullable Duration getNoRequestTimeout() {
|
||||
return this.noRequestTimeout;
|
||||
}
|
||||
|
||||
public void setNoRequestTimeout(Duration noRequestTimeout) {
|
||||
public void setNoRequestTimeout(@Nullable Duration noRequestTimeout) {
|
||||
this.noRequestTimeout = noRequestTimeout;
|
||||
}
|
||||
|
||||
@@ -355,26 +356,26 @@ public class UndertowServerProperties {
|
||||
* Number of I/O threads to create for the worker. The default is derived from the
|
||||
* number of available processors.
|
||||
*/
|
||||
private Integer io;
|
||||
private @Nullable Integer io;
|
||||
|
||||
/**
|
||||
* Number of worker threads. The default is 8 times the number of I/O threads.
|
||||
*/
|
||||
private Integer worker;
|
||||
private @Nullable Integer worker;
|
||||
|
||||
public Integer getIo() {
|
||||
public @Nullable Integer getIo() {
|
||||
return this.io;
|
||||
}
|
||||
|
||||
public void setIo(Integer io) {
|
||||
public void setIo(@Nullable Integer io) {
|
||||
this.io = io;
|
||||
}
|
||||
|
||||
public Integer getWorker() {
|
||||
public @Nullable Integer getWorker() {
|
||||
return this.worker;
|
||||
}
|
||||
|
||||
public void setWorker(Integer worker) {
|
||||
public void setWorker(@Nullable Integer worker) {
|
||||
this.worker = worker;
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -18,6 +18,8 @@ package org.springframework.boot.undertow.autoconfigure.actuate.web.server;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.AccessLogCustomizer;
|
||||
import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory;
|
||||
|
||||
@@ -29,10 +31,10 @@ import org.springframework.boot.undertow.ConfigurableUndertowWebServerFactory;
|
||||
*/
|
||||
class UndertowAccessLogCustomizer<T extends ConfigurableUndertowWebServerFactory> extends AccessLogCustomizer<T> {
|
||||
|
||||
private final Function<T, String> accessLogPrefixExtractor;
|
||||
private final Function<T, @Nullable String> accessLogPrefixExtractor;
|
||||
|
||||
UndertowAccessLogCustomizer(UndertowManagementServerProperties properties,
|
||||
Function<T, String> accessLogPrefixExtractor) {
|
||||
Function<T, @Nullable String> accessLogPrefixExtractor) {
|
||||
super(properties.getAccesslog().getPrefix());
|
||||
this.accessLogPrefixExtractor = accessLogPrefixExtractor;
|
||||
}
|
||||
|
||||
+3
@@ -17,4 +17,7 @@
|
||||
/**
|
||||
* Actuator Undertow actuator web concerns.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.undertow.autoconfigure.actuate.web.server;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
+3
@@ -18,4 +18,7 @@
|
||||
* Classes related to the auto-configuration of a servlet or reactive web server using
|
||||
* Undertow.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.undertow.autoconfigure;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
+3
@@ -17,4 +17,7 @@
|
||||
/**
|
||||
* Classes related to the auto-configuration of a reactive web server using Undertow.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.undertow.autoconfigure.reactive;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
+3
@@ -17,4 +17,7 @@
|
||||
/**
|
||||
* Classes related to the auto-configuration of a servlet web server using Undertow.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.undertow.autoconfigure.servlet;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
+3
@@ -20,4 +20,7 @@
|
||||
* @see org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory
|
||||
* @see org.springframework.boot.undertow.reactive.UndertowReactiveWebServerFactory
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.undertow;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
+3
@@ -17,4 +17,7 @@
|
||||
/**
|
||||
* Reactive web server implementation backed by Undertow.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.undertow.reactive;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ import io.undertow.UndertowMessages;
|
||||
import io.undertow.server.handlers.resource.Resource;
|
||||
import io.undertow.server.handlers.resource.ResourceChangeListener;
|
||||
import io.undertow.server.handlers.resource.ResourceManager;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A {@link ResourceManager} that delegates to multiple {@code ResourceManager} instances.
|
||||
@@ -46,7 +47,7 @@ class CompositeResourceManager implements ResourceManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource(String path) throws IOException {
|
||||
public @Nullable Resource getResource(String path) throws IOException {
|
||||
for (ResourceManager resourceManager : this.resourceManagers) {
|
||||
Resource resource = resourceManager.getResource(path);
|
||||
if (resource != null) {
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ import io.undertow.server.HttpHandler;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.servlet.api.DeploymentManager;
|
||||
import jakarta.servlet.ServletException;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.undertow.HttpHandlerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -42,7 +43,7 @@ class DeploymentManagerHttpHandlerFactory implements HttpHandlerFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHandler getHandler(HttpHandler next) {
|
||||
public @Nullable HttpHandler getHandler(@Nullable HttpHandler next) {
|
||||
Assert.state(next == null, "DeploymentManagerHttpHandlerFactory must be first");
|
||||
return new DeploymentManagerHandler(this.deploymentManager);
|
||||
}
|
||||
|
||||
+3
-1
@@ -29,6 +29,7 @@ import java.util.Map;
|
||||
|
||||
import io.undertow.servlet.UndertowServletLogger;
|
||||
import io.undertow.servlet.api.SessionPersistenceManager;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.ConfigurableObjectInputStream;
|
||||
|
||||
@@ -70,7 +71,8 @@ class FileSessionPersistence implements SessionPersistenceManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, PersistentSession> loadSessionAttributes(String deploymentName, final ClassLoader classLoader) {
|
||||
public @Nullable Map<String, PersistentSession> loadSessionAttributes(String deploymentName,
|
||||
final ClassLoader classLoader) {
|
||||
try {
|
||||
File file = getSessionFile(deploymentName);
|
||||
if (file.exists()) {
|
||||
|
||||
+2
-1
@@ -26,6 +26,7 @@ import io.undertow.server.handlers.resource.Resource;
|
||||
import io.undertow.server.handlers.resource.ResourceChangeListener;
|
||||
import io.undertow.server.handlers.resource.ResourceManager;
|
||||
import io.undertow.server.handlers.resource.URLResource;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -49,7 +50,7 @@ class JarResourceManager implements ResourceManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource(String path) throws IOException {
|
||||
public @Nullable Resource getResource(String path) throws IOException {
|
||||
URL url = new URL("jar:" + this.jarPath + "!" + (path.startsWith("/") ? path : "/" + path));
|
||||
URLResource resource = new URLResource(url, path);
|
||||
if (StringUtils.hasText(path) && !"/".equals(path) && resource.getContentLength() < 0) {
|
||||
|
||||
+5
-4
@@ -20,6 +20,7 @@ import io.undertow.Handlers;
|
||||
import io.undertow.Undertow.Builder;
|
||||
import io.undertow.server.HttpHandler;
|
||||
import io.undertow.servlet.api.DeploymentManager;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.undertow.HttpHandlerFactory;
|
||||
import org.springframework.boot.undertow.UndertowWebServer;
|
||||
@@ -43,7 +44,7 @@ public class UndertowServletWebServer extends UndertowWebServer {
|
||||
|
||||
private final String contextPath;
|
||||
|
||||
private final DeploymentManager manager;
|
||||
private final @Nullable DeploymentManager manager;
|
||||
|
||||
/**
|
||||
* Create a new {@link UndertowServletWebServer} instance.
|
||||
@@ -60,7 +61,7 @@ public class UndertowServletWebServer extends UndertowWebServer {
|
||||
this.manager = findManager(httpHandlerFactories);
|
||||
}
|
||||
|
||||
private DeploymentManager findManager(Iterable<HttpHandlerFactory> httpHandlerFactories) {
|
||||
private @Nullable DeploymentManager findManager(Iterable<HttpHandlerFactory> httpHandlerFactories) {
|
||||
for (HttpHandlerFactory httpHandlerFactory : httpHandlerFactories) {
|
||||
if (httpHandlerFactory instanceof DeploymentManagerHttpHandlerFactory deploymentManagerFactory) {
|
||||
return deploymentManagerFactory.getDeploymentManager();
|
||||
@@ -70,7 +71,7 @@ public class UndertowServletWebServer extends UndertowWebServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpHandler createHttpHandler() {
|
||||
protected @Nullable HttpHandler createHttpHandler() {
|
||||
HttpHandler handler = super.createHttpHandler();
|
||||
if (StringUtils.hasLength(this.contextPath)) {
|
||||
handler = Handlers.path().addPrefixPath(this.contextPath, handler);
|
||||
@@ -88,7 +89,7 @@ public class UndertowServletWebServer extends UndertowWebServer {
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
public DeploymentManager getDeploymentManager() {
|
||||
public @Nullable DeploymentManager getDeploymentManager() {
|
||||
return this.manager;
|
||||
}
|
||||
|
||||
|
||||
+18
-12
@@ -61,6 +61,7 @@ import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.ServletException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.boot.undertow.HttpHandlerFactory;
|
||||
@@ -110,6 +111,7 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
|
||||
private Set<UndertowDeploymentInfoCustomizer> deploymentInfoCustomizers = new LinkedHashSet<>();
|
||||
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
private boolean eagerFilterInit = true;
|
||||
@@ -273,10 +275,12 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<? extends EventListener> loadWebListenerClass(String className) throws ClassNotFoundException {
|
||||
return (Class<? extends EventListener>) getServletClassLoader().loadClass(className);
|
||||
ClassLoader classLoader = getServletClassLoader();
|
||||
Assert.state(classLoader != null, "'classLoader' must not be null");
|
||||
return (Class<? extends EventListener>) classLoader.loadClass(className);
|
||||
}
|
||||
|
||||
private boolean isZeroOrLess(Duration timeoutDuration) {
|
||||
private boolean isZeroOrLess(@Nullable Duration timeoutDuration) {
|
||||
return timeoutDuration == null || timeoutDuration.isZero() || timeoutDuration.isNegative();
|
||||
}
|
||||
|
||||
@@ -293,7 +297,7 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
new ImmediateInstanceFactory<>(initializer), NO_CLASSES));
|
||||
}
|
||||
|
||||
private ClassLoader getServletClassLoader() {
|
||||
private @Nullable ClassLoader getServletClassLoader() {
|
||||
if (this.resourceLoader != null) {
|
||||
return this.resourceLoader.getClassLoader();
|
||||
}
|
||||
@@ -337,7 +341,7 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
return new CompositeResourceManager(managers.toArray(new ResourceManager[0]));
|
||||
}
|
||||
|
||||
private File getCanonicalDocumentRoot(File docBase) {
|
||||
private File getCanonicalDocumentRoot(@Nullable File docBase) {
|
||||
try {
|
||||
File root = (docBase != null) ? docBase : createTempDir("undertow-docbase");
|
||||
return root.getCanonicalFile();
|
||||
@@ -402,7 +406,7 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
port >= 0);
|
||||
}
|
||||
|
||||
private HttpHandlerFactory getCookieHandlerFactory(Deployment deployment) {
|
||||
private @Nullable HttpHandlerFactory getCookieHandlerFactory(Deployment deployment) {
|
||||
SameSite sessionSameSite = getSettings().getSession().getCookie().getSameSite();
|
||||
List<CookieSameSiteSupplier> suppliers = new ArrayList<>();
|
||||
if (sessionSameSite != null) {
|
||||
@@ -458,7 +462,7 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource(String path) {
|
||||
public @Nullable Resource getResource(String path) {
|
||||
for (URL url : this.metaInfResourceJarUrls) {
|
||||
URLResource resource = getMetaInfResource(url, path);
|
||||
if (resource != null) {
|
||||
@@ -482,7 +486,7 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
|
||||
}
|
||||
|
||||
private URLResource getMetaInfResource(URL resourceJar, String path) {
|
||||
private @Nullable URLResource getMetaInfResource(URL resourceJar, String path) {
|
||||
try {
|
||||
String urlPath = URLEncoder.encode(ENCODED_SLASH.matcher(path).replaceAll("/"), StandardCharsets.UTF_8);
|
||||
URL resourceUrl = new URL(resourceJar + "META-INF/resources" + urlPath);
|
||||
@@ -511,7 +515,7 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource(String path) throws IOException {
|
||||
public @Nullable Resource getResource(String path) throws IOException {
|
||||
if (path.startsWith("/org/springframework/boot")) {
|
||||
return null;
|
||||
}
|
||||
@@ -546,11 +550,11 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
*/
|
||||
private static class SuppliedSameSiteCookieHandler implements HttpHandler {
|
||||
|
||||
private final HttpHandler next;
|
||||
private final @Nullable HttpHandler next;
|
||||
|
||||
private final List<CookieSameSiteSupplier> suppliers;
|
||||
|
||||
SuppliedSameSiteCookieHandler(HttpHandler next, List<CookieSameSiteSupplier> suppliers) {
|
||||
SuppliedSameSiteCookieHandler(@Nullable HttpHandler next, List<CookieSameSiteSupplier> suppliers) {
|
||||
this.next = next;
|
||||
this.suppliers = suppliers;
|
||||
}
|
||||
@@ -558,7 +562,9 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
@Override
|
||||
public void handleRequest(HttpServerExchange exchange) throws Exception {
|
||||
exchange.addResponseCommitListener(this::beforeCommit);
|
||||
this.next.handleRequest(exchange);
|
||||
if (this.next != null) {
|
||||
this.next.handleRequest(exchange);
|
||||
}
|
||||
}
|
||||
|
||||
private void beforeCommit(HttpServerExchange exchange) {
|
||||
@@ -587,7 +593,7 @@ public class UndertowServletWebServerFactory extends UndertowWebServerFactory
|
||||
return result;
|
||||
}
|
||||
|
||||
private SameSite getSameSite(jakarta.servlet.http.Cookie cookie) {
|
||||
private @Nullable SameSite getSameSite(jakarta.servlet.http.Cookie cookie) {
|
||||
for (CookieSameSiteSupplier supplier : this.suppliers) {
|
||||
SameSite sameSite = supplier.getSameSite(cookie);
|
||||
if (sameSite != null) {
|
||||
|
||||
+3
@@ -17,4 +17,7 @@
|
||||
/**
|
||||
* Servlet web server implementation backed by Undertow.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.undertow.servlet;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
Reference in New Issue
Block a user