View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.http2.hpack;
29  
30  import java.util.List;
31  import java.util.concurrent.ConcurrentHashMap;
32  import java.util.concurrent.ConcurrentMap;
33  import java.util.concurrent.CopyOnWriteArrayList;
34  
35  import org.apache.hc.core5.http2.H2PseudoRequestHeaders;
36  import org.apache.hc.core5.http2.H2PseudoResponseHeaders;
37  
38  final class StaticTable {
39  
40      static final HPackHeader[] STANDARD_HEADERS = {
41              new HPackHeader(H2PseudoRequestHeaders.AUTHORITY, ""),
42              new HPackHeader(H2PseudoRequestHeaders.METHOD, "GET"),
43              new HPackHeader(H2PseudoRequestHeaders.METHOD, "POST"),
44              new HPackHeader(H2PseudoRequestHeaders.PATH, "/"),
45              new HPackHeader(H2PseudoRequestHeaders.PATH, "/index.html"),
46              new HPackHeader(H2PseudoRequestHeaders.SCHEME, "http"),
47              new HPackHeader(H2PseudoRequestHeaders.SCHEME, "https"),
48              new HPackHeader(H2PseudoResponseHeaders.STATUS, "200"),
49              new HPackHeader(H2PseudoResponseHeaders.STATUS, "204"),
50              new HPackHeader(H2PseudoResponseHeaders.STATUS, "206"),
51              new HPackHeader(H2PseudoResponseHeaders.STATUS, "304"),
52              new HPackHeader(H2PseudoResponseHeaders.STATUS, "400"),
53              new HPackHeader(H2PseudoResponseHeaders.STATUS, "404"),
54              new HPackHeader(H2PseudoResponseHeaders.STATUS, "500"),
55              new HPackHeader("accept-charset", ""),
56              new HPackHeader("accept-encoding", "gzip, deflate"),
57              new HPackHeader("accept-language", ""),
58              new HPackHeader("accept-ranges", ""),
59              new HPackHeader("accept", ""),
60              new HPackHeader("access-control-allow-origin", ""),
61              new HPackHeader("age", ""),
62              new HPackHeader("allow", ""),
63              new HPackHeader("authorization", ""),
64              new HPackHeader("cache-control", ""),
65              new HPackHeader("content-disposition", ""),
66              new HPackHeader("content-encoding", ""),
67              new HPackHeader("content-language", ""),
68              new HPackHeader("content-length", ""),
69              new HPackHeader("content-location", ""),
70              new HPackHeader("content-range", ""),
71              new HPackHeader("content-type", ""),
72              new HPackHeader("cookie", ""),
73              new HPackHeader("date", ""),
74              new HPackHeader("etag", ""),
75              new HPackHeader("expect", ""),
76              new HPackHeader("expires", ""),
77              new HPackHeader("from", ""),
78              new HPackHeader("host", ""),
79              new HPackHeader("if-match", ""),
80              new HPackHeader("if-modified-since", ""),
81              new HPackHeader("if-none-match", ""),
82              new HPackHeader("if-range", ""),
83              new HPackHeader("if-unmodified-since", ""),
84              new HPackHeader("last-modified", ""),
85              new HPackHeader("link", ""),
86              new HPackHeader("location", ""),
87              new HPackHeader("max-forwards", ""),
88              new HPackHeader("proxy-authenticate", ""),
89              new HPackHeader("proxy-authorization", ""),
90              new HPackHeader("range", ""),
91              new HPackHeader("referer", ""),
92              new HPackHeader("refresh", ""),
93              new HPackHeader("retry-after", ""),
94              new HPackHeader("server", ""),
95              new HPackHeader("set-cookie", ""),
96              new HPackHeader("strict-transport-security", ""),
97              new HPackHeader("transfer-encoding", ""),
98              new HPackHeader("user-agent", ""),
99              new HPackHeader("vary", ""),
100             new HPackHeader("via", ""),
101             new HPackHeader("www-authenticate", "")
102     };
103 
104     final static StaticTableck/StaticTable.html#StaticTable">StaticTable INSTANCE = new StaticTable(STANDARD_HEADERS);
105 
106     private final HPackHeader[] headers;
107     private final ConcurrentMap<String, CopyOnWriteArrayList<HPackEntry>> mapByName;
108 
109     StaticTable(final HPackHeader... headers) {
110         this.headers = headers;
111         this.mapByName = new ConcurrentHashMap<>();
112 
113         for (int i = 0; i < headers.length; i++) {
114             final HPackHeader header = headers[i];
115 
116             final String key = header.getName();
117             CopyOnWriteArrayList<HPackEntry> entries = this.mapByName.get(key);
118             if (entries == null) {
119                 entries = new CopyOnWriteArrayList<>(new HPackEntry[] { new InternalEntry(header, i) });
120                 this.mapByName.put(key, entries);
121             } else {
122                 entries.add(new InternalEntry(header, i));
123             }
124         }
125     }
126 
127     public int length() {
128         return this.headers.length;
129     }
130 
131     public HPackHeader get(final int index) {
132         return this.headers[index - 1];
133     }
134 
135     public List<HPackEntry> getByName(final String key) {
136         return this.mapByName.get(key);
137     }
138 
139     static class InternalEntry implements HPackEntry {
140 
141         private final HPackHeader header;
142         private final int index;
143 
144         InternalEntry(final HPackHeader header, final int index) {
145             this.header = header;
146             this.index = index;
147         }
148 
149         @Override
150         public int getIndex() {
151             return index + 1;
152         }
153 
154         @Override
155         public HPackHeader getHeader() {
156             return header;
157         }
158 
159     }
160 
161 }