Skip to content

Commit cbcd7b9

Browse files
saraswathy-krishwilkinsona
authored andcommitted
Add idle timeout property for Reactor Netty
See gh-27371
1 parent 9d461a0 commit cbcd7b9

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,12 @@ public static class Netty {
13001300
*/
13011301
private boolean validateHeaders = true;
13021302

1303+
/**
1304+
* IdleTimeout for netty server .If an idletimeout is not specified, this
1305+
* indicates no timeout(infinite).
1306+
*/
1307+
private Duration idleTimeout;
1308+
13031309
public Duration getConnectionTimeout() {
13041310
return this.connectionTimeout;
13051311
}
@@ -1348,6 +1354,14 @@ public void setValidateHeaders(boolean validateHeaders) {
13481354
this.validateHeaders = validateHeaders;
13491355
}
13501356

1357+
public Duration getIdleTimeout() {
1358+
return this.idleTimeout;
1359+
}
1360+
1361+
public void setIdleTimeout(Duration idleTimeout) {
1362+
this.idleTimeout = idleTimeout;
1363+
}
1364+
13511365
}
13521366

13531367
/**

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public void customize(NettyReactiveWebServerFactory factory) {
6060
ServerProperties.Netty nettyProperties = this.serverProperties.getNetty();
6161
propertyMapper.from(nettyProperties::getConnectionTimeout).whenNonNull()
6262
.to((connectionTimeout) -> customizeConnectionTimeout(factory, connectionTimeout));
63+
propertyMapper.from(nettyProperties::getIdleTimeout).whenNonNull()
64+
.to((idleTimeout) -> customizeIdleTimeout(factory, idleTimeout));
6365
customizeRequestDecoder(factory, propertyMapper);
6466
}
6567

@@ -98,4 +100,8 @@ private void customizeRequestDecoder(NettyReactiveWebServerFactory factory, Prop
98100
}));
99101
}
100102

103+
private void customizeIdleTimeout(NettyReactiveWebServerFactory factory, Duration idleTimeout) {
104+
factory.addServerCustomizers((httpServer) -> httpServer.idleTimeout(idleTimeout));
105+
}
106+
101107
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,12 @@ void nettyInitialBufferSizeMatchesHttpDecoderSpecDefault() {
535535
.isEqualTo(HttpDecoderSpec.DEFAULT_INITIAL_BUFFER_SIZE);
536536
}
537537

538+
@Test
539+
void testCustomizeNettyIdleTimeout() {
540+
bind("server.netty.idle-timeout", "10s");
541+
assertThat(this.properties.getNetty().getIdleTimeout()).isEqualTo(Duration.ofSeconds(10));
542+
}
543+
538544
private Connector getDefaultConnector() {
539545
return new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
540546
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/NettyWebServerFactoryCustomizerTests.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,22 @@ void forwardHeadersWhenStrategyIsNoneShouldNotConfigureValve() {
104104

105105
@Test
106106
void setConnectionTimeout() {
107-
setupConnectionTimeout(Duration.ofSeconds(1));
107+
setServerProperties();
108+
this.serverProperties.getNetty().setConnectionTimeout(Duration.ofSeconds(1));
108109
NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class);
109110
this.customizer.customize(factory);
110111
verifyConnectionTimeout(factory, 1000);
111112
}
112113

114+
@Test
115+
void setIdleTimeout() {
116+
setServerProperties();
117+
this.serverProperties.getNetty().setIdleTimeout(Duration.ofSeconds(1));
118+
NettyReactiveWebServerFactory factory = mock(NettyReactiveWebServerFactory.class);
119+
this.customizer.customize(factory);
120+
verifyIdleTimeout(factory, Duration.ofSeconds(1));
121+
}
122+
113123
@Test
114124
void configureHttpRequestDecoder() {
115125
ServerProperties.Netty nettyProperties = this.serverProperties.getNetty();
@@ -143,10 +153,21 @@ private void verifyConnectionTimeout(NettyReactiveWebServerFactory factory, Inte
143153
assertThat(options.get(ChannelOption.CONNECT_TIMEOUT_MILLIS)).isEqualTo(expected);
144154
}
145155

146-
private void setupConnectionTimeout(Duration connectionTimeout) {
156+
private void verifyIdleTimeout(NettyReactiveWebServerFactory factory, Duration expected) {
157+
if (expected == null) {
158+
verify(factory, never()).addServerCustomizers(any(NettyServerCustomizer.class));
159+
return;
160+
}
161+
verify(factory, times(2)).addServerCustomizers(this.customizerCaptor.capture());
162+
NettyServerCustomizer serverCustomizer = this.customizerCaptor.getAllValues().get(0);
163+
HttpServer httpServer = serverCustomizer.apply(HttpServer.create());
164+
Duration idleTimeout = httpServer.configuration().idleTimeout();
165+
assertThat(idleTimeout).isEqualTo(expected);
166+
}
167+
168+
private void setServerProperties() {
147169
this.serverProperties.setForwardHeadersStrategy(ForwardHeadersStrategy.NONE);
148170
this.serverProperties.setMaxHttpHeaderSize(null);
149-
this.serverProperties.getNetty().setConnectionTimeout(connectionTimeout);
150171
}
151172

152173
}

0 commit comments

Comments
 (0)