1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.codec.http;
17
18 import io.netty5.buffer.api.BufferAllocator;
19 import io.netty5.channel.ChannelFutureListeners;
20 import io.netty5.channel.ChannelHandler;
21 import io.netty5.channel.ChannelHandlerContext;
22 import io.netty5.util.Resource;
23
24 import static io.netty5.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
25 import static io.netty5.handler.codec.http.HttpResponseStatus.CONTINUE;
26 import static io.netty5.handler.codec.http.HttpResponseStatus.EXPECTATION_FAILED;
27 import static io.netty5.handler.codec.http.HttpVersion.HTTP_1_1;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class HttpServerExpectContinueHandler implements ChannelHandler {
49
50
51
52
53 protected HttpResponse acceptMessage(BufferAllocator allocator, @SuppressWarnings("unused") HttpRequest request) {
54 return newEmptyResponse(allocator, CONTINUE);
55 }
56
57
58
59
60 protected HttpResponse rejectResponse(BufferAllocator allocator, @SuppressWarnings("unused") HttpRequest request) {
61 return newEmptyResponse(allocator, EXPECTATION_FAILED);
62 }
63
64 private static DefaultFullHttpResponse newEmptyResponse(BufferAllocator allocator, HttpResponseStatus status) {
65 final DefaultFullHttpResponse resp = new DefaultFullHttpResponse(HTTP_1_1, status, allocator.allocate(0));
66 resp.headers().set(CONTENT_LENGTH, 0);
67 return resp;
68 }
69
70 @Override
71 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
72 if (msg instanceof HttpRequest) {
73 HttpRequest req = (HttpRequest) msg;
74
75 if (HttpUtil.is100ContinueExpected(req)) {
76 HttpResponse accept = acceptMessage(ctx.bufferAllocator(), req);
77
78 if (accept == null) {
79
80 HttpResponse rejection = rejectResponse(ctx.bufferAllocator(), req);
81 Resource.dispose(msg);
82 ctx.writeAndFlush(rejection).addListener(ctx.channel(), ChannelFutureListeners.CLOSE_ON_FAILURE);
83 return;
84 }
85
86 ctx.writeAndFlush(accept).addListener(ctx.channel(), ChannelFutureListeners.CLOSE_ON_FAILURE);
87 req.headers().remove(HttpHeaderNames.EXPECT);
88 }
89 }
90 ctx.fireChannelRead(msg);
91 }
92 }