Browse Source

Merge branch '3.5.x'

Fixes gh-48059
pull/48170/head
Phillip Webb 1 month ago
parent
commit
2a9e6a2b93
  1. 19
      module/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyWebServer.java
  2. 13
      module/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/NettyReactiveWebServerFactoryTests.java

19
module/spring-boot-reactor-netty/src/main/java/org/springframework/boot/reactor/netty/NettyWebServer.java

@ -65,6 +65,11 @@ public class NettyWebServer implements WebServer {
*/ */
private static final int ERROR_NO_EACCES = -13; private static final int ERROR_NO_EACCES = -13;
/**
* Address in use error code from {@code errno.h}.
*/
private static final int ERROR_ADDR_IN_USE = -98;
private static final Predicate<HttpServerRequest> ALWAYS = (request) -> true; private static final Predicate<HttpServerRequest> ALWAYS = (request) -> true;
private static final Log logger = LogFactory.getLog(NettyWebServer.class); private static final Log logger = LogFactory.getLog(NettyWebServer.class);
@ -119,11 +124,19 @@ public class NettyWebServer implements WebServer {
this.disposableServer = disposableServer; this.disposableServer = disposableServer;
} }
catch (Exception ex) { catch (Exception ex) {
PortInUseException.ifCausedBy(ex, ChannelBindException.class, (bindException) -> { PortInUseException.ifCausedBy(ex, ChannelBindException.class, (channelBindException) -> {
if (bindException.localPort() > 0 && !isPermissionDenied(bindException.getCause())) { if (channelBindException.localPort() > 0 && !isPermissionDenied(channelBindException.getCause())) {
throw new PortInUseException(bindException.localPort(), ex); PortInUseException.throwIfPortBindingException(channelBindException,
channelBindException::localPort);
} }
}); });
if (ex instanceof ChannelBindException channelBindException) {
PortInUseException.ifCausedBy(ex, NativeIoException.class, (nativeIoException) -> {
if (nativeIoException.expectedErr() == ERROR_ADDR_IN_USE) {
throw new PortInUseException(channelBindException.localPort(), ex);
}
});
}
throw new WebServerException("Unable to start Netty", ex); throw new WebServerException("Unable to start Netty", ex);
} }
logger.info(getStartedOnMessage(disposableServer)); logger.info(getStartedOnMessage(disposableServer));

13
module/spring-boot-reactor-netty/src/test/java/org/springframework/boot/reactor/netty/NettyReactiveWebServerFactoryTests.java

@ -17,7 +17,9 @@
package org.springframework.boot.reactor.netty; package org.springframework.boot.reactor.netty;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.InetAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.time.Duration; import java.time.Duration;
import java.util.Arrays; import java.util.Arrays;
@ -44,6 +46,7 @@ import org.springframework.boot.testsupport.classpath.resources.WithPackageResou
import org.springframework.boot.web.server.PortInUseException; import org.springframework.boot.web.server.PortInUseException;
import org.springframework.boot.web.server.Shutdown; import org.springframework.boot.web.server.Shutdown;
import org.springframework.boot.web.server.Ssl; import org.springframework.boot.web.server.Ssl;
import org.springframework.boot.web.server.WebServerException;
import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactory; import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactory;
import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactoryTests; import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactoryTests;
import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory; import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory;
@ -72,7 +75,7 @@ import static org.mockito.Mockito.mock;
class NettyReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactoryTests { class NettyReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactoryTests {
@Test @Test
void exceptionIsThrownWhenPortIsAlreadyInUse() { void portInUseExceptionIsThrownWhenPortIsAlreadyInUse() {
AbstractReactiveWebServerFactory factory = getFactory(); AbstractReactiveWebServerFactory factory = getFactory();
factory.setPort(0); factory.setPort(0);
this.webServer = factory.getWebServer(new EchoHandler()); this.webServer = factory.getWebServer(new EchoHandler());
@ -83,6 +86,14 @@ class NettyReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactor
.withCauseInstanceOf(Throwable.class); .withCauseInstanceOf(Throwable.class);
} }
@Test
void webServerExceptionIsThrownWhenAddressCannotBeAssigned() throws UnknownHostException {
AbstractReactiveWebServerFactory factory = getFactory();
factory.setPort(8080);
factory.setAddress(InetAddress.getByName("1.2.3.4"));
assertThatExceptionOfType(WebServerException.class).isThrownBy(factory.getWebServer(new EchoHandler())::start);
}
@Test @Test
void getPortWhenDisposableServerPortOperationIsUnsupportedReturnsMinusOne() { void getPortWhenDisposableServerPortOperationIsUnsupportedReturnsMinusOne() {
NettyReactiveWebServerFactory factory = new NoPortNettyReactiveWebServerFactory(0); NettyReactiveWebServerFactory factory = new NoPortNettyReactiveWebServerFactory(0);

Loading…
Cancel
Save