1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
19 * Licensed under the Apache License, Version 2.0 (the "License");
20 * you may not use this file except in compliance with the License.
21 * You may obtain a copy of the License at
23 * http://www.apache.org/licenses/LICENSE-2.0
25 * Unless required by applicable law or agreed to in writing, software
26 * distributed under the License is distributed on an "AS IS" BASIS,
27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28 * See the License for the specific language governing permissions and
29 * limitations under the License.
34 #include <apr_strings.h>
35 #include <apr_optional.h>
36 #include <apr_optional_hooks.h>
39 #include <http_core.h>
40 #include <http_config.h>
41 #include <http_connection.h>
42 #include <http_protocol.h>
43 #include <http_request.h>
48 #include "mod_http2.h"
49 #include "h2_private.h"
51 #include "h2_bucket_beam.h"
52 #include "h2_stream.h"
54 #include "h2_config.h"
57 #include "h2_filter.h"
58 #include "h2_request.h"
59 #include "h2_headers.h"
60 #include "h2_session.h"
63 #include "mod_http2.h"
65 const char *h2_tls_protos[] = {
69 const char *h2_clear_protos[] = {
73 const char *H2_MAGIC_TOKEN = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
75 /*******************************************************************************
76 * The optional mod_ssl functions we need.
78 static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *opt_ssl_engine_disable;
79 static APR_OPTIONAL_FN_TYPE(ssl_is_https) *opt_ssl_is_https;
80 static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *opt_ssl_var_lookup;
83 /*******************************************************************************
86 static const char *h2_err_descr[] = {
92 "stream closed", /* 0x5 */
97 "connect error", /* 0xa */
99 "inadequate security",
103 const char *h2_h2_err_description(unsigned int h2_error)
105 if (h2_error < (sizeof(h2_err_descr)/sizeof(h2_err_descr[0]))) {
106 return h2_err_descr[h2_error];
108 return "unknown http/2 error code";
111 /*******************************************************************************
112 * Check connection security requirements of RFC 7540
116 * Black Listed Ciphers from RFC 7549 Appendix A
119 static const char *RFC7540_names[] = {
120 /* ciphers with NULL encrpytion */
121 "NULL-MD5", /* TLS_NULL_WITH_NULL_NULL */
122 /* same */ /* TLS_RSA_WITH_NULL_MD5 */
123 "NULL-SHA", /* TLS_RSA_WITH_NULL_SHA */
124 "NULL-SHA256", /* TLS_RSA_WITH_NULL_SHA256 */
125 "PSK-NULL-SHA", /* TLS_PSK_WITH_NULL_SHA */
126 "DHE-PSK-NULL-SHA", /* TLS_DHE_PSK_WITH_NULL_SHA */
127 "RSA-PSK-NULL-SHA", /* TLS_RSA_PSK_WITH_NULL_SHA */
128 "PSK-NULL-SHA256", /* TLS_PSK_WITH_NULL_SHA256 */
129 "PSK-NULL-SHA384", /* TLS_PSK_WITH_NULL_SHA384 */
130 "DHE-PSK-NULL-SHA256", /* TLS_DHE_PSK_WITH_NULL_SHA256 */
131 "DHE-PSK-NULL-SHA384", /* TLS_DHE_PSK_WITH_NULL_SHA384 */
132 "RSA-PSK-NULL-SHA256", /* TLS_RSA_PSK_WITH_NULL_SHA256 */
133 "RSA-PSK-NULL-SHA384", /* TLS_RSA_PSK_WITH_NULL_SHA384 */
134 "ECDH-ECDSA-NULL-SHA", /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
135 "ECDHE-ECDSA-NULL-SHA", /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
136 "ECDH-RSA-NULL-SHA", /* TLS_ECDH_RSA_WITH_NULL_SHA */
137 "ECDHE-RSA-NULL-SHA", /* TLS_ECDHE_RSA_WITH_NULL_SHA */
138 "AECDH-NULL-SHA", /* TLS_ECDH_anon_WITH_NULL_SHA */
139 "ECDHE-PSK-NULL-SHA", /* TLS_ECDHE_PSK_WITH_NULL_SHA */
140 "ECDHE-PSK-NULL-SHA256", /* TLS_ECDHE_PSK_WITH_NULL_SHA256 */
141 "ECDHE-PSK-NULL-SHA384", /* TLS_ECDHE_PSK_WITH_NULL_SHA384 */
143 /* DES/3DES ciphers */
144 "PSK-3DES-EDE-CBC-SHA", /* TLS_PSK_WITH_3DES_EDE_CBC_SHA */
145 "DHE-PSK-3DES-EDE-CBC-SHA", /* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA */
146 "RSA-PSK-3DES-EDE-CBC-SHA", /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */
147 "ECDH-ECDSA-DES-CBC3-SHA", /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */
148 "ECDHE-ECDSA-DES-CBC3-SHA", /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */
149 "ECDH-RSA-DES-CBC3-SHA", /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */
150 "ECDHE-RSA-DES-CBC3-SHA", /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
151 "AECDH-DES-CBC3-SHA", /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
152 "SRP-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA */
153 "SRP-RSA-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA */
154 "SRP-DSS-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA */
155 "ECDHE-PSK-3DES-EDE-CBC-SHA", /* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA */
156 "DES-CBC-SHA", /* TLS_RSA_WITH_DES_CBC_SHA */
157 "DES-CBC3-SHA", /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
158 "DHE-DSS-DES-CBC3-SHA", /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
159 "DHE-RSA-DES-CBC-SHA", /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
160 "DHE-RSA-DES-CBC3-SHA", /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
161 "ADH-DES-CBC-SHA", /* TLS_DH_anon_WITH_DES_CBC_SHA */
162 "ADH-DES-CBC3-SHA", /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
163 "EXP-DH-DSS-DES-CBC-SHA", /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
164 "DH-DSS-DES-CBC-SHA", /* TLS_DH_DSS_WITH_DES_CBC_SHA */
165 "DH-DSS-DES-CBC3-SHA", /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
166 "EXP-DH-RSA-DES-CBC-SHA", /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
167 "DH-RSA-DES-CBC-SHA", /* TLS_DH_RSA_WITH_DES_CBC_SHA */
168 "DH-RSA-DES-CBC3-SHA", /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
170 /* blacklisted EXPORT ciphers */
171 "EXP-RC4-MD5", /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
172 "EXP-RC2-CBC-MD5", /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
173 "EXP-DES-CBC-SHA", /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
174 "EXP-DHE-DSS-DES-CBC-SHA", /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
175 "EXP-DHE-RSA-DES-CBC-SHA", /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
176 "EXP-ADH-DES-CBC-SHA", /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
177 "EXP-ADH-RC4-MD5", /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
179 /* blacklisted RC4 encryption */
180 "RC4-MD5", /* TLS_RSA_WITH_RC4_128_MD5 */
181 "RC4-SHA", /* TLS_RSA_WITH_RC4_128_SHA */
182 "ADH-RC4-MD5", /* TLS_DH_anon_WITH_RC4_128_MD5 */
183 "KRB5-RC4-SHA", /* TLS_KRB5_WITH_RC4_128_SHA */
184 "KRB5-RC4-MD5", /* TLS_KRB5_WITH_RC4_128_MD5 */
185 "EXP-KRB5-RC4-SHA", /* TLS_KRB5_EXPORT_WITH_RC4_40_SHA */
186 "EXP-KRB5-RC4-MD5", /* TLS_KRB5_EXPORT_WITH_RC4_40_MD5 */
187 "PSK-RC4-SHA", /* TLS_PSK_WITH_RC4_128_SHA */
188 "DHE-PSK-RC4-SHA", /* TLS_DHE_PSK_WITH_RC4_128_SHA */
189 "RSA-PSK-RC4-SHA", /* TLS_RSA_PSK_WITH_RC4_128_SHA */
190 "ECDH-ECDSA-RC4-SHA", /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
191 "ECDHE-ECDSA-RC4-SHA", /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */
192 "ECDH-RSA-RC4-SHA", /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
193 "ECDHE-RSA-RC4-SHA", /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
194 "AECDH-RC4-SHA", /* TLS_ECDH_anon_WITH_RC4_128_SHA */
195 "ECDHE-PSK-RC4-SHA", /* TLS_ECDHE_PSK_WITH_RC4_128_SHA */
197 /* blacklisted AES128 encrpytion ciphers */
198 "AES128-SHA256", /* TLS_RSA_WITH_AES_128_CBC_SHA */
199 "DH-DSS-AES128-SHA", /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */
200 "DH-RSA-AES128-SHA", /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */
201 "DHE-DSS-AES128-SHA", /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */
202 "DHE-RSA-AES128-SHA", /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
203 "ADH-AES128-SHA", /* TLS_DH_anon_WITH_AES_128_CBC_SHA */
204 "AES128-SHA256", /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
205 "DH-DSS-AES128-SHA256", /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */
206 "DH-RSA-AES128-SHA256", /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */
207 "DHE-DSS-AES128-SHA256", /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */
208 "DHE-RSA-AES128-SHA256", /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
209 "ECDH-ECDSA-AES128-SHA", /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */
210 "ECDHE-ECDSA-AES128-SHA", /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
211 "ECDH-RSA-AES128-SHA", /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
212 "ECDHE-RSA-AES128-SHA", /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
213 "AECDH-AES128-SHA", /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
214 "ECDHE-ECDSA-AES128-SHA256", /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 */
215 "ECDH-ECDSA-AES128-SHA256", /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */
216 "ECDHE-RSA-AES128-SHA256", /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */
217 "ECDH-RSA-AES128-SHA256", /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
218 "ADH-AES128-SHA256", /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
219 "PSK-AES128-CBC-SHA", /* TLS_PSK_WITH_AES_128_CBC_SHA */
220 "DHE-PSK-AES128-CBC-SHA", /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA */
221 "RSA-PSK-AES128-CBC-SHA", /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */
222 "PSK-AES128-CBC-SHA256", /* TLS_PSK_WITH_AES_128_CBC_SHA256 */
223 "DHE-PSK-AES128-CBC-SHA256", /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */
224 "RSA-PSK-AES128-CBC-SHA256", /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 */
225 "ECDHE-PSK-AES128-CBC-SHA", /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA */
226 "ECDHE-PSK-AES128-CBC-SHA256", /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */
227 "AES128-CCM", /* TLS_RSA_WITH_AES_128_CCM */
228 "AES128-CCM8", /* TLS_RSA_WITH_AES_128_CCM_8 */
229 "PSK-AES128-CCM", /* TLS_PSK_WITH_AES_128_CCM */
230 "PSK-AES128-CCM8", /* TLS_PSK_WITH_AES_128_CCM_8 */
231 "AES128-GCM-SHA256", /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
232 "DH-RSA-AES128-GCM-SHA256", /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */
233 "DH-DSS-AES128-GCM-SHA256", /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */
234 "ADH-AES128-GCM-SHA256", /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
235 "PSK-AES128-GCM-SHA256", /* TLS_PSK_WITH_AES_128_GCM_SHA256 */
236 "RSA-PSK-AES128-GCM-SHA256", /* TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 */
237 "ECDH-ECDSA-AES128-GCM-SHA256", /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */
238 "ECDH-RSA-AES128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
239 "SRP-AES-128-CBC-SHA", /* TLS_SRP_SHA_WITH_AES_128_CBC_SHA */
240 "SRP-RSA-AES-128-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA */
241 "SRP-DSS-AES-128-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA */
243 /* blacklisted AES256 encrpytion ciphers */
244 "AES256-SHA", /* TLS_RSA_WITH_AES_256_CBC_SHA */
245 "DH-DSS-AES256-SHA", /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */
246 "DH-RSA-AES256-SHA", /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */
247 "DHE-DSS-AES256-SHA", /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */
248 "DHE-RSA-AES256-SHA", /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
249 "ADH-AES256-SHA", /* TLS_DH_anon_WITH_AES_256_CBC_SHA */
250 "AES256-SHA256", /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
251 "DH-DSS-AES256-SHA256", /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */
252 "DH-RSA-AES256-SHA256", /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */
253 "DHE-DSS-AES256-SHA256", /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */
254 "DHE-RSA-AES256-SHA256", /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
255 "ADH-AES256-SHA256", /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
256 "ECDH-ECDSA-AES256-SHA", /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
257 "ECDHE-ECDSA-AES256-SHA", /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
258 "ECDH-RSA-AES256-SHA", /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
259 "ECDHE-RSA-AES256-SHA", /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
260 "AECDH-AES256-SHA", /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
261 "ECDHE-ECDSA-AES256-SHA384", /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 */
262 "ECDH-ECDSA-AES256-SHA384", /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */
263 "ECDHE-RSA-AES256-SHA384", /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */
264 "ECDH-RSA-AES256-SHA384", /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
265 "PSK-AES256-CBC-SHA", /* TLS_PSK_WITH_AES_256_CBC_SHA */
266 "DHE-PSK-AES256-CBC-SHA", /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA */
267 "RSA-PSK-AES256-CBC-SHA", /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */
268 "PSK-AES256-CBC-SHA384", /* TLS_PSK_WITH_AES_256_CBC_SHA384 */
269 "DHE-PSK-AES256-CBC-SHA384", /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */
270 "RSA-PSK-AES256-CBC-SHA384", /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 */
271 "ECDHE-PSK-AES256-CBC-SHA", /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA */
272 "ECDHE-PSK-AES256-CBC-SHA384", /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 */
273 "SRP-AES-256-CBC-SHA", /* TLS_SRP_SHA_WITH_AES_256_CBC_SHA */
274 "SRP-RSA-AES-256-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA */
275 "SRP-DSS-AES-256-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA */
276 "AES256-CCM", /* TLS_RSA_WITH_AES_256_CCM */
277 "AES256-CCM8", /* TLS_RSA_WITH_AES_256_CCM_8 */
278 "PSK-AES256-CCM", /* TLS_PSK_WITH_AES_256_CCM */
279 "PSK-AES256-CCM8", /* TLS_PSK_WITH_AES_256_CCM_8 */
280 "AES256-GCM-SHA384", /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
281 "DH-RSA-AES256-GCM-SHA384", /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */
282 "DH-DSS-AES256-GCM-SHA384", /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */
283 "ADH-AES256-GCM-SHA384", /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
284 "PSK-AES256-GCM-SHA384", /* TLS_PSK_WITH_AES_256_GCM_SHA384 */
285 "RSA-PSK-AES256-GCM-SHA384", /* TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 */
286 "ECDH-ECDSA-AES256-GCM-SHA384", /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */
287 "ECDH-RSA-AES256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
289 /* blacklisted CAMELLIA128 encrpytion ciphers */
290 "CAMELLIA128-SHA", /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
291 "DH-DSS-CAMELLIA128-SHA", /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */
292 "DH-RSA-CAMELLIA128-SHA", /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */
293 "DHE-DSS-CAMELLIA128-SHA", /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */
294 "DHE-RSA-CAMELLIA128-SHA", /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */
295 "ADH-CAMELLIA128-SHA", /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */
296 "ECDHE-ECDSA-CAMELLIA128-SHA256", /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
297 "ECDH-ECDSA-CAMELLIA128-SHA256", /* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
298 "ECDHE-RSA-CAMELLIA128-SHA256", /* TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
299 "ECDH-RSA-CAMELLIA128-SHA256", /* TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
300 "PSK-CAMELLIA128-SHA256", /* TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
301 "DHE-PSK-CAMELLIA128-SHA256", /* TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
302 "RSA-PSK-CAMELLIA128-SHA256", /* TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
303 "ECDHE-PSK-CAMELLIA128-SHA256", /* TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
304 "CAMELLIA128-GCM-SHA256", /* TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
305 "DH-RSA-CAMELLIA128-GCM-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
306 "DH-DSS-CAMELLIA128-GCM-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 */
307 "ADH-CAMELLIA128-GCM-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 */
308 "ECDH-ECDSA-CAMELLIA128-GCM-SHA256",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 */
309 "ECDH-RSA-CAMELLIA128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
310 "PSK-CAMELLIA128-GCM-SHA256", /* TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
311 "RSA-PSK-CAMELLIA128-GCM-SHA256", /* TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
312 "CAMELLIA128-SHA256", /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
313 "DH-DSS-CAMELLIA128-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
314 "DH-RSA-CAMELLIA128-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
315 "DHE-DSS-CAMELLIA128-SHA256", /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
316 "DHE-RSA-CAMELLIA128-SHA256", /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
317 "ADH-CAMELLIA128-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */
319 /* blacklisted CAMELLIA256 encrpytion ciphers */
320 "CAMELLIA256-SHA", /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
321 "DH-RSA-CAMELLIA256-SHA", /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */
322 "DH-DSS-CAMELLIA256-SHA", /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */
323 "DHE-DSS-CAMELLIA256-SHA", /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */
324 "DHE-RSA-CAMELLIA256-SHA", /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */
325 "ADH-CAMELLIA256-SHA", /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */
326 "ECDHE-ECDSA-CAMELLIA256-SHA384", /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
327 "ECDH-ECDSA-CAMELLIA256-SHA384", /* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
328 "ECDHE-RSA-CAMELLIA256-SHA384", /* TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
329 "ECDH-RSA-CAMELLIA256-SHA384", /* TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
330 "PSK-CAMELLIA256-SHA384", /* TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
331 "DHE-PSK-CAMELLIA256-SHA384", /* TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
332 "RSA-PSK-CAMELLIA256-SHA384", /* TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
333 "ECDHE-PSK-CAMELLIA256-SHA384", /* TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
334 "CAMELLIA256-SHA256", /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
335 "DH-DSS-CAMELLIA256-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
336 "DH-RSA-CAMELLIA256-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
337 "DHE-DSS-CAMELLIA256-SHA256", /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
338 "DHE-RSA-CAMELLIA256-SHA256", /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
339 "ADH-CAMELLIA256-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */
340 "CAMELLIA256-GCM-SHA384", /* TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
341 "DH-RSA-CAMELLIA256-GCM-SHA384", /* TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
342 "DH-DSS-CAMELLIA256-GCM-SHA384", /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */
343 "ADH-CAMELLIA256-GCM-SHA384", /* TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 */
344 "ECDH-ECDSA-CAMELLIA256-GCM-SHA384",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */
345 "ECDH-RSA-CAMELLIA256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
346 "PSK-CAMELLIA256-GCM-SHA384", /* TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
347 "RSA-PSK-CAMELLIA256-GCM-SHA384", /* TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
349 /* The blacklisted ARIA encrpytion ciphers */
350 "ARIA128-SHA256", /* TLS_RSA_WITH_ARIA_128_CBC_SHA256 */
351 "ARIA256-SHA384", /* TLS_RSA_WITH_ARIA_256_CBC_SHA384 */
352 "DH-DSS-ARIA128-SHA256", /* TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 */
353 "DH-DSS-ARIA256-SHA384", /* TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 */
354 "DH-RSA-ARIA128-SHA256", /* TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 */
355 "DH-RSA-ARIA256-SHA384", /* TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 */
356 "DHE-DSS-ARIA128-SHA256", /* TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 */
357 "DHE-DSS-ARIA256-SHA384", /* TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 */
358 "DHE-RSA-ARIA128-SHA256", /* TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 */
359 "DHE-RSA-ARIA256-SHA384", /* TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 */
360 "ADH-ARIA128-SHA256", /* TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 */
361 "ADH-ARIA256-SHA384", /* TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 */
362 "ECDHE-ECDSA-ARIA128-SHA256", /* TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 */
363 "ECDHE-ECDSA-ARIA256-SHA384", /* TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 */
364 "ECDH-ECDSA-ARIA128-SHA256", /* TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 */
365 "ECDH-ECDSA-ARIA256-SHA384", /* TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 */
366 "ECDHE-RSA-ARIA128-SHA256", /* TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 */
367 "ECDHE-RSA-ARIA256-SHA384", /* TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 */
368 "ECDH-RSA-ARIA128-SHA256", /* TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 */
369 "ECDH-RSA-ARIA256-SHA384", /* TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 */
370 "ARIA128-GCM-SHA256", /* TLS_RSA_WITH_ARIA_128_GCM_SHA256 */
371 "ARIA256-GCM-SHA384", /* TLS_RSA_WITH_ARIA_256_GCM_SHA384 */
372 "DH-DSS-ARIA128-GCM-SHA256", /* TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 */
373 "DH-DSS-ARIA256-GCM-SHA384", /* TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 */
374 "DH-RSA-ARIA128-GCM-SHA256", /* TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 */
375 "DH-RSA-ARIA256-GCM-SHA384", /* TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 */
376 "ADH-ARIA128-GCM-SHA256", /* TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 */
377 "ADH-ARIA256-GCM-SHA384", /* TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 */
378 "ECDH-ECDSA-ARIA128-GCM-SHA256", /* TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 */
379 "ECDH-ECDSA-ARIA256-GCM-SHA384", /* TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 */
380 "ECDH-RSA-ARIA128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 */
381 "ECDH-RSA-ARIA256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 */
382 "PSK-ARIA128-SHA256", /* TLS_PSK_WITH_ARIA_128_CBC_SHA256 */
383 "PSK-ARIA256-SHA384", /* TLS_PSK_WITH_ARIA_256_CBC_SHA384 */
384 "DHE-PSK-ARIA128-SHA256", /* TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 */
385 "DHE-PSK-ARIA256-SHA384", /* TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 */
386 "RSA-PSK-ARIA128-SHA256", /* TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 */
387 "RSA-PSK-ARIA256-SHA384", /* TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 */
388 "ARIA128-GCM-SHA256", /* TLS_PSK_WITH_ARIA_128_GCM_SHA256 */
389 "ARIA256-GCM-SHA384", /* TLS_PSK_WITH_ARIA_256_GCM_SHA384 */
390 "RSA-PSK-ARIA128-GCM-SHA256", /* TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 */
391 "RSA-PSK-ARIA256-GCM-SHA384", /* TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 */
392 "ECDHE-PSK-ARIA128-SHA256", /* TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 */
393 "ECDHE-PSK-ARIA256-SHA384", /* TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */
395 /* blacklisted SEED encryptions */
396 "SEED-SHA", /*TLS_RSA_WITH_SEED_CBC_SHA */
397 "DH-DSS-SEED-SHA", /* TLS_DH_DSS_WITH_SEED_CBC_SHA */
398 "DH-RSA-SEED-SHA", /* TLS_DH_RSA_WITH_SEED_CBC_SHA */
399 "DHE-DSS-SEED-SHA", /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */
400 "DHE-RSA-SEED-SHA", /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */
401 "ADH-SEED-SHA", /* TLS_DH_anon_WITH_SEED_CBC_SHA */
403 /* blacklisted KRB5 ciphers */
404 "KRB5-DES-CBC-SHA", /* TLS_KRB5_WITH_DES_CBC_SHA */
405 "KRB5-DES-CBC3-SHA", /* TLS_KRB5_WITH_3DES_EDE_CBC_SHA */
406 "KRB5-IDEA-CBC-SHA", /* TLS_KRB5_WITH_IDEA_CBC_SHA */
407 "KRB5-DES-CBC-MD5", /* TLS_KRB5_WITH_DES_CBC_MD5 */
408 "KRB5-DES-CBC3-MD5", /* TLS_KRB5_WITH_3DES_EDE_CBC_MD5 */
409 "KRB5-IDEA-CBC-MD5", /* TLS_KRB5_WITH_IDEA_CBC_MD5 */
410 "EXP-KRB5-DES-CBC-SHA", /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA */
411 "EXP-KRB5-DES-CBC-MD5", /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */
412 "EXP-KRB5-RC2-CBC-SHA", /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA */
413 "EXP-KRB5-RC2-CBC-MD5", /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 */
415 /* blacklisted exoticas */
416 "DHE-DSS-CBC-SHA", /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
417 "IDEA-CBC-SHA", /* TLS_RSA_WITH_IDEA_CBC_SHA */
419 /* not really sure if the following names are correct */
420 "SSL3_CK_SCSV", /* TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
421 "SSL3_CK_FALLBACK_SCSV"
423 static size_t RFC7540_names_LEN = sizeof(RFC7540_names)/sizeof(RFC7540_names[0]);
426 static apr_hash_t *BLCNames;
428 static void cipher_init(apr_pool_t *pool)
430 apr_hash_t *hash = apr_hash_make(pool);
435 for (i = 0; i < RFC7540_names_LEN; ++i) {
436 apr_hash_set(hash, RFC7540_names[i], APR_HASH_KEY_STRING, source);
442 static int cipher_is_blacklisted(const char *cipher, const char **psource)
444 *psource = apr_hash_get(BLCNames, cipher, APR_HASH_KEY_STRING);
448 /*******************************************************************************
449 * Hooks for processing incoming connections:
450 * - process_conn take over connection in case of h2
452 static int h2_h2_process_conn(conn_rec* c);
453 static int h2_h2_pre_close_conn(conn_rec* c);
454 static int h2_h2_post_read_req(request_rec *r);
455 static int h2_h2_late_fixups(request_rec *r);
457 /*******************************************************************************
458 * Once per lifetime init, retrieve optional functions
460 apr_status_t h2_h2_init(apr_pool_t *pool, server_rec *s)
463 ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "h2_h2, child_init");
464 opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
465 opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
466 opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
468 if (!opt_ssl_is_https || !opt_ssl_var_lookup) {
469 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
470 APLOGNO(02951) "mod_ssl does not seem to be enabled");
478 int h2_h2_is_tls(conn_rec *c)
480 return opt_ssl_is_https && opt_ssl_is_https(c);
483 int h2_is_acceptable_connection(conn_rec *c, int require_all)
485 int is_tls = h2_h2_is_tls(c);
486 const h2_config *cfg = h2_config_get(c);
488 if (is_tls && h2_config_geti(cfg, H2_CONF_MODERN_TLS_ONLY) > 0) {
489 /* Check TLS connection for modern TLS parameters, as defined in
490 * RFC 7540 and https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
492 apr_pool_t *pool = c->pool;
493 server_rec *s = c->base_server;
496 if (!opt_ssl_var_lookup) {
497 /* unable to check */
501 /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
503 val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_PROTOCOL");
505 if (strncmp("TLS", val, 3)
506 || !strcmp("TLSv1", val)
507 || !strcmp("TLSv1.1", val)) {
508 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03050)
509 "h2_h2(%ld): tls protocol not suitable: %s",
514 else if (require_all) {
515 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03051)
516 "h2_h2(%ld): tls protocol is indetermined", (long)c->id);
520 /* Check TLS cipher blacklist
522 val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_CIPHER");
525 if (cipher_is_blacklisted(val, &source)) {
526 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03052)
527 "h2_h2(%ld): tls cipher %s blacklisted by %s",
528 (long)c->id, val, source);
532 else if (require_all) {
533 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03053)
534 "h2_h2(%ld): tls cipher is indetermined", (long)c->id);
541 int h2_allows_h2_direct(conn_rec *c)
543 const h2_config *cfg = h2_config_get(c);
544 int is_tls = h2_h2_is_tls(c);
545 const char *needed_protocol = is_tls? "h2" : "h2c";
546 int h2_direct = h2_config_geti(cfg, H2_CONF_DIRECT);
549 h2_direct = is_tls? 0 : 1;
552 && ap_is_allowed_protocol(c, NULL, NULL, needed_protocol));
555 int h2_allows_h2_upgrade(conn_rec *c)
557 const h2_config *cfg = h2_config_get(c);
558 int h2_upgrade = h2_config_geti(cfg, H2_CONF_UPGRADE);
560 return h2_upgrade > 0 || (h2_upgrade < 0 && !h2_h2_is_tls(c));
563 /*******************************************************************************
564 * Register various hooks
566 static const char* const mod_ssl[] = { "mod_ssl.c", NULL};
567 static const char* const mod_reqtimeout[] = { "mod_reqtimeout.c", NULL};
569 void h2_h2_register_hooks(void)
571 /* Our main processing needs to run quite late. Definitely after mod_ssl,
572 * as we need its connection filters, but also before reqtimeout as its
573 * method of timeouts is specific to HTTP/1.1 (as of now).
574 * The core HTTP/1 processing run as REALLY_LAST, so we will have
575 * a chance to take over before it.
577 ap_hook_process_connection(h2_h2_process_conn,
578 mod_ssl, mod_reqtimeout, APR_HOOK_LAST);
580 /* One last chance to properly say goodbye if we have not done so
582 ap_hook_pre_close_connection(h2_h2_pre_close_conn, NULL, mod_ssl, APR_HOOK_LAST);
584 /* With "H2SerializeHeaders On", we install the filter in this hook
585 * that parses the response. This needs to happen before any other post
586 * read function terminates the request with an error. Otherwise we will
587 * never see the response.
589 ap_hook_post_read_request(h2_h2_post_read_req, NULL, NULL, APR_HOOK_REALLY_FIRST);
590 ap_hook_fixups(h2_h2_late_fixups, NULL, NULL, APR_HOOK_LAST);
592 /* special bucket type transfer through a h2_bucket_beam */
593 h2_register_bucket_beamer(h2_bucket_headers_beam);
594 h2_register_bucket_beamer(h2_bucket_observer_beam);
597 int h2_h2_process_conn(conn_rec* c)
606 ctx = h2_ctx_get(c, 0);
607 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn");
608 if (h2_ctx_is_task(ctx)) {
609 /* our stream pseudo connection */
610 ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "h2_h2, task, declined");
614 if (!ctx && c->keepalives == 0) {
615 const char *proto = ap_get_protocol(c);
617 if (APLOGctrace1(c)) {
618 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn, "
619 "new connection using protocol '%s', direct=%d, "
620 "tls acceptable=%d", proto, h2_allows_h2_direct(c),
621 h2_is_acceptable_connection(c, 1));
624 if (!strcmp(AP_PROTOCOL_HTTP1, proto)
625 && h2_allows_h2_direct(c)
626 && h2_is_acceptable_connection(c, 1)) {
627 /* Fresh connection still is on http/1.1 and H2Direct is enabled.
628 * Otherwise connection is in a fully acceptable state.
629 * -> peek at the first 24 incoming bytes
631 apr_bucket_brigade *temp;
635 temp = apr_brigade_create(c->pool, c->bucket_alloc);
636 status = ap_get_brigade(c->input_filters, temp,
637 AP_MODE_SPECULATIVE, APR_BLOCK_READ, 24);
639 if (status != APR_SUCCESS) {
640 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c, APLOGNO(03054)
641 "h2_h2, error reading 24 bytes speculative");
642 apr_brigade_destroy(temp);
646 apr_brigade_pflatten(temp, &s, &slen, c->pool);
647 if ((slen >= 24) && !memcmp(H2_MAGIC_TOKEN, s, 24)) {
648 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
649 "h2_h2, direct mode detected");
651 ctx = h2_ctx_get(c, 1);
653 h2_ctx_protocol_set(ctx, h2_h2_is_tls(c)? "h2" : "h2c");
656 ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
657 "h2_h2, not detected in %d bytes: %s",
661 apr_brigade_destroy(temp);
666 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "process_conn");
667 if (!h2_ctx_session_get(ctx)) {
668 status = h2_conn_setup(ctx, c, NULL);
669 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, c, "conn_setup");
670 if (status != APR_SUCCESS) {
679 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, declined");
683 static int h2_h2_pre_close_conn(conn_rec *c)
687 /* slave connection? */
692 ctx = h2_ctx_get(c, 0);
694 /* If the session has been closed correctly already, we will not
695 * find a h2_ctx here. The presence indicates that the session
696 * is still ongoing. */
697 return h2_conn_pre_close(ctx, c);
702 static void check_push(request_rec *r, const char *tag)
704 const h2_config *conf = h2_config_rget(r);
705 if (!r->expecting_100
706 && conf && conf->push_list && conf->push_list->nelts > 0) {
708 const char *old_line;
709 ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
710 "%s, early announcing %d resources for push",
711 tag, conf->push_list->nelts);
712 for (i = 0; i < conf->push_list->nelts; ++i) {
713 h2_push_res *push = &APR_ARRAY_IDX(conf->push_list, i, h2_push_res);
714 apr_table_addn(r->headers_out, "Link",
715 apr_psprintf(r->pool, "<%s>; rel=preload%s",
716 push->uri_ref, push->critical? "; critical" : ""));
718 old_status = r->status;
719 old_line = r->status_line;
721 r->status_line = "103 Early Hints";
722 ap_send_interim_response(r, 1);
723 r->status = old_status;
724 r->status_line = old_line;
728 static int h2_h2_post_read_req(request_rec *r)
730 /* slave connection? */
731 if (r->connection->master) {
732 h2_ctx *ctx = h2_ctx_rget(r);
733 struct h2_task *task = h2_ctx_get_task(ctx);
734 /* This hook will get called twice on internal redirects. Take care
735 * that we manipulate filters only once. */
736 if (task && !task->filters_set) {
738 ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
739 "h2_task(%s): adding request filters", task->id);
741 /* setup the correct filters to process the request for h2 */
742 ap_add_input_filter("H2_REQUEST", task, r, r->connection);
744 /* replace the core http filter that formats response headers
745 * in HTTP/1 with our own that collects status and headers */
746 ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
747 ap_add_output_filter("H2_RESPONSE", task, r, r->connection);
749 for (f = r->input_filters; f; f = f->next) {
750 if (!strcmp("H2_SLAVE_IN", f->frec->name)) {
755 ap_add_output_filter("H2_TRAILERS_OUT", task, r, r->connection);
756 task->filters_set = 1;
762 static int h2_h2_late_fixups(request_rec *r)
764 /* slave connection? */
765 if (r->connection->master) {
766 h2_ctx *ctx = h2_ctx_rget(r);
767 struct h2_task *task = h2_ctx_get_task(ctx);
769 /* check if we copy vs. setaside files in this location */
770 task->output.copy_files = h2_config_geti(h2_config_rget(r),
772 if (task->output.copy_files) {
773 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c,
774 "h2_slave_out(%s): copy_files on", task->id);
775 h2_beam_on_file_beam(task->output.beam, h2_beam_no_files, NULL);
777 check_push(r, "late_fixup");