1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http2;
17
18 import java.io.Closeable;
19
20 import io.netty.buffer.ByteBuf;
21 import io.netty.buffer.Unpooled;
22
23 import static io.netty.handler.codec.http2.Http2Error.COMPRESSION_ERROR;
24 import static io.netty.handler.codec.http2.Http2Exception.connectionError;
25 import static io.netty.util.internal.ObjectUtil.checkNotNull;
26
27 public class DefaultHttp2HeadersEncoder implements
28 Http2HeadersEncoder, Http2HeadersEncoder.Configuration, Closeable {
29
30 private final HpackEncoder hpackEncoder;
31 private final SensitivityDetector sensitivityDetector;
32 private ByteBuf tableSizeChangeOutput;
33
34 public DefaultHttp2HeadersEncoder() {
35 this(NEVER_SENSITIVE);
36 }
37
38 public DefaultHttp2HeadersEncoder(SensitivityDetector sensitivityDetector) {
39 this(sensitivityDetector, new HpackEncoder());
40 }
41
42 public DefaultHttp2HeadersEncoder(SensitivityDetector sensitivityDetector, boolean ignoreMaxHeaderListSize) {
43 this(sensitivityDetector, new HpackEncoder(ignoreMaxHeaderListSize));
44 }
45
46 public DefaultHttp2HeadersEncoder(SensitivityDetector sensitivityDetector, boolean ignoreMaxHeaderListSize,
47 int dynamicTableArraySizeHint) {
48 this(sensitivityDetector, ignoreMaxHeaderListSize, dynamicTableArraySizeHint, HpackEncoder.HUFF_CODE_THRESHOLD);
49 }
50
51 public DefaultHttp2HeadersEncoder(SensitivityDetector sensitivityDetector, boolean ignoreMaxHeaderListSize,
52 int dynamicTableArraySizeHint, int huffCodeThreshold) {
53 this(sensitivityDetector,
54 new HpackEncoder(ignoreMaxHeaderListSize, dynamicTableArraySizeHint, huffCodeThreshold));
55 }
56
57
58
59
60
61 DefaultHttp2HeadersEncoder(SensitivityDetector sensitivityDetector, HpackEncoder hpackEncoder) {
62 this.sensitivityDetector = checkNotNull(sensitivityDetector, "sensitiveDetector");
63 this.hpackEncoder = checkNotNull(hpackEncoder, "hpackEncoder");
64 }
65
66 @Override
67 public void encodeHeaders(int streamId, Http2Headers headers, ByteBuf buffer) throws Http2Exception {
68 try {
69
70
71 if (tableSizeChangeOutput != null && tableSizeChangeOutput.isReadable()) {
72 buffer.writeBytes(tableSizeChangeOutput);
73 tableSizeChangeOutput.clear();
74 }
75
76 hpackEncoder.encodeHeaders(streamId, buffer, headers, sensitivityDetector);
77 } catch (Http2Exception e) {
78 throw e;
79 } catch (Throwable t) {
80 throw connectionError(COMPRESSION_ERROR, t, "Failed encoding headers block: %s", t.getMessage());
81 }
82 }
83
84 @Override
85 public void maxHeaderTableSize(long max) throws Http2Exception {
86 if (tableSizeChangeOutput == null) {
87 tableSizeChangeOutput = Unpooled.buffer();
88 }
89 hpackEncoder.setMaxHeaderTableSize(tableSizeChangeOutput, max);
90 }
91
92 @Override
93 public long maxHeaderTableSize() {
94 return hpackEncoder.getMaxHeaderTableSize();
95 }
96
97 @Override
98 public void maxHeaderListSize(long max) throws Http2Exception {
99 hpackEncoder.setMaxHeaderListSize(max);
100 }
101
102 @Override
103 public long maxHeaderListSize() {
104 return hpackEncoder.getMaxHeaderListSize();
105 }
106
107 @Override
108 public Configuration configuration() {
109 return this;
110 }
111
112
113
114
115 @Override
116 public void close() {
117 if (tableSizeChangeOutput != null) {
118 tableSizeChangeOutput.release();
119 tableSizeChangeOutput = null;
120 }
121 }
122 }