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