Skip to content

Commit e314307

Browse files
committed
Enable IdleTimeoutHandler only during periods without active HTTP message exchange
Signed-off-by: raccoonback <[email protected]>
1 parent 86790f3 commit e314307

File tree

1 file changed

+52
-14
lines changed

1 file changed

+52
-14
lines changed

reactor-netty-http/src/main/java/reactor/netty/http/server/HttpTrafficHandler.java

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@
1515
*/
1616
package reactor.netty.http.server;
1717

18-
import java.net.SocketAddress;
19-
import java.time.Duration;
20-
import java.time.ZonedDateTime;
21-
import java.util.Optional;
22-
import java.util.Queue;
23-
import java.util.function.BiFunction;
24-
import java.util.function.BiPredicate;
18+
import static io.netty.handler.codec.http.HttpUtil.isContentLengthSet;
19+
import static io.netty.handler.codec.http.HttpUtil.isKeepAlive;
20+
import static io.netty.handler.codec.http.HttpUtil.isTransferEncodingChunked;
21+
import static io.netty.handler.codec.http.HttpUtil.setKeepAlive;
22+
import static io.netty.handler.codec.http.LastHttpContent.EMPTY_LAST_CONTENT;
23+
import static reactor.netty.ReactorNetty.format;
2524

2625
import io.netty.channel.ChannelDuplexHandler;
2726
import io.netty.channel.ChannelFutureListener;
2827
import io.netty.channel.ChannelHandlerContext;
28+
import io.netty.channel.ChannelPipeline;
2929
import io.netty.channel.ChannelPromise;
3030
import io.netty.handler.codec.DecoderResult;
3131
import io.netty.handler.codec.DecoderResultProvider;
@@ -43,28 +43,32 @@
4343
import io.netty.handler.codec.http.LastHttpContent;
4444
import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
4545
import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
46+
import io.netty.handler.codec.http2.Http2FrameCodec;
4647
import io.netty.handler.ssl.SslHandler;
4748
import io.netty.util.ReferenceCountUtil;
49+
import java.net.SocketAddress;
50+
import java.time.Duration;
51+
import java.time.ZonedDateTime;
52+
import java.util.Optional;
53+
import java.util.Queue;
54+
import java.util.function.BiFunction;
55+
import java.util.function.BiPredicate;
4856
import reactor.core.Exceptions;
4957
import reactor.core.publisher.Mono;
5058
import reactor.netty.Connection;
5159
import reactor.netty.ConnectionObserver;
5260
import reactor.netty.ReactorNetty;
5361
import reactor.netty.channel.ChannelOperations;
62+
import reactor.netty.http.Http2ConnectionLiveness;
5463
import reactor.netty.http.Http2SettingsSpec;
64+
import reactor.netty.http.HttpConnectionImmediateClose;
65+
import reactor.netty.http.IdleTimeoutHandler;
5566
import reactor.netty.http.logging.HttpMessageArgProviderFactory;
5667
import reactor.netty.http.logging.HttpMessageLogFactory;
5768
import reactor.netty.http.server.compression.HttpCompressionOptionsSpec;
5869
import reactor.util.annotation.Nullable;
5970
import reactor.util.concurrent.Queues;
6071

61-
import static io.netty.handler.codec.http.HttpUtil.isContentLengthSet;
62-
import static io.netty.handler.codec.http.HttpUtil.isKeepAlive;
63-
import static io.netty.handler.codec.http.HttpUtil.isTransferEncodingChunked;
64-
import static io.netty.handler.codec.http.HttpUtil.setKeepAlive;
65-
import static io.netty.handler.codec.http.LastHttpContent.EMPTY_LAST_CONTENT;
66-
import static reactor.netty.ReactorNetty.format;
67-
6872
/**
6973
* Replace {@link io.netty.handler.codec.http.HttpServerKeepAliveHandler} with extra
7074
* handler management.
@@ -157,6 +161,12 @@ public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
157161
ctx.read();
158162
}
159163

164+
@Override
165+
public void channelActive(ChannelHandlerContext ctx) {
166+
setupIdleTimeoutHandler(ctx.pipeline());
167+
ctx.fireChannelActive();
168+
}
169+
160170
@Override
161171
public void channelRead(ChannelHandlerContext ctx, Object msg) {
162172
read = true;
@@ -172,6 +182,10 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) {
172182
if (msg instanceof HttpRequest) {
173183
finalizingResponse = false;
174184

185+
if (idleTimeout != null) {
186+
IdleTimeoutHandler.removeIdleTimeoutHandler(ctx.pipeline());
187+
}
188+
175189
final HttpRequest request = (HttpRequest) msg;
176190

177191
if (H2.equals(request.protocolVersion())) {
@@ -539,6 +553,7 @@ void handleLastHttpContent(Object msg, ChannelPromise promise) {
539553
ctx.executor().execute(this);
540554
}
541555
else {
556+
setupIdleTimeoutHandler(ctx.pipeline());
542557
ctx.read();
543558
}
544559
}
@@ -682,6 +697,29 @@ static boolean isMultipart(HttpResponse response) {
682697
MULTIPART_PREFIX.length());
683698
}
684699

700+
private void setupIdleTimeoutHandler(ChannelPipeline pipeline) {
701+
Http2FrameCodec httpCodec = pipeline.get(Http2FrameCodec.class);
702+
if(httpCodec != null) {
703+
IdleTimeoutHandler.addIdleTimeoutServerHandler(
704+
pipeline,
705+
idleTimeout,
706+
new Http2ConnectionLiveness(
707+
httpCodec,
708+
http2SettingsSpec != null ? http2SettingsSpec.pingAckTimeout() : null,
709+
http2SettingsSpec != null ? http2SettingsSpec.pingScheduleInterval() : null,
710+
http2SettingsSpec != null ? http2SettingsSpec.pingAckDropThreshold() : null
711+
)
712+
);
713+
return;
714+
}
715+
716+
IdleTimeoutHandler.addIdleTimeoutServerHandler(
717+
pipeline,
718+
idleTimeout,
719+
new HttpConnectionImmediateClose()
720+
);
721+
}
722+
685723
static final class HttpRequestHolder {
686724
final HttpRequest request;
687725
final ZonedDateTime timestamp;

0 commit comments

Comments
 (0)