Skip to content

Commit 37e3896

Browse files
committed
Idle timeout between servers and a few other server options
1 parent b1165c1 commit 37e3896

11 files changed

Lines changed: 193 additions & 63 deletions

File tree

jooby-jetty/src/main/resources/org/jooby/spi/server.conf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ jetty {
4141
# The max idle time is applied:
4242
# When waiting for a new message to be received on a connection
4343
# When waiting for a new message to be sent on a connection
44-
44+
4545
# This value is interpreted as the maximum time between some progress being made on the connection.
4646
# So if a single byte is read or written, then the timeout is reset.
47-
IdleTimeout = 30000
47+
IdleTimeout = ${server.http.IdleTimeout}
4848
}
4949
}
5050

jooby-netty/src/main/java/org/jooby/internal/netty/NettyHandler.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import io.netty.handler.codec.http.HttpHeaders;
2828
import io.netty.handler.codec.http.HttpResponseStatus;
2929
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
30+
import io.netty.handler.timeout.IdleStateEvent;
3031
import io.netty.util.Attribute;
3132

3233
import org.jooby.spi.HttpHandler;
@@ -42,11 +43,18 @@ public class NettyHandler extends SimpleChannelInboundHandler<Object> {
4243

4344
private HttpHandler handler;
4445

45-
private Config config;
46+
private String tmpdir;
47+
48+
private int wsMaxMessageSize;
4649

4750
public NettyHandler(final HttpHandler handler, final Config config) {
4851
this.handler = requireNonNull(handler, "Application handler is required.");
49-
this.config = requireNonNull(config, "Application config is required.");
52+
this.tmpdir = config.getString("application.tmpdir");
53+
this.wsMaxMessageSize = Math
54+
.max(
55+
config.getBytes("server.ws.MaxTextMessageSize").intValue(),
56+
config.getBytes("server.ws.MaxBinaryMessageSize").intValue()
57+
);
5058
}
5159

5260
@Override
@@ -65,7 +73,7 @@ public void channelRead0(final ChannelHandlerContext ctx, final Object msg) {
6573
boolean keepAlive = HttpHeaders.isKeepAlive(req);
6674

6775
try {
68-
NettyRequest nreq = new NettyRequest(ctx, req, config.getString("application.tmpdir"));
76+
NettyRequest nreq = new NettyRequest(ctx, req, tmpdir, wsMaxMessageSize);
6977
handler.handle(nreq, new NettyResponse(ctx, nreq, keepAlive));
7078
} catch (Throwable ex) {
7179
exceptionCaught(ctx, ex);
@@ -90,4 +98,16 @@ public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cau
9098
}
9199
}
92100

101+
@Override
102+
public void userEventTriggered(final ChannelHandlerContext ctx, final Object evt)
103+
throws Exception {
104+
// Idle timeout
105+
if (evt instanceof IdleStateEvent) {
106+
log.debug("idle timeout: {}", ctx);
107+
ctx.close();
108+
} else {
109+
super.userEventTriggered(ctx, evt);
110+
}
111+
}
112+
93113
}

jooby-netty/src/main/java/org/jooby/internal/netty/NettyInitializer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
import io.netty.channel.socket.SocketChannel;
2323
import io.netty.handler.codec.http.HttpObjectAggregator;
2424
import io.netty.handler.codec.http.HttpServerCodec;
25+
import io.netty.handler.timeout.IdleStateHandler;
2526
import io.netty.util.concurrent.EventExecutorGroup;
2627

28+
import java.util.concurrent.TimeUnit;
29+
2730
import org.jooby.spi.HttpHandler;
2831

2932
import com.typesafe.config.Config;
@@ -44,6 +47,8 @@ public class NettyInitializer extends ChannelInitializer<SocketChannel> {
4447

4548
private int maxContentLength;
4649

50+
private long idleTimeOut;
51+
4752
public NettyInitializer(final EventExecutorGroup executor, final HttpHandler handler,
4853
final Config config) {
4954
this.executor = executor;
@@ -54,13 +59,15 @@ public NettyInitializer(final EventExecutorGroup executor, final HttpHandler han
5459
maxHeaderSize = config.getBytes("netty.http.MaxHeaderSize").intValue();
5560
maxChunkSize = config.getBytes("netty.http.MaxChunkSize").intValue();
5661
maxContentLength = config.getBytes("netty.http.MaxContentLength").intValue();
62+
idleTimeOut = config.getDuration("netty.http.IdleTimeout", TimeUnit.MILLISECONDS);
5763
}
5864

5965
@Override
6066
protected void initChannel(final SocketChannel ch) throws Exception {
6167
ch.pipeline()
6268
.addLast(new HttpServerCodec(maxInitialLineLength, maxHeaderSize, maxChunkSize))
6369
.addLast(new HttpObjectAggregator(maxContentLength))
70+
.addLast(new IdleStateHandler(0, 0, idleTimeOut, TimeUnit.MILLISECONDS))
6471
.addLast(executor, new NettyHandler(handler, config));
6572
}
6673

jooby-netty/src/main/java/org/jooby/internal/netty/NettyRequest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ public class NettyRequest implements NativeRequest {
7171

7272
private ChannelHandlerContext ctx;
7373

74-
public NettyRequest(final ChannelHandlerContext ctx, final HttpRequest req, final String tmpdir)
75-
throws IOException {
74+
private int wsMaxMessageSize;
75+
76+
public NettyRequest(final ChannelHandlerContext ctx, final HttpRequest req, final String tmpdir,
77+
final int wsMaxMessageSize) throws IOException {
7678
this.ctx = ctx;
7779
this.req = req;
7880
this.tmpdir = tmpdir;
7981
this.query = new QueryStringDecoder(req.getUri());
8082
this.path = URLDecoder.decode(query.path(), "UTF-8");
83+
this.wsMaxMessageSize = wsMaxMessageSize;
8184
}
8285

8386
@Override
@@ -177,7 +180,7 @@ public <T> T upgrade(final Class<T> type) throws Exception {
177180
String webSocketURL = protocol + "://" + req.headers().get(HttpHeaders.Names.HOST) + path;
178181

179182
WebSocketServerHandshakerFactory wsFactory =
180-
new WebSocketServerHandshakerFactory(webSocketURL, null, true);
183+
new WebSocketServerHandshakerFactory(webSocketURL, null, true, wsMaxMessageSize);
181184
WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req);
182185
NettyWebSocket result = new NettyWebSocket(ctx, handshaker, (ws) -> {
183186
handshaker.handshake(ctx.channel(), (FullHttpRequest) req)

jooby-netty/src/main/resources/org/jooby/spi/server.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ netty {
1010
MaxChunkSize = 8k
1111

1212
MaxContentLength = ${server.http.MaxRequestSize}
13+
14+
IdleTimeout = ${server.http.IdleTimeout}
1315
}
1416

1517
threads {

0 commit comments

Comments
 (0)