1 /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
18 #include <apr_strings.h>
19 #include <apr_optional.h>
20 #include <apr_optional_hooks.h>
23 #include <http_core.h>
24 #include <http_config.h>
25 #include <http_connection.h>
26 #include <http_protocol.h>
27 #include <http_request.h>
32 #include "mod_http2.h"
33 #include "h2_private.h"
35 #include "h2_stream.h"
37 #include "h2_config.h"
40 #include "h2_request.h"
41 #include "h2_session.h"
44 #include "mod_http2.h"
46 const char *h2_tls_protos[] = {
50 const char *h2_clear_protos[] = {
54 const char *H2_MAGIC_TOKEN = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
56 /*******************************************************************************
57 * The optional mod_ssl functions we need.
59 static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *opt_ssl_engine_disable;
60 static APR_OPTIONAL_FN_TYPE(ssl_is_https) *opt_ssl_is_https;
61 static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *opt_ssl_var_lookup;
64 /*******************************************************************************
67 static const char *h2_err_descr[] = {
73 "stream closed", /* 0x5 */
78 "connect error", /* 0xa */
80 "inadequate security",
84 const char *h2_h2_err_description(unsigned int h2_error)
86 if (h2_error < (sizeof(h2_err_descr)/sizeof(h2_err_descr[0]))) {
87 return h2_err_descr[h2_error];
89 return "unknown http/2 error code";
92 /*******************************************************************************
93 * Check connection security requirements of RFC 7540
97 * Black Listed Ciphers from RFC 7549 Appendix A
100 static const char *RFC7540_names[] = {
101 /* ciphers with NULL encrpytion */
102 "NULL-MD5", /* TLS_NULL_WITH_NULL_NULL */
103 /* same */ /* TLS_RSA_WITH_NULL_MD5 */
104 "NULL-SHA", /* TLS_RSA_WITH_NULL_SHA */
105 "NULL-SHA256", /* TLS_RSA_WITH_NULL_SHA256 */
106 "PSK-NULL-SHA", /* TLS_PSK_WITH_NULL_SHA */
107 "DHE-PSK-NULL-SHA", /* TLS_DHE_PSK_WITH_NULL_SHA */
108 "RSA-PSK-NULL-SHA", /* TLS_RSA_PSK_WITH_NULL_SHA */
109 "PSK-NULL-SHA256", /* TLS_PSK_WITH_NULL_SHA256 */
110 "PSK-NULL-SHA384", /* TLS_PSK_WITH_NULL_SHA384 */
111 "DHE-PSK-NULL-SHA256", /* TLS_DHE_PSK_WITH_NULL_SHA256 */
112 "DHE-PSK-NULL-SHA384", /* TLS_DHE_PSK_WITH_NULL_SHA384 */
113 "RSA-PSK-NULL-SHA256", /* TLS_RSA_PSK_WITH_NULL_SHA256 */
114 "RSA-PSK-NULL-SHA384", /* TLS_RSA_PSK_WITH_NULL_SHA384 */
115 "ECDH-ECDSA-NULL-SHA", /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
116 "ECDHE-ECDSA-NULL-SHA", /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
117 "ECDH-RSA-NULL-SHA", /* TLS_ECDH_RSA_WITH_NULL_SHA */
118 "ECDHE-RSA-NULL-SHA", /* TLS_ECDHE_RSA_WITH_NULL_SHA */
119 "AECDH-NULL-SHA", /* TLS_ECDH_anon_WITH_NULL_SHA */
120 "ECDHE-PSK-NULL-SHA", /* TLS_ECDHE_PSK_WITH_NULL_SHA */
121 "ECDHE-PSK-NULL-SHA256", /* TLS_ECDHE_PSK_WITH_NULL_SHA256 */
122 "ECDHE-PSK-NULL-SHA384", /* TLS_ECDHE_PSK_WITH_NULL_SHA384 */
124 /* DES/3DES ciphers */
125 "PSK-3DES-EDE-CBC-SHA", /* TLS_PSK_WITH_3DES_EDE_CBC_SHA */
126 "DHE-PSK-3DES-EDE-CBC-SHA", /* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA */
127 "RSA-PSK-3DES-EDE-CBC-SHA", /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */
128 "ECDH-ECDSA-DES-CBC3-SHA", /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */
129 "ECDHE-ECDSA-DES-CBC3-SHA", /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */
130 "ECDH-RSA-DES-CBC3-SHA", /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */
131 "ECDHE-RSA-DES-CBC3-SHA", /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
132 "AECDH-DES-CBC3-SHA", /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
133 "SRP-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA */
134 "SRP-RSA-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA */
135 "SRP-DSS-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA */
136 "ECDHE-PSK-3DES-EDE-CBC-SHA", /* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA */
137 "DES-CBC-SHA", /* TLS_RSA_WITH_DES_CBC_SHA */
138 "DES-CBC3-SHA", /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
139 "DHE-DSS-DES-CBC3-SHA", /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
140 "DHE-RSA-DES-CBC-SHA", /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
141 "DHE-RSA-DES-CBC3-SHA", /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
142 "ADH-DES-CBC-SHA", /* TLS_DH_anon_WITH_DES_CBC_SHA */
143 "ADH-DES-CBC3-SHA", /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
144 "EXP-DH-DSS-DES-CBC-SHA", /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
145 "DH-DSS-DES-CBC-SHA", /* TLS_DH_DSS_WITH_DES_CBC_SHA */
146 "DH-DSS-DES-CBC3-SHA", /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
147 "EXP-DH-RSA-DES-CBC-SHA", /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
148 "DH-RSA-DES-CBC-SHA", /* TLS_DH_RSA_WITH_DES_CBC_SHA */
149 "DH-RSA-DES-CBC3-SHA", /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
151 /* blacklisted EXPORT ciphers */
152 "EXP-RC4-MD5", /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
153 "EXP-RC2-CBC-MD5", /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
154 "EXP-DES-CBC-SHA", /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
155 "EXP-DHE-DSS-DES-CBC-SHA", /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
156 "EXP-DHE-RSA-DES-CBC-SHA", /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
157 "EXP-ADH-DES-CBC-SHA", /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
158 "EXP-ADH-RC4-MD5", /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
160 /* blacklisted RC4 encryption */
161 "RC4-MD5", /* TLS_RSA_WITH_RC4_128_MD5 */
162 "RC4-SHA", /* TLS_RSA_WITH_RC4_128_SHA */
163 "ADH-RC4-MD5", /* TLS_DH_anon_WITH_RC4_128_MD5 */
164 "KRB5-RC4-SHA", /* TLS_KRB5_WITH_RC4_128_SHA */
165 "KRB5-RC4-MD5", /* TLS_KRB5_WITH_RC4_128_MD5 */
166 "EXP-KRB5-RC4-SHA", /* TLS_KRB5_EXPORT_WITH_RC4_40_SHA */
167 "EXP-KRB5-RC4-MD5", /* TLS_KRB5_EXPORT_WITH_RC4_40_MD5 */
168 "PSK-RC4-SHA", /* TLS_PSK_WITH_RC4_128_SHA */
169 "DHE-PSK-RC4-SHA", /* TLS_DHE_PSK_WITH_RC4_128_SHA */
170 "RSA-PSK-RC4-SHA", /* TLS_RSA_PSK_WITH_RC4_128_SHA */
171 "ECDH-ECDSA-RC4-SHA", /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
172 "ECDHE-ECDSA-RC4-SHA", /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */
173 "ECDH-RSA-RC4-SHA", /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
174 "ECDHE-RSA-RC4-SHA", /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
175 "AECDH-RC4-SHA", /* TLS_ECDH_anon_WITH_RC4_128_SHA */
176 "ECDHE-PSK-RC4-SHA", /* TLS_ECDHE_PSK_WITH_RC4_128_SHA */
178 /* blacklisted AES128 encrpytion ciphers */
179 "AES128-SHA256", /* TLS_RSA_WITH_AES_128_CBC_SHA */
180 "DH-DSS-AES128-SHA", /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */
181 "DH-RSA-AES128-SHA", /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */
182 "DHE-DSS-AES128-SHA", /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */
183 "DHE-RSA-AES128-SHA", /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
184 "ADH-AES128-SHA", /* TLS_DH_anon_WITH_AES_128_CBC_SHA */
185 "AES128-SHA256", /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
186 "DH-DSS-AES128-SHA256", /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */
187 "DH-RSA-AES128-SHA256", /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */
188 "DHE-DSS-AES128-SHA256", /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */
189 "DHE-RSA-AES128-SHA256", /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
190 "ECDH-ECDSA-AES128-SHA", /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */
191 "ECDHE-ECDSA-AES128-SHA", /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
192 "ECDH-RSA-AES128-SHA", /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
193 "ECDHE-RSA-AES128-SHA", /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
194 "AECDH-AES128-SHA", /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
195 "ECDHE-ECDSA-AES128-SHA256", /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 */
196 "ECDH-ECDSA-AES128-SHA256", /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */
197 "ECDHE-RSA-AES128-SHA256", /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */
198 "ECDH-RSA-AES128-SHA256", /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
199 "ADH-AES128-SHA256", /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
200 "PSK-AES128-CBC-SHA", /* TLS_PSK_WITH_AES_128_CBC_SHA */
201 "DHE-PSK-AES128-CBC-SHA", /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA */
202 "RSA-PSK-AES128-CBC-SHA", /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */
203 "PSK-AES128-CBC-SHA256", /* TLS_PSK_WITH_AES_128_CBC_SHA256 */
204 "DHE-PSK-AES128-CBC-SHA256", /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */
205 "RSA-PSK-AES128-CBC-SHA256", /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 */
206 "ECDHE-PSK-AES128-CBC-SHA", /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA */
207 "ECDHE-PSK-AES128-CBC-SHA256", /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */
208 "AES128-CCM", /* TLS_RSA_WITH_AES_128_CCM */
209 "AES128-CCM8", /* TLS_RSA_WITH_AES_128_CCM_8 */
210 "PSK-AES128-CCM", /* TLS_PSK_WITH_AES_128_CCM */
211 "PSK-AES128-CCM8", /* TLS_PSK_WITH_AES_128_CCM_8 */
212 "AES128-GCM-SHA256", /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
213 "DH-RSA-AES128-GCM-SHA256", /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */
214 "DH-DSS-AES128-GCM-SHA256", /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */
215 "ADH-AES128-GCM-SHA256", /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
216 "PSK-AES128-GCM-SHA256", /* TLS_PSK_WITH_AES_128_GCM_SHA256 */
217 "RSA-PSK-AES128-GCM-SHA256", /* TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 */
218 "ECDH-ECDSA-AES128-GCM-SHA256", /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */
219 "ECDH-RSA-AES128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
220 "SRP-AES-128-CBC-SHA", /* TLS_SRP_SHA_WITH_AES_128_CBC_SHA */
221 "SRP-RSA-AES-128-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA */
222 "SRP-DSS-AES-128-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA */
224 /* blacklisted AES256 encrpytion ciphers */
225 "AES256-SHA", /* TLS_RSA_WITH_AES_256_CBC_SHA */
226 "DH-DSS-AES256-SHA", /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */
227 "DH-RSA-AES256-SHA", /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */
228 "DHE-DSS-AES256-SHA", /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */
229 "DHE-RSA-AES256-SHA", /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
230 "ADH-AES256-SHA", /* TLS_DH_anon_WITH_AES_256_CBC_SHA */
231 "AES256-SHA256", /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
232 "DH-DSS-AES256-SHA256", /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */
233 "DH-RSA-AES256-SHA256", /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */
234 "DHE-DSS-AES256-SHA256", /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */
235 "DHE-RSA-AES256-SHA256", /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
236 "ADH-AES256-SHA256", /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
237 "ECDH-ECDSA-AES256-SHA", /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
238 "ECDHE-ECDSA-AES256-SHA", /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
239 "ECDH-RSA-AES256-SHA", /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
240 "ECDHE-RSA-AES256-SHA", /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
241 "AECDH-AES256-SHA", /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
242 "ECDHE-ECDSA-AES256-SHA384", /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 */
243 "ECDH-ECDSA-AES256-SHA384", /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */
244 "ECDHE-RSA-AES256-SHA384", /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */
245 "ECDH-RSA-AES256-SHA384", /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
246 "PSK-AES256-CBC-SHA", /* TLS_PSK_WITH_AES_256_CBC_SHA */
247 "DHE-PSK-AES256-CBC-SHA", /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA */
248 "RSA-PSK-AES256-CBC-SHA", /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */
249 "PSK-AES256-CBC-SHA384", /* TLS_PSK_WITH_AES_256_CBC_SHA384 */
250 "DHE-PSK-AES256-CBC-SHA384", /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */
251 "RSA-PSK-AES256-CBC-SHA384", /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 */
252 "ECDHE-PSK-AES256-CBC-SHA", /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA */
253 "ECDHE-PSK-AES256-CBC-SHA384", /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 */
254 "SRP-AES-256-CBC-SHA", /* TLS_SRP_SHA_WITH_AES_256_CBC_SHA */
255 "SRP-RSA-AES-256-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA */
256 "SRP-DSS-AES-256-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA */
257 "AES256-CCM", /* TLS_RSA_WITH_AES_256_CCM */
258 "AES256-CCM8", /* TLS_RSA_WITH_AES_256_CCM_8 */
259 "PSK-AES256-CCM", /* TLS_PSK_WITH_AES_256_CCM */
260 "PSK-AES256-CCM8", /* TLS_PSK_WITH_AES_256_CCM_8 */
261 "AES256-GCM-SHA384", /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
262 "DH-RSA-AES256-GCM-SHA384", /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */
263 "DH-DSS-AES256-GCM-SHA384", /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */
264 "ADH-AES256-GCM-SHA384", /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
265 "PSK-AES256-GCM-SHA384", /* TLS_PSK_WITH_AES_256_GCM_SHA384 */
266 "RSA-PSK-AES256-GCM-SHA384", /* TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 */
267 "ECDH-ECDSA-AES256-GCM-SHA384", /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */
268 "ECDH-RSA-AES256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
270 /* blacklisted CAMELLIA128 encrpytion ciphers */
271 "CAMELLIA128-SHA", /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
272 "DH-DSS-CAMELLIA128-SHA", /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */
273 "DH-RSA-CAMELLIA128-SHA", /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */
274 "DHE-DSS-CAMELLIA128-SHA", /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */
275 "DHE-RSA-CAMELLIA128-SHA", /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */
276 "ADH-CAMELLIA128-SHA", /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */
277 "ECDHE-ECDSA-CAMELLIA128-SHA256", /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
278 "ECDH-ECDSA-CAMELLIA128-SHA256", /* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
279 "ECDHE-RSA-CAMELLIA128-SHA256", /* TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
280 "ECDH-RSA-CAMELLIA128-SHA256", /* TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
281 "PSK-CAMELLIA128-SHA256", /* TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
282 "DHE-PSK-CAMELLIA128-SHA256", /* TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
283 "RSA-PSK-CAMELLIA128-SHA256", /* TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
284 "ECDHE-PSK-CAMELLIA128-SHA256", /* TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
285 "CAMELLIA128-GCM-SHA256", /* TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
286 "DH-RSA-CAMELLIA128-GCM-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
287 "DH-DSS-CAMELLIA128-GCM-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 */
288 "ADH-CAMELLIA128-GCM-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 */
289 "ECDH-ECDSA-CAMELLIA128-GCM-SHA256",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 */
290 "ECDH-RSA-CAMELLIA128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
291 "PSK-CAMELLIA128-GCM-SHA256", /* TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
292 "RSA-PSK-CAMELLIA128-GCM-SHA256", /* TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
293 "CAMELLIA128-SHA256", /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
294 "DH-DSS-CAMELLIA128-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
295 "DH-RSA-CAMELLIA128-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
296 "DHE-DSS-CAMELLIA128-SHA256", /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
297 "DHE-RSA-CAMELLIA128-SHA256", /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
298 "ADH-CAMELLIA128-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */
300 /* blacklisted CAMELLIA256 encrpytion ciphers */
301 "CAMELLIA256-SHA", /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
302 "DH-RSA-CAMELLIA256-SHA", /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */
303 "DH-DSS-CAMELLIA256-SHA", /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */
304 "DHE-DSS-CAMELLIA256-SHA", /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */
305 "DHE-RSA-CAMELLIA256-SHA", /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */
306 "ADH-CAMELLIA256-SHA", /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */
307 "ECDHE-ECDSA-CAMELLIA256-SHA384", /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
308 "ECDH-ECDSA-CAMELLIA256-SHA384", /* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
309 "ECDHE-RSA-CAMELLIA256-SHA384", /* TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
310 "ECDH-RSA-CAMELLIA256-SHA384", /* TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
311 "PSK-CAMELLIA256-SHA384", /* TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
312 "DHE-PSK-CAMELLIA256-SHA384", /* TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
313 "RSA-PSK-CAMELLIA256-SHA384", /* TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
314 "ECDHE-PSK-CAMELLIA256-SHA384", /* TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
315 "CAMELLIA256-SHA256", /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
316 "DH-DSS-CAMELLIA256-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
317 "DH-RSA-CAMELLIA256-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
318 "DHE-DSS-CAMELLIA256-SHA256", /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
319 "DHE-RSA-CAMELLIA256-SHA256", /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
320 "ADH-CAMELLIA256-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */
321 "CAMELLIA256-GCM-SHA384", /* TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
322 "DH-RSA-CAMELLIA256-GCM-SHA384", /* TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
323 "DH-DSS-CAMELLIA256-GCM-SHA384", /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */
324 "ADH-CAMELLIA256-GCM-SHA384", /* TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 */
325 "ECDH-ECDSA-CAMELLIA256-GCM-SHA384",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */
326 "ECDH-RSA-CAMELLIA256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
327 "PSK-CAMELLIA256-GCM-SHA384", /* TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
328 "RSA-PSK-CAMELLIA256-GCM-SHA384", /* TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
330 /* The blacklisted ARIA encrpytion ciphers */
331 "ARIA128-SHA256", /* TLS_RSA_WITH_ARIA_128_CBC_SHA256 */
332 "ARIA256-SHA384", /* TLS_RSA_WITH_ARIA_256_CBC_SHA384 */
333 "DH-DSS-ARIA128-SHA256", /* TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 */
334 "DH-DSS-ARIA256-SHA384", /* TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 */
335 "DH-RSA-ARIA128-SHA256", /* TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 */
336 "DH-RSA-ARIA256-SHA384", /* TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 */
337 "DHE-DSS-ARIA128-SHA256", /* TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 */
338 "DHE-DSS-ARIA256-SHA384", /* TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 */
339 "DHE-RSA-ARIA128-SHA256", /* TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 */
340 "DHE-RSA-ARIA256-SHA384", /* TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 */
341 "ADH-ARIA128-SHA256", /* TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 */
342 "ADH-ARIA256-SHA384", /* TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 */
343 "ECDHE-ECDSA-ARIA128-SHA256", /* TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 */
344 "ECDHE-ECDSA-ARIA256-SHA384", /* TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 */
345 "ECDH-ECDSA-ARIA128-SHA256", /* TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 */
346 "ECDH-ECDSA-ARIA256-SHA384", /* TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 */
347 "ECDHE-RSA-ARIA128-SHA256", /* TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 */
348 "ECDHE-RSA-ARIA256-SHA384", /* TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 */
349 "ECDH-RSA-ARIA128-SHA256", /* TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 */
350 "ECDH-RSA-ARIA256-SHA384", /* TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 */
351 "ARIA128-GCM-SHA256", /* TLS_RSA_WITH_ARIA_128_GCM_SHA256 */
352 "ARIA256-GCM-SHA384", /* TLS_RSA_WITH_ARIA_256_GCM_SHA384 */
353 "DH-DSS-ARIA128-GCM-SHA256", /* TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 */
354 "DH-DSS-ARIA256-GCM-SHA384", /* TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 */
355 "DH-RSA-ARIA128-GCM-SHA256", /* TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 */
356 "DH-RSA-ARIA256-GCM-SHA384", /* TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 */
357 "ADH-ARIA128-GCM-SHA256", /* TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 */
358 "ADH-ARIA256-GCM-SHA384", /* TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 */
359 "ECDH-ECDSA-ARIA128-GCM-SHA256", /* TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 */
360 "ECDH-ECDSA-ARIA256-GCM-SHA384", /* TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 */
361 "ECDH-RSA-ARIA128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 */
362 "ECDH-RSA-ARIA256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 */
363 "PSK-ARIA128-SHA256", /* TLS_PSK_WITH_ARIA_128_CBC_SHA256 */
364 "PSK-ARIA256-SHA384", /* TLS_PSK_WITH_ARIA_256_CBC_SHA384 */
365 "DHE-PSK-ARIA128-SHA256", /* TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 */
366 "DHE-PSK-ARIA256-SHA384", /* TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 */
367 "RSA-PSK-ARIA128-SHA256", /* TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 */
368 "RSA-PSK-ARIA256-SHA384", /* TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 */
369 "ARIA128-GCM-SHA256", /* TLS_PSK_WITH_ARIA_128_GCM_SHA256 */
370 "ARIA256-GCM-SHA384", /* TLS_PSK_WITH_ARIA_256_GCM_SHA384 */
371 "RSA-PSK-ARIA128-GCM-SHA256", /* TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 */
372 "RSA-PSK-ARIA256-GCM-SHA384", /* TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 */
373 "ECDHE-PSK-ARIA128-SHA256", /* TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 */
374 "ECDHE-PSK-ARIA256-SHA384", /* TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */
376 /* blacklisted SEED encryptions */
377 "SEED-SHA", /*TLS_RSA_WITH_SEED_CBC_SHA */
378 "DH-DSS-SEED-SHA", /* TLS_DH_DSS_WITH_SEED_CBC_SHA */
379 "DH-RSA-SEED-SHA", /* TLS_DH_RSA_WITH_SEED_CBC_SHA */
380 "DHE-DSS-SEED-SHA", /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */
381 "DHE-RSA-SEED-SHA", /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */
382 "ADH-SEED-SHA", /* TLS_DH_anon_WITH_SEED_CBC_SHA */
384 /* blacklisted KRB5 ciphers */
385 "KRB5-DES-CBC-SHA", /* TLS_KRB5_WITH_DES_CBC_SHA */
386 "KRB5-DES-CBC3-SHA", /* TLS_KRB5_WITH_3DES_EDE_CBC_SHA */
387 "KRB5-IDEA-CBC-SHA", /* TLS_KRB5_WITH_IDEA_CBC_SHA */
388 "KRB5-DES-CBC-MD5", /* TLS_KRB5_WITH_DES_CBC_MD5 */
389 "KRB5-DES-CBC3-MD5", /* TLS_KRB5_WITH_3DES_EDE_CBC_MD5 */
390 "KRB5-IDEA-CBC-MD5", /* TLS_KRB5_WITH_IDEA_CBC_MD5 */
391 "EXP-KRB5-DES-CBC-SHA", /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA */
392 "EXP-KRB5-DES-CBC-MD5", /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */
393 "EXP-KRB5-RC2-CBC-SHA", /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA */
394 "EXP-KRB5-RC2-CBC-MD5", /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 */
396 /* blacklisted exoticas */
397 "DHE-DSS-CBC-SHA", /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
398 "IDEA-CBC-SHA", /* TLS_RSA_WITH_IDEA_CBC_SHA */
400 /* not really sure if the following names are correct */
401 "SSL3_CK_SCSV", /* TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
402 "SSL3_CK_FALLBACK_SCSV"
404 static size_t RFC7540_names_LEN = sizeof(RFC7540_names)/sizeof(RFC7540_names[0]);
407 static apr_hash_t *BLCNames;
409 static void cipher_init(apr_pool_t *pool)
411 apr_hash_t *hash = apr_hash_make(pool);
416 for (i = 0; i < RFC7540_names_LEN; ++i) {
417 apr_hash_set(hash, RFC7540_names[i], APR_HASH_KEY_STRING, source);
423 static int cipher_is_blacklisted(const char *cipher, const char **psource)
425 *psource = apr_hash_get(BLCNames, cipher, APR_HASH_KEY_STRING);
429 /*******************************************************************************
430 * Hooks for processing incoming connections:
431 * - process_conn take over connection in case of h2
433 static int h2_h2_process_conn(conn_rec* c);
434 static int h2_h2_pre_close_conn(conn_rec* c);
435 static int h2_h2_post_read_req(request_rec *r);
437 /*******************************************************************************
438 * Once per lifetime init, retrieve optional functions
440 apr_status_t h2_h2_init(apr_pool_t *pool, server_rec *s)
443 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "h2_h2, child_init");
444 opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
445 opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
446 opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
448 if (!opt_ssl_is_https || !opt_ssl_var_lookup) {
449 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
450 APLOGNO(02951) "mod_ssl does not seem to be enabled");
458 int h2_h2_is_tls(conn_rec *c)
460 return opt_ssl_is_https && opt_ssl_is_https(c);
463 int h2_is_acceptable_connection(conn_rec *c, int require_all)
465 int is_tls = h2_h2_is_tls(c);
466 const h2_config *cfg = h2_config_get(c);
468 if (is_tls && h2_config_geti(cfg, H2_CONF_MODERN_TLS_ONLY) > 0) {
469 /* Check TLS connection for modern TLS parameters, as defined in
470 * RFC 7540 and https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
472 apr_pool_t *pool = c->pool;
473 server_rec *s = c->base_server;
476 if (!opt_ssl_var_lookup) {
477 /* unable to check */
481 /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
483 val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_PROTOCOL");
485 if (strncmp("TLS", val, 3)
486 || !strcmp("TLSv1", val)
487 || !strcmp("TLSv1.1", val)) {
488 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03050)
489 "h2_h2(%ld): tls protocol not suitable: %s",
494 else if (require_all) {
495 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03051)
496 "h2_h2(%ld): tls protocol is indetermined", (long)c->id);
500 /* Check TLS cipher blacklist
502 val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_CIPHER");
505 if (cipher_is_blacklisted(val, &source)) {
506 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03052)
507 "h2_h2(%ld): tls cipher %s blacklisted by %s",
508 (long)c->id, val, source);
512 else if (require_all) {
513 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03053)
514 "h2_h2(%ld): tls cipher is indetermined", (long)c->id);
521 int h2_allows_h2_direct(conn_rec *c)
523 const h2_config *cfg = h2_config_get(c);
524 int is_tls = h2_h2_is_tls(c);
525 const char *needed_protocol = is_tls? "h2" : "h2c";
526 int h2_direct = h2_config_geti(cfg, H2_CONF_DIRECT);
529 h2_direct = is_tls? 0 : 1;
532 && ap_is_allowed_protocol(c, NULL, NULL, needed_protocol));
535 int h2_allows_h2_upgrade(conn_rec *c)
537 const h2_config *cfg = h2_config_get(c);
538 int h2_upgrade = h2_config_geti(cfg, H2_CONF_UPGRADE);
540 return h2_upgrade > 0 || (h2_upgrade < 0 && !h2_h2_is_tls(c));
543 /*******************************************************************************
544 * Register various hooks
546 static const char* const mod_ssl[] = { "mod_ssl.c", NULL};
547 static const char* const mod_reqtimeout[] = { "mod_reqtimeout.c", NULL};
549 void h2_h2_register_hooks(void)
551 /* Our main processing needs to run quite late. Definitely after mod_ssl,
552 * as we need its connection filters, but also before reqtimeout as its
553 * method of timeouts is specific to HTTP/1.1 (as of now).
554 * The core HTTP/1 processing run as REALLY_LAST, so we will have
555 * a chance to take over before it.
557 ap_hook_process_connection(h2_h2_process_conn,
558 mod_ssl, mod_reqtimeout, APR_HOOK_LAST);
560 /* One last chance to properly say goodbye if we have not done so
562 ap_hook_pre_close_connection(h2_h2_pre_close_conn, NULL, mod_ssl, APR_HOOK_LAST);
564 /* With "H2SerializeHeaders On", we install the filter in this hook
565 * that parses the response. This needs to happen before any other post
566 * read function terminates the request with an error. Otherwise we will
567 * never see the response.
569 ap_hook_post_read_request(h2_h2_post_read_req, NULL, NULL, APR_HOOK_REALLY_FIRST);
572 int h2_h2_process_conn(conn_rec* c)
581 ctx = h2_ctx_get(c, 0);
582 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn");
583 if (h2_ctx_is_task(ctx)) {
584 /* our stream pseudo connection */
585 ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "h2_h2, task, declined");
589 if (!ctx && c->keepalives == 0) {
590 const char *proto = ap_get_protocol(c);
592 if (APLOGctrace1(c)) {
593 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn, "
594 "new connection using protocol '%s', direct=%d, "
595 "tls acceptable=%d", proto, h2_allows_h2_direct(c),
596 h2_is_acceptable_connection(c, 1));
599 if (!strcmp(AP_PROTOCOL_HTTP1, proto)
600 && h2_allows_h2_direct(c)
601 && h2_is_acceptable_connection(c, 1)) {
602 /* Fresh connection still is on http/1.1 and H2Direct is enabled.
603 * Otherwise connection is in a fully acceptable state.
604 * -> peek at the first 24 incoming bytes
606 apr_bucket_brigade *temp;
610 temp = apr_brigade_create(c->pool, c->bucket_alloc);
611 status = ap_get_brigade(c->input_filters, temp,
612 AP_MODE_SPECULATIVE, APR_BLOCK_READ, 24);
614 if (status != APR_SUCCESS) {
615 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c, APLOGNO(03054)
616 "h2_h2, error reading 24 bytes speculative");
617 apr_brigade_destroy(temp);
621 apr_brigade_pflatten(temp, &s, &slen, c->pool);
622 if ((slen >= 24) && !memcmp(H2_MAGIC_TOKEN, s, 24)) {
623 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
624 "h2_h2, direct mode detected");
626 ctx = h2_ctx_get(c, 1);
628 h2_ctx_protocol_set(ctx, h2_h2_is_tls(c)? "h2" : "h2c");
631 ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
632 "h2_h2, not detected in %d bytes: %s",
636 apr_brigade_destroy(temp);
641 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "process_conn");
642 if (!h2_ctx_session_get(ctx)) {
643 status = h2_conn_setup(ctx, c, NULL);
644 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, c, "conn_setup");
645 if (status != APR_SUCCESS) {
649 return h2_conn_run(ctx, c);
652 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, declined");
656 static int h2_h2_pre_close_conn(conn_rec *c)
660 /* slave connection? */
665 ctx = h2_ctx_get(c, 0);
667 /* If the session has been closed correctly already, we will not
668 * fiond a h2_ctx here. The presence indicates that the session
669 * is still ongoing. */
670 return h2_conn_pre_close(ctx, c);
675 static int h2_h2_post_read_req(request_rec *r)
677 /* slave connection? */
678 if (r->connection->master) {
679 h2_ctx *ctx = h2_ctx_rget(r);
680 struct h2_task *task = h2_ctx_get_task(ctx);
681 /* This hook will get called twice on internal redirects. Take care
682 * that we manipulate filters only once. */
683 if (task && !task->filters_set) {
686 /* setup the correct output filters to process the response
687 * on the proper mod_http2 way. */
688 ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "adding task output filter");
689 if (task->ser_headers) {
690 ap_add_output_filter("H1_TO_H2_RESP", task, r, r->connection);
693 /* replace the core http filter that formats response headers
694 * in HTTP/1 with our own that collects status and headers */
695 ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
696 ap_add_output_filter("H2_RESPONSE", task, r, r->connection);
699 /* trailers processing. Incoming trailers are added to this
700 * request via our h2 input filter, outgoing trailers
701 * in a special h2 out filter. */
702 for (f = r->input_filters; f; f = f->next) {
703 if (!strcmp("H2_TO_H1", f->frec->name)) {
708 ap_add_output_filter("H2_TRAILERS", task, r, r->connection);
709 task->filters_set = 1;