• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2021 Tatsuhiro Tsujikawa
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 #include "http3.h"
26 
27 namespace nghttp2 {
28 
29 namespace http3 {
30 
31 namespace {
copy_headers_to_nva_internal(std::vector<nghttp3_nv> & nva,const HeaderRefs & headers,uint8_t nv_flags,uint32_t flags)32 void copy_headers_to_nva_internal(std::vector<nghttp3_nv> &nva,
33                                   const HeaderRefs &headers, uint8_t nv_flags,
34                                   uint32_t flags) {
35   auto it_forwarded = std::end(headers);
36   auto it_xff = std::end(headers);
37   auto it_xfp = std::end(headers);
38   auto it_via = std::end(headers);
39 
40   for (auto it = std::begin(headers); it != std::end(headers); ++it) {
41     auto kv = &(*it);
42     if (kv->name.empty() || kv->name[0] == ':') {
43       continue;
44     }
45     switch (kv->token) {
46     case http2::HD_COOKIE:
47     case http2::HD_CONNECTION:
48     case http2::HD_HOST:
49     case http2::HD_HTTP2_SETTINGS:
50     case http2::HD_KEEP_ALIVE:
51     case http2::HD_PROXY_CONNECTION:
52     case http2::HD_SERVER:
53     case http2::HD_TE:
54     case http2::HD_TRANSFER_ENCODING:
55     case http2::HD_UPGRADE:
56       continue;
57     case http2::HD_EARLY_DATA:
58       if (flags & http2::HDOP_STRIP_EARLY_DATA) {
59         continue;
60       }
61       break;
62     case http2::HD_SEC_WEBSOCKET_ACCEPT:
63       if (flags & http2::HDOP_STRIP_SEC_WEBSOCKET_ACCEPT) {
64         continue;
65       }
66       break;
67     case http2::HD_SEC_WEBSOCKET_KEY:
68       if (flags & http2::HDOP_STRIP_SEC_WEBSOCKET_KEY) {
69         continue;
70       }
71       break;
72     case http2::HD_FORWARDED:
73       if (flags & http2::HDOP_STRIP_FORWARDED) {
74         continue;
75       }
76 
77       if (it_forwarded == std::end(headers)) {
78         it_forwarded = it;
79         continue;
80       }
81 
82       kv = &(*it_forwarded);
83       it_forwarded = it;
84       break;
85     case http2::HD_X_FORWARDED_FOR:
86       if (flags & http2::HDOP_STRIP_X_FORWARDED_FOR) {
87         continue;
88       }
89 
90       if (it_xff == std::end(headers)) {
91         it_xff = it;
92         continue;
93       }
94 
95       kv = &(*it_xff);
96       it_xff = it;
97       break;
98     case http2::HD_X_FORWARDED_PROTO:
99       if (flags & http2::HDOP_STRIP_X_FORWARDED_PROTO) {
100         continue;
101       }
102 
103       if (it_xfp == std::end(headers)) {
104         it_xfp = it;
105         continue;
106       }
107 
108       kv = &(*it_xfp);
109       it_xfp = it;
110       break;
111     case http2::HD_VIA:
112       if (flags & http2::HDOP_STRIP_VIA) {
113         continue;
114       }
115 
116       if (it_via == std::end(headers)) {
117         it_via = it;
118         continue;
119       }
120 
121       kv = &(*it_via);
122       it_via = it;
123       break;
124     }
125     nva.push_back(make_field_flags(kv->name, kv->value,
126                                    nv_flags | never_index(kv->no_index)));
127   }
128 }
129 } // namespace
130 
copy_headers_to_nva_nocopy(std::vector<nghttp3_nv> & nva,const HeaderRefs & headers,uint32_t flags)131 void copy_headers_to_nva_nocopy(std::vector<nghttp3_nv> &nva,
132                                 const HeaderRefs &headers, uint32_t flags) {
133   copy_headers_to_nva_internal(
134       nva, headers,
135       NGHTTP3_NV_FLAG_NO_COPY_NAME | NGHTTP3_NV_FLAG_NO_COPY_VALUE, flags);
136 }
137 
138 } // namespace http3
139 
140 } // namespace nghttp2
141