Skip to content

Commit 1c32c00

Browse files
authored
feat: rest protocol support keep-alive timeout header config (#14560)
* feat: rest protocol support keep-alive timeout header config * optimize: rest protocol connection default keepalive * optimize: rest protocol connection default keepalive
1 parent 05cb55a commit 1c32c00

File tree

2 files changed

+17
-19
lines changed

2 files changed

+17
-19
lines changed

dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/netty/NettyHttpResponse.java

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.apache.dubbo.metadata.rest.media.MediaType;
2121
import org.apache.dubbo.remoting.Constants;
2222
import org.apache.dubbo.rpc.protocol.rest.RestHeaderEnum;
23+
import org.apache.dubbo.rpc.protocol.rest.constans.RestConstant;
2324

2425
import java.io.IOException;
2526
import java.io.OutputStream;
@@ -36,10 +37,9 @@
3637
import io.netty.handler.codec.http.DefaultHttpResponse;
3738
import io.netty.handler.codec.http.HttpHeaderNames;
3839
import io.netty.handler.codec.http.HttpHeaderValues;
39-
import io.netty.handler.codec.http.HttpHeaders;
40-
import io.netty.handler.codec.http.HttpHeaders.Names;
4140
import io.netty.handler.codec.http.HttpMethod;
4241
import io.netty.handler.codec.http.HttpResponseStatus;
42+
import io.netty.handler.codec.http.HttpUtil;
4343
import io.netty.handler.codec.http.LastHttpContent;
4444

4545
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
@@ -51,11 +51,13 @@ public class NettyHttpResponse implements HttpResponse {
5151
private static final int EMPTY_CONTENT_LENGTH = 0;
5252
private int status = 200;
5353
private OutputStream os;
54-
private Map<String, List<String>> outputHeaders;
54+
private final Map<String, List<String>> outputHeaders;
5555
private final ChannelHandlerContext ctx;
5656
private boolean committed;
57-
private boolean keepAlive;
58-
private HttpMethod method;
57+
private final boolean keepAlive;
58+
59+
private final int idleTimeout;
60+
private final HttpMethod method;
5961
// raw response body
6062
private Object responseBody;
6163
// raw response class
@@ -69,6 +71,7 @@ public NettyHttpResponse(final ChannelHandlerContext ctx, final boolean keepAliv
6971
outputHeaders = new HashMap<>();
7072
this.method = method;
7173
os = new ChunkOutputStream(this, ctx, url.getParameter(Constants.PAYLOAD_KEY, Constants.DEFAULT_PAYLOAD));
74+
this.idleTimeout = url.getParameter(RestConstant.IDLE_TIMEOUT_PARAM, RestConstant.IDLE_TIMEOUT);
7275
this.ctx = ctx;
7376
this.keepAlive = keepAlive;
7477
}
@@ -125,7 +128,6 @@ public void reset() {
125128
throw new IllegalStateException("Messages.MESSAGES.alreadyCommitted()");
126129
}
127130
outputHeaders.clear();
128-
outputHeaders.clear();
129131
}
130132

131133
public boolean isKeepAlive() {
@@ -141,7 +143,7 @@ public DefaultHttpResponse getDefaultHttpResponse() {
141143
public DefaultHttpResponse getEmptyHttpResponse() {
142144
DefaultFullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(getStatus()));
143145
if (method == null || !method.equals(HttpMethod.HEAD)) {
144-
res.headers().add(Names.CONTENT_LENGTH, EMPTY_CONTENT_LENGTH);
146+
res.headers().add(HttpHeaderNames.CONTENT_LENGTH, EMPTY_CONTENT_LENGTH);
145147
}
146148
transformResponseHeaders(res);
147149

@@ -155,7 +157,7 @@ private void transformResponseHeaders(io.netty.handler.codec.http.HttpResponse r
155157
public void prepareChunkStream() {
156158
committed = true;
157159
DefaultHttpResponse response = getDefaultHttpResponse();
158-
HttpHeaders.setTransferEncodingChunked(response);
160+
HttpUtil.setTransferEncodingChunked(response, true);
159161
ctx.write(response);
160162
}
161163

@@ -185,12 +187,7 @@ public void flushBuffer() throws IOException {
185187
@Override
186188
public void addOutputHeaders(String name, String value) {
187189

188-
List<String> values = outputHeaders.get(name);
189-
190-
if (values == null) {
191-
values = new ArrayList<>();
192-
outputHeaders.put(name, values);
193-
}
190+
List<String> values = outputHeaders.computeIfAbsent(name, k -> new ArrayList<>());
194191

195192
if (values.contains(value)) {
196193
return;
@@ -200,10 +197,12 @@ public void addOutputHeaders(String name, String value) {
200197
}
201198

202199
@SuppressWarnings({"rawtypes", "unchecked"})
203-
public static void transformHeaders(
204-
NettyHttpResponse nettyResponse, io.netty.handler.codec.http.HttpResponse response) {
200+
public void transformHeaders(NettyHttpResponse nettyResponse, io.netty.handler.codec.http.HttpResponse response) {
205201
if (nettyResponse.isKeepAlive()) {
206202
response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
203+
if (idleTimeout > 0) {
204+
response.headers().set(HttpHeaderNames.KEEP_ALIVE, "timeout=" + idleTimeout);
205+
}
207206
} else {
208207
response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
209208
}

dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/netty/RestHttpRequestDecoder.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
import io.netty.channel.ChannelHandlerContext;
3333
import io.netty.handler.codec.MessageToMessageDecoder;
34-
import io.netty.handler.codec.http.HttpHeaders;
34+
import io.netty.handler.codec.http.HttpUtil;
3535

3636
import static org.apache.dubbo.config.Constants.SERVER_THREAD_POOL_NAME;
3737

@@ -56,8 +56,7 @@ public RestHttpRequestDecoder(URL url, ServiceDeployer serviceDeployer) {
5656
protected void decode(
5757
ChannelHandlerContext ctx, io.netty.handler.codec.http.FullHttpRequest request, List<Object> out)
5858
throws Exception {
59-
boolean keepAlive = HttpHeaders.isKeepAlive(request);
60-
59+
boolean keepAlive = HttpUtil.isKeepAlive(request);
6160
NettyHttpResponse nettyHttpResponse = new NettyHttpResponse(ctx, keepAlive, url);
6261
NettyRequestFacade requestFacade = new NettyRequestFacade(request, ctx, serviceDeployer);
6362

0 commit comments

Comments
 (0)