HttpServerKeepAliveHandler Class — netty Architecture
Architecture documentation for the HttpServerKeepAliveHandler class in HttpServerKeepAliveHandler.java from the netty codebase.
Entity Profile
Dependency Diagram
graph TD 08219795_24b6_3fff_1446_c9792531660c["HttpServerKeepAliveHandler"] bb5713d4_7022_035f_23dd_140380ed2dfa["HttpServerKeepAliveHandler.java"] 08219795_24b6_3fff_1446_c9792531660c -->|defined in| bb5713d4_7022_035f_23dd_140380ed2dfa 8a7331c0_8538_53a5_4f8d_af6ea5f3b2e2["channelRead()"] 08219795_24b6_3fff_1446_c9792531660c -->|method| 8a7331c0_8538_53a5_4f8d_af6ea5f3b2e2 db8fa580_b26b_c3cb_8f82_220d29371c8b["write()"] 08219795_24b6_3fff_1446_c9792531660c -->|method| db8fa580_b26b_c3cb_8f82_220d29371c8b a6374c00_c860_8572_b173_8706804dfb6e["trackResponse()"] 08219795_24b6_3fff_1446_c9792531660c -->|method| a6374c00_c860_8572_b173_8706804dfb6e 0fc97c94_f864_244f_c666_b10e832aaf95["shouldKeepAlive()"] 08219795_24b6_3fff_1446_c9792531660c -->|method| 0fc97c94_f864_244f_c666_b10e832aaf95 f90d5a22_63aa_2c1b_2232_c23c91dfad4a["isSelfDefinedMessageLength()"] 08219795_24b6_3fff_1446_c9792531660c -->|method| f90d5a22_63aa_2c1b_2232_c23c91dfad4a c0e2636f_edd9_86b7_13b8_ef3bde47c463["isInformational()"] 08219795_24b6_3fff_1446_c9792531660c -->|method| c0e2636f_edd9_86b7_13b8_ef3bde47c463 e02b7ffd_94d2_eb03_5dbd_61e0353f04f0["isMultipart()"] 08219795_24b6_3fff_1446_c9792531660c -->|method| e02b7ffd_94d2_eb03_5dbd_61e0353f04f0
Relationship Graph
Source Code
codec-http/src/main/java/io/netty/handler/codec/http/HttpServerKeepAliveHandler.java lines 47–128
public class HttpServerKeepAliveHandler extends ChannelDuplexHandler {
private static final String MULTIPART_PREFIX = "multipart";
private boolean persistentConnection = true;
// Track pending responses to support client pipelining: https://tools.ietf.org/html/rfc7230#section-6.3.2
private int pendingResponses;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// read message and track if it was keepAlive
if (msg instanceof HttpRequest) {
final HttpRequest request = (HttpRequest) msg;
if (persistentConnection) {
pendingResponses += 1;
persistentConnection = isKeepAlive(request);
}
}
super.channelRead(ctx, msg);
}
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
// modify message on way out to add headers if needed
if (msg instanceof HttpResponse) {
final HttpResponse response = (HttpResponse) msg;
trackResponse(response);
// Assume the response writer knows if they can persist or not and sets isKeepAlive on the response
if (!isKeepAlive(response) || !isSelfDefinedMessageLength(response)) {
// No longer keep alive as the client can't tell when the message is done unless we close connection
pendingResponses = 0;
persistentConnection = false;
}
// Server might think it can keep connection alive, but we should fix response header if we know better
if (!shouldKeepAlive()) {
setKeepAlive(response, false);
}
}
if (msg instanceof LastHttpContent && !shouldKeepAlive()) {
promise = promise.unvoid().addListener(ChannelFutureListener.CLOSE);
}
super.write(ctx, msg, promise);
}
private void trackResponse(HttpResponse response) {
if (!isInformational(response)) {
pendingResponses -= 1;
}
}
private boolean shouldKeepAlive() {
return pendingResponses != 0 || persistentConnection;
}
/**
* Keep-alive only works if the client can detect when the message has ended without relying on the connection being
* closed.
* <p>
* <ul>
* <li>See <a href="https://tools.ietf.org/html/rfc7230#section-6.3"/></li>
* <li>See <a href="https://tools.ietf.org/html/rfc7230#section-3.3.2"/></li>
* <li>See <a href="https://tools.ietf.org/html/rfc7230#section-3.3.3"/></li>
* </ul>
*
* @param response The HttpResponse to check
*
* @return true if the response has a self defined message length.
*/
private static boolean isSelfDefinedMessageLength(HttpResponse response) {
return isContentLengthSet(response) || isTransferEncodingChunked(response) || isMultipart(response) ||
isInformational(response) || response.status().code() == HttpResponseStatus.NO_CONTENT.code();
}
private static boolean isInformational(HttpResponse response) {
return response.status().codeClass() == HttpStatusClass.INFORMATIONAL;
}
private static boolean isMultipart(HttpResponse response) {
String contentType = response.headers().get(HttpHeaderNames.CONTENT_TYPE);
return contentType != null &&
contentType.regionMatches(true, 0, MULTIPART_PREFIX, 0, MULTIPART_PREFIX.length());
}
Source
Frequently Asked Questions
What is the HttpServerKeepAliveHandler class?
HttpServerKeepAliveHandler is a class in the netty codebase, defined in codec-http/src/main/java/io/netty/handler/codec/http/HttpServerKeepAliveHandler.java.
Where is HttpServerKeepAliveHandler defined?
HttpServerKeepAliveHandler is defined in codec-http/src/main/java/io/netty/handler/codec/http/HttpServerKeepAliveHandler.java at line 47.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free