1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.Unpooled;
20 import io.netty.util.internal.StringUtil;
21
22 import java.util.Map;
23
24
25
26
27 public class DefaultLastHttpContent extends DefaultHttpContent implements LastHttpContent {
28
29 private final HttpHeaders trailingHeaders;
30 private final boolean validateHeaders;
31
32 public DefaultLastHttpContent() {
33 this(Unpooled.buffer(0));
34 }
35
36 public DefaultLastHttpContent(ByteBuf content) {
37 this(content, true);
38 }
39
40 public DefaultLastHttpContent(ByteBuf content, boolean validateHeaders) {
41 super(content);
42 trailingHeaders = new TrailingHeaders(validateHeaders);
43 this.validateHeaders = validateHeaders;
44 }
45
46 @Override
47 public LastHttpContent copy() {
48 DefaultLastHttpContent copy = new DefaultLastHttpContent(content().copy(), validateHeaders);
49 copy.trailingHeaders().set(trailingHeaders());
50 return copy;
51 }
52
53 @Override
54 public LastHttpContent duplicate() {
55 DefaultLastHttpContent copy = new DefaultLastHttpContent(content().duplicate(), validateHeaders);
56 copy.trailingHeaders().set(trailingHeaders());
57 return copy;
58 }
59
60 @Override
61 public LastHttpContent retain(int increment) {
62 super.retain(increment);
63 return this;
64 }
65
66 @Override
67 public LastHttpContent retain() {
68 super.retain();
69 return this;
70 }
71
72 @Override
73 public HttpHeaders trailingHeaders() {
74 return trailingHeaders;
75 }
76
77 @Override
78 public String toString() {
79 StringBuilder buf = new StringBuilder(super.toString());
80 buf.append(StringUtil.NEWLINE);
81 appendHeaders(buf);
82
83
84 buf.setLength(buf.length() - StringUtil.NEWLINE.length());
85 return buf.toString();
86 }
87
88 private void appendHeaders(StringBuilder buf) {
89 for (Map.Entry<String, String> e: trailingHeaders()) {
90 buf.append(e.getKey());
91 buf.append(": ");
92 buf.append(e.getValue());
93 buf.append(StringUtil.NEWLINE);
94 }
95 }
96
97 private static final class TrailingHeaders extends DefaultHttpHeaders {
98 TrailingHeaders(boolean validate) {
99 super(validate);
100 }
101
102 @Override
103 void validateHeaderName0(CharSequence name) {
104 super.validateHeaderName0(name);
105 if (HttpHeaders.equalsIgnoreCase(HttpHeaders.Names.CONTENT_LENGTH, name) ||
106 HttpHeaders.equalsIgnoreCase(HttpHeaders.Names.TRANSFER_ENCODING, name) ||
107 HttpHeaders.equalsIgnoreCase(HttpHeaders.Names.TRAILER, name)) {
108 throw new IllegalArgumentException(
109 "prohibited trailing header: " + name);
110 }
111 }
112 }
113 }