1 //--------------------------------------------------------------------------
2 // Copyright (C) 2019-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation.  You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // http2_hpack_table.cc author Katura Harvey <katharve@cisco.com>
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "http2_enum.h"
25 #include "http2_flow_data.h"
26 #include "http2_hpack_table.h"
27 
28 #include <cstring>
29 
30 #define MAKE_TABLE_ENTRY(name, value) \
31     HpackTableEntry(strlen(name), (const uint8_t*)name, strlen(value), (const uint8_t*)value)
32 
33 using namespace Http2Enums;
34 
HpackTableEntry(const Field & copy_name,const Field & copy_value)35 HpackTableEntry::HpackTableEntry(const Field& copy_name, const Field& copy_value)
36 {
37     uint8_t* new_name = new uint8_t[copy_name.length()];
38     uint8_t* new_value = new uint8_t[copy_value.length()];
39     memcpy(new_name, copy_name.start(), copy_name.length());
40     memcpy(new_value, copy_value.start(), copy_value.length());
41 
42     name.set(copy_name.length(), new_name, true);
43     value.set(copy_value.length(), new_value, true);
44 }
45 
46 const HpackTableEntry HpackIndexTable::static_table[STATIC_MAX_INDEX + 1] =
47 {
48     MAKE_TABLE_ENTRY("", ""),
49     MAKE_TABLE_ENTRY(":authority", ""),
50     MAKE_TABLE_ENTRY(":method", "GET"),
51     MAKE_TABLE_ENTRY(":method", "POST"),
52     MAKE_TABLE_ENTRY(":path", "/"),
53     MAKE_TABLE_ENTRY(":path", "/index.html"),
54     MAKE_TABLE_ENTRY(":scheme", "http"),
55     MAKE_TABLE_ENTRY(":scheme", "https"),
56     MAKE_TABLE_ENTRY(":status", "200"),
57     MAKE_TABLE_ENTRY(":status", "204"),
58     MAKE_TABLE_ENTRY(":status", "206"),
59     MAKE_TABLE_ENTRY(":status", "304"),
60     MAKE_TABLE_ENTRY(":status", "400"),
61     MAKE_TABLE_ENTRY(":status", "404"),
62     MAKE_TABLE_ENTRY(":status", "500"),
63     MAKE_TABLE_ENTRY("accept-charset", ""),
64     MAKE_TABLE_ENTRY("accept-encoding", "gzip, deflate"),
65     MAKE_TABLE_ENTRY("accept-language", ""),
66     MAKE_TABLE_ENTRY("accept-ranges", ""),
67     MAKE_TABLE_ENTRY("accept", ""),
68     MAKE_TABLE_ENTRY("access-control-allow-origin", ""),
69     MAKE_TABLE_ENTRY("age", ""),
70     MAKE_TABLE_ENTRY("allow", ""),
71     MAKE_TABLE_ENTRY("authorization", ""),
72     MAKE_TABLE_ENTRY("cache-control", ""),
73     MAKE_TABLE_ENTRY("content-disposition", ""),
74     MAKE_TABLE_ENTRY("content-encoding", ""),
75     MAKE_TABLE_ENTRY("content-language", ""),
76     MAKE_TABLE_ENTRY("content-length", ""),
77     MAKE_TABLE_ENTRY("content-location", ""),
78     MAKE_TABLE_ENTRY("content-range", ""),
79     MAKE_TABLE_ENTRY("content-type", ""),
80     MAKE_TABLE_ENTRY("cookie", ""),
81     MAKE_TABLE_ENTRY("date", ""),
82     MAKE_TABLE_ENTRY("etag", ""),
83     MAKE_TABLE_ENTRY("expect", ""),
84     MAKE_TABLE_ENTRY("expires", ""),
85     MAKE_TABLE_ENTRY("from", ""),
86     MAKE_TABLE_ENTRY("host", ""),
87     MAKE_TABLE_ENTRY("if-match", ""),
88     MAKE_TABLE_ENTRY("if-modified-since", ""),
89     MAKE_TABLE_ENTRY("if-none-match", ""),
90     MAKE_TABLE_ENTRY("if-range", ""),
91     MAKE_TABLE_ENTRY("if-unmodified-since", ""),
92     MAKE_TABLE_ENTRY("last-modified", ""),
93     MAKE_TABLE_ENTRY("link", ""),
94     MAKE_TABLE_ENTRY("location", ""),
95     MAKE_TABLE_ENTRY("max-forwards", ""),
96     MAKE_TABLE_ENTRY("proxy-authenticate", ""),
97     MAKE_TABLE_ENTRY("proxy-authorization", ""),
98     MAKE_TABLE_ENTRY("range", ""),
99     MAKE_TABLE_ENTRY("referer", ""),
100     MAKE_TABLE_ENTRY("refresh", ""),
101     MAKE_TABLE_ENTRY("retry-after", ""),
102     MAKE_TABLE_ENTRY("server", ""),
103     MAKE_TABLE_ENTRY("set-cookie", ""),
104     MAKE_TABLE_ENTRY("strict-transport-security", ""),
105     MAKE_TABLE_ENTRY("transfer-encoding", ""),
106     MAKE_TABLE_ENTRY("user-agent", ""),
107     MAKE_TABLE_ENTRY("vary", ""),
108     MAKE_TABLE_ENTRY("via", ""),
109     MAKE_TABLE_ENTRY("www-authenticate", ""),
110 };
111 
lookup(uint64_t index) const112 const HpackTableEntry* HpackIndexTable::lookup(uint64_t index) const
113 {
114     if (index <= STATIC_MAX_INDEX)
115         return &static_table[index];
116     else
117         return dynamic_table.get_entry(index);
118 }
119 
add_index(const Field & name,const Field & value)120 bool HpackIndexTable::add_index(const Field& name, const Field& value)
121 {
122     return dynamic_table.add_entry(name, value);
123 }
124