/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.
*/
#define CONFIG_CMD_SET(cmd,dir,var,val) \
h2_config_seti(((cmd)->path? (dir) : NULL), h2_config_sget((cmd)->server), var, val)
#define CONFIG_CMD_SET64(cmd,dir,var,val) \
h2_config_seti64(((cmd)->path? (dir) : NULL), h2_config_sget((cmd)->server), var, val)
/* Apache httpd module configuration for h2. */ typedefstruct h2_config { constchar *name; int h2_max_streams; /* max concurrent # streams (http2) */ int h2_window_size; /* stream window size (http2) */ int min_workers; /* min # of worker threads/child */ int max_workers; /* max # of worker threads/child */
apr_interval_time_t idle_limit; /* max duration for idle workers */ int stream_max_mem_size; /* max # bytes held in memory/stream */ int h2_direct; /* if mod_h2 is active directly */ int modern_tls_only; /* Accept only modern TLS in HTTP/2 connections */ int h2_upgrade; /* Allow HTTP/1 upgrade to h2/h2c */
apr_int64_t tls_warmup_size; /* Amount of TLS data to send before going full write size */ int tls_cooldown_secs; /* Seconds of idle time before going back to small TLS records */ int h2_push; /* if HTTP/2 server push is enabled */ struct apr_hash_t *priorities; /* map of content-type to h2_priority records */
int push_diary_size; /* # of entries in push diary */ int copy_files; /* if files shall be copied vs setaside on output */
apr_array_header_t *push_list; /* list of h2_push_res configurations */
apr_table_t *early_headers; /* HTTP headers for a 103 response */ int early_hints; /* support status code 103 */ int padding_bits; int padding_always; int output_buffered;
apr_interval_time_t stream_timeout;/* beam timeout */ int max_data_frame_len; /* max # bytes in a single h2 DATA frame */ int max_hd_block_len; /* max # bytes in a response header block */ int proxy_requests; /* act as forward proxy */ int h2_websockets; /* if mod_h2 negotiating WebSockets */
} h2_config;
typedefstruct h2_dir_config { constchar *name; int h2_upgrade; /* Allow HTTP/1 upgrade to h2/h2c */ int h2_push; /* if HTTP/2 server push is enabled */
apr_array_header_t *push_list; /* list of h2_push_res configurations */
apr_table_t *early_headers; /* HTTP headers for a 103 response */ int early_hints; /* support status code 103 */
apr_interval_time_t stream_timeout;/* beam timeout */
} h2_dir_config;
static h2_config defconf = { "default",
100, /* max_streams */
H2_INITIAL_WINDOW_SIZE, /* window_size */
-1, /* min workers */
-1, /* max workers */
apr_time_from_sec(10 * 60), /* workers idle limit */
32 * 1024, /* stream max mem size */
-1, /* h2 direct mode */
1, /* modern TLS only */
-1, /* HTTP/1 Upgrade support */
1024*1024, /* TLS warmup size */
1, /* TLS cooldown secs */
1, /* HTTP/2 server push enabled */
NULL, /* map of content-type to priorities */
256, /* push diary size */
0, /* copy files across threads */
NULL, /* push list */
NULL, /* early headers */
0, /* early hints, http status 103 */
0, /* padding bits */
1, /* padding always */
1, /* stream output buffered */
-1, /* beam timeout */
0, /* max DATA frame len, 0 == no extra limit */
0, /* max header block len, 0 == no extra limit */
0, /* forward proxy */
0, /* WebSockets negotiation, enabled */
};
static h2_dir_config defdconf = { "default",
-1, /* HTTP/1 Upgrade support */
-1, /* HTTP/2 server push enabled */
NULL, /* push list */
NULL, /* early headers */
-1, /* early hints, http status 103 */
-1, /* beam timeout */
};
staticconstchar *h2_conf_set_stream_max_mem_size(cmd_parms *cmd, void *dirconf, constchar *value)
{ int val = (int)apr_atoi64(value); if (val < 1024) { return"value must be >= 1024";
}
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_STREAM_MAX_MEM, val); return NULL;
}
staticconstchar *h2_conf_set_max_data_frame_len(cmd_parms *cmd, void *dirconf, constchar *value)
{ int val = (int)apr_atoi64(value); if (val < 0) { return"value must be 0 or larger";
}
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MAX_DATA_FRAME_LEN, val); return NULL;
}
staticconstchar *h2_conf_set_max_hd_block_len(cmd_parms *cmd, void *dirconf, constchar *value)
{ int val = (int)apr_atoi64(value); if (val < 0) { return"value must be 0 or larger";
}
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_MAX_HEADER_BLOCK_LEN, val); return NULL;
}
staticconstchar *h2_conf_set_session_extra_files(cmd_parms *cmd, void *dirconf, constchar *value)
{ /* deprecated, ignore */
(void)dirconf;
(void)value;
ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, cmd->pool, /* NO LOGNO */ "H2SessionExtraFiles is obsolete and will be ignored"); return NULL;
}
staticconstchar *h2_conf_set_serialize_headers(cmd_parms *parms, void *dirconf, constchar *value)
{ if (!strcasecmp(value, "On")) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, parms->server, APLOGNO(10307) "%s: this feature has been disabled and the directive " "to enable it is ignored.", parms->cmd->name);
} return NULL;
}
staticconstchar *h2_conf_set_direct(cmd_parms *cmd, void *dirconf, constchar *value)
{ if (!strcasecmp(value, "On")) {
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_DIRECT, 1); return NULL;
} elseif (!strcasecmp(value, "Off")) {
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_DIRECT, 0); return NULL;
} return"value must be On or Off";
}
staticconstchar *h2_conf_set_push(cmd_parms *cmd, void *dirconf, constchar *value)
{ if (!strcasecmp(value, "On")) {
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PUSH, 1); return NULL;
} elseif (!strcasecmp(value, "Off")) {
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PUSH, 0); return NULL;
} return"value must be On or Off";
}
staticconstchar *h2_conf_set_websockets(cmd_parms *cmd, void *dirconf, constchar *value)
{ if (!strcasecmp(value, "On")) { #if H2_USE_WEBSOCKETS
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_WEBSOCKETS, 1); return NULL; #elif !H2_USE_PIPES return"HTTP/2 WebSockets are not supported on this platform"; #else return"HTTP/2 WebSockets are not supported in this server version"; #endif
} elseif (!strcasecmp(value, "Off")) {
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_WEBSOCKETS, 0); return NULL;
} return"value must be On or Off";
}
(void)_cfg; if (!*ctype) { return"1st argument must be a mime-type, like 'text/css' or '*'";
}
if (!sweight) { /* 2 args only, but which one? */ if (apr_isdigit(sdependency[0])) {
sweight = sdependency;
sdependency = "AFTER"; /* default dependency */
}
}
if (!strcasecmp("AFTER", sdependency)) {
dependency = H2_DEPENDANT_AFTER;
} elseif (!strcasecmp("BEFORE", sdependency)) {
dependency = H2_DEPENDANT_BEFORE; if (sweight) { return"dependency 'Before' does not allow a weight";
}
} elseif (!strcasecmp("INTERLEAVED", sdependency)) {
dependency = H2_DEPENDANT_INTERLEAVED;
sdefweight = "256"; /* default INTERLEAVED weight */
} else { return"dependency must be one of 'After', 'Before' or 'Interleaved'";
}
weight = (int)apr_atoi64(sweight? sweight : sdefweight); if (weight < NGHTTP2_MIN_WEIGHT) { return apr_psprintf(cmd->pool, "weight must be a number >= %d",
NGHTTP2_MIN_WEIGHT);
}
staticconstchar *h2_conf_set_push_diary_size(cmd_parms *cmd, void *dirconf, constchar *value)
{ int val = (int)apr_atoi64(value); if (val < 0) { return"value must be >= 0";
} if (val > 0 && (val & (val-1))) { return"value must a power of 2";
} if (val > (1 << 15)) { return"value must <= 65536";
}
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PUSH_DIARY_SIZE, val); return NULL;
}
staticconstchar *h2_conf_set_copy_files(cmd_parms *cmd, void *dirconf, constchar *value)
{ if (!strcasecmp(value, "On")) {
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_COPY_FILES, 1); return NULL;
} elseif (!strcasecmp(value, "Off")) {
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_COPY_FILES, 0); return NULL;
} return"value must be On or Off";
}
if(!name || !*name) return"Early Hint header name must not be empty"; if(!value) return"Early Hint header value must not be empty"; while (apr_isspace(*value))
++value; if(!*value) return"Early Hint header value must not be empty/only space"; if (*ap_scan_http_field_content(value)) return"Early Hint header value contains invalid characters";
staticconstchar *h2_conf_set_padding(cmd_parms *cmd, void *dirconf, constchar *value)
{ int val;
val = (int)apr_atoi64(value); if (val < 0) { return"number of bits must be >= 0";
} if (val > 8) { return"number of bits must be <= 8";
}
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_PADDING_BITS, val); return NULL;
}
staticconstchar *h2_conf_set_output_buffer(cmd_parms *cmd, void *dirconf, constchar *value)
{ if (!strcasecmp(value, "On")) {
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_OUTPUT_BUFFER, 1); return NULL;
} elseif (!strcasecmp(value, "Off")) {
CONFIG_CMD_SET(cmd, dirconf, H2_CONF_OUTPUT_BUFFER, 0); return NULL;
} return"value must be On or Off";
}
const command_rec h2_cmds[] = {
AP_INIT_TAKE1("H2MaxSessionStreams", h2_conf_set_max_streams, NULL,
RSRC_CONF, "maximum number of open streams per session"),
AP_INIT_TAKE1("H2WindowSize", h2_conf_set_window_size, NULL,
RSRC_CONF, "window size on client DATA"),
AP_INIT_TAKE1("H2MinWorkers", h2_conf_set_min_workers, NULL,
RSRC_CONF, "minimum number of worker threads per child"),
AP_INIT_TAKE1("H2MaxWorkers", h2_conf_set_max_workers, NULL,
RSRC_CONF, "maximum number of worker threads per child"),
AP_INIT_TAKE1("H2MaxWorkerIdleSeconds", h2_conf_set_max_worker_idle_limit, NULL,
RSRC_CONF, "maximum number of idle seconds before a worker shuts down"),
AP_INIT_TAKE1("H2StreamMaxMemSize", h2_conf_set_stream_max_mem_size, NULL,
RSRC_CONF, "maximum number of bytes buffered in memory for a stream"),
AP_INIT_TAKE1("H2SerializeHeaders", h2_conf_set_serialize_headers, NULL,
RSRC_CONF, "disabled, this directive has no longer an effect."),
AP_INIT_TAKE1("H2ModernTLSOnly", h2_conf_set_modern_tls_only, NULL,
RSRC_CONF, "off to not impose RFC 7540 restrictions on TLS"),
AP_INIT_TAKE1("H2Upgrade", h2_conf_set_upgrade, NULL,
RSRC_CONF|OR_AUTHCFG, "on to allow HTTP/1 Upgrades to h2/h2c"),
AP_INIT_TAKE1("H2Direct", h2_conf_set_direct, NULL,
RSRC_CONF, "on to enable direct HTTP/2 mode"),
AP_INIT_TAKE1("H2SessionExtraFiles", h2_conf_set_session_extra_files, NULL,
RSRC_CONF, "number of extra file a session might keep open (obsolete)"),
AP_INIT_TAKE1("H2TLSWarmUpSize", h2_conf_set_tls_warmup_size, NULL,
RSRC_CONF, "number of bytes on TLS connection before doing max writes"),
AP_INIT_TAKE1("H2TLSCoolDownSecs", h2_conf_set_tls_cooldown_secs, NULL,
RSRC_CONF, "seconds of idle time on TLS before shrinking writes"),
AP_INIT_TAKE1("H2Push", h2_conf_set_push, NULL,
RSRC_CONF|OR_AUTHCFG, "off to disable HTTP/2 server push"),
AP_INIT_TAKE23("H2PushPriority", h2_conf_add_push_priority, NULL,
RSRC_CONF, "define priority of PUSHed resources per content type"),
AP_INIT_TAKE1("H2PushDiarySize", h2_conf_set_push_diary_size, NULL,
RSRC_CONF, "size of push diary"),
AP_INIT_TAKE1("H2CopyFiles", h2_conf_set_copy_files, NULL,
OR_FILEINFO, "on to perform copy of file data"),
AP_INIT_TAKE123("H2PushResource", h2_conf_add_push_res, NULL,
OR_FILEINFO|OR_AUTHCFG, "add a resource to be pushed in this location/on this server."),
AP_INIT_TAKE1("H2EarlyHints", h2_conf_set_early_hints, NULL,
RSRC_CONF, "on to enable interim status 103 responses"),
AP_INIT_TAKE1("H2Padding", h2_conf_set_padding, NULL,
RSRC_CONF, "set payload padding"),
AP_INIT_TAKE1("H2OutputBuffering", h2_conf_set_output_buffer, NULL,
RSRC_CONF, "set stream output buffer on/off"),
AP_INIT_TAKE1("H2StreamTimeout", h2_conf_set_stream_timeout, NULL,
RSRC_CONF, "set stream timeout"),
AP_INIT_TAKE1("H2MaxDataFrameLen", h2_conf_set_max_data_frame_len, NULL,
RSRC_CONF, "maximum number of bytes in a single HTTP/2 DATA frame"),
AP_INIT_TAKE1("H2MaxHeaderBlockLen", h2_conf_set_max_hd_block_len, NULL,
RSRC_CONF, "maximum number of bytes in a response header block"),
AP_INIT_TAKE2("H2EarlyHint", h2_conf_add_early_hint, NULL,
OR_FILEINFO|OR_AUTHCFG, "add a a 'Link:' header for a 103 Early Hints response."),
AP_INIT_TAKE1("H2ProxyRequests", h2_conf_set_proxy_requests, NULL,
OR_FILEINFO, "Enables forward proxy requests via HTTP/2"),
AP_INIT_TAKE1("H2WebSockets", h2_conf_set_websockets, NULL,
RSRC_CONF, "off to disable WebSockets over HTTP/2"),
AP_END_CMD
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.