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 }