summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/ap_mmn.h4
-rw-r--r--include/http_core.h7
-rw-r--r--server/core.c54
-rw-r--r--server/protocol.c27
4 files changed, 63 insertions, 29 deletions
diff --git a/include/ap_mmn.h b/include/ap_mmn.h
index 74dab7c32a..18827118c2 100644
--- a/include/ap_mmn.h
+++ b/include/ap_mmn.h
@@ -404,6 +404,8 @@
* 20120724.4 (2.5.0-dev) Add dirwalk_stat hook.
* 20120724.5 (2.5.0-dev) Add ap_get_sload() and ap_get_loadavg().
* 20120724.6 (2.5.0-dev) Add sticky_separator to proxy_balancer_shared struct.
+ * 20120724.7 (2.5.0-dev) Add min_http_version/max_http_version to
+ * core_server_config
*/
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
@@ -411,7 +413,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20120724
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 6 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 7 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
diff --git a/include/http_core.h b/include/http_core.h
index bb1102aa83..ca480f01a2 100644
--- a/include/http_core.h
+++ b/include/http_core.h
@@ -664,10 +664,9 @@ typedef struct {
#define AP_TRACE_EXTENDED 2
int trace_enable;
-#define AP_HTTP09_UNSET 0
-#define AP_HTTP09_ENABLE 1
-#define AP_HTTP09_DISABLE 2
- char http09_enable;
+#define AP_HTTP_VERSION_UNSET 0
+ uint16_t min_http_version;
+ uint16_t max_http_version;
} core_server_config;
diff --git a/server/core.c b/server/core.c
index 871c1c9750..c6c47d3360 100644
--- a/server/core.c
+++ b/server/core.c
@@ -502,8 +502,10 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
if (virt->trace_enable != AP_TRACE_UNSET)
conf->trace_enable = virt->trace_enable;
- if (virt->http09_enable != AP_HTTP09_UNSET)
- conf->http09_enable = virt->http09_enable;
+ if (virt->min_http_version != AP_HTTP_VERSION_UNSET) {
+ conf->min_http_version = virt->min_http_version;
+ conf->max_http_version = virt->max_http_version;
+ }
/* no action for virt->accf_map, not allowed per-vhost */
@@ -3615,21 +3617,45 @@ static const char *set_trace_enable(cmd_parms *cmd, void *dummy,
}
static const char *set_http_protocol(cmd_parms *cmd, void *dummy,
- const char *arg1)
+ const char *arg)
{
- core_server_config *conf =
- ap_get_core_module_config(cmd->server->module_config);
+ core_server_config *conf;
+ conf = ap_get_core_module_config(cmd->server->module_config);
+ if (apr_isdigit(arg[0])) {
+ unsigned short min_major, min_minor, max_major, max_minor;
+ unsigned int min, max;
+ char ch;
- if (strcmp(arg1, "+0.9") == 0) {
- conf->http09_enable = AP_HTTP09_ENABLE;
- }
- else if (strcmp(arg1, "-0.9") == 0) {
- conf->http09_enable = AP_HTTP09_DISABLE;
+ if (sscanf(arg, "%hu.%hu-%hu.%hu%c", &min_major, &min_minor,
+ &max_major, &max_minor, &ch) == 4) {
+ }
+ else if (sscanf(arg, "%hu.%hu%c", &min_major, &min_minor, &ch) == 2) {
+ max_major = min_major;
+ max_minor = min_minor;
+ }
+ else {
+ return "Protocol version must be in format a.b or a.b-c.d";
+ }
+ if ( HTTP_VERSION(0, min_minor) >= HTTP_VERSION(1,0)
+ || HTTP_VERSION(0, max_minor) >= HTTP_VERSION(1,0)) {
+ return "HTTP minor version may not be more than 999";
+ }
+ min = HTTP_VERSION(min_major, min_minor);
+ max = HTTP_VERSION(max_major, max_minor);
+ if (min > APR_UINT16_MAX || max > APR_UINT16_MAX)
+ return "HTTP major version may not be more than 64";
+ if (min > max)
+ return "HTTP version range must be min-max";
+ /* 0 is used for "unset", so make sure the min is larger */
+ if (min < HTTP_VERSION(0,9))
+ min = HTTP_VERSION(0,9);
+ conf->min_http_version = min;
+ conf->max_http_version = max;
}
else {
- return "HttpProtocol must be one of '+0.9' and '-0.9'";
+ return "Valid arguments are a version number (e.g. '1.1')"
+ "or a version range (e.g. '1.0-9.9')";
}
-
return NULL;
}
@@ -4141,8 +4167,8 @@ AP_INIT_TAKE1("EnableExceptionHook", ap_mpm_set_exception_hook, NULL, RSRC_CONF,
#endif
AP_INIT_TAKE1("TraceEnable", set_trace_enable, NULL, RSRC_CONF,
"'on' (default), 'off' or 'extended' to trace request body content"),
-AP_INIT_TAKE1("HttpProtocol", set_http_protocol, NULL, RSRC_CONF,
- "'+0.9' (default) or '-0.9' to allow/deny HTTP/0.9"),
+AP_INIT_ITERATE("HttpProtocol", set_http_protocol, NULL, RSRC_CONF,
+ "Allowed HTTP version or range (e.g. '1.1', '1.0-9.9'"),
AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF,
"Registers non-standard HTTP methods"),
{ NULL }
diff --git a/server/protocol.c b/server/protocol.c
index 2fa3895cbd..a3710a58f6 100644
--- a/server/protocol.c
+++ b/server/protocol.c
@@ -566,6 +566,8 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
apr_size_t len;
int num_blank_lines = 0;
int max_blank_lines = r->server->limit_req_fields;
+ core_server_config *conf =
+ ap_get_core_module_config(r->server->module_config);
if (max_blank_lines <= 0) {
max_blank_lines = DEFAULT_LIMIT_REQUEST_FIELDS;
@@ -644,19 +646,9 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
pro = ll;
len = strlen(ll);
} else {
- core_server_config *conf;
- conf = ap_get_core_module_config(r->server->module_config);
r->assbackwards = 1;
pro = "HTTP/0.9";
len = 8;
- if (conf->http09_enable == AP_HTTP09_DISABLE) {
- r->status = HTTP_VERSION_NOT_SUPPORTED;
- r->protocol = apr_pstrmemdup(r->pool, pro, len);
- r->proto_num = HTTP_VERSION(0, 9);
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02401)
- "HTTP/0.9 denied by server configuration");
- return 0;
- }
}
r->protocol = apr_pstrmemdup(r->pool, pro, len);
@@ -674,6 +666,21 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
else
r->proto_num = HTTP_VERSION(1, 0);
+ if (conf->min_http_version != AP_HTTP_VERSION_UNSET
+ && ( conf->min_http_version > r->proto_num
+ || conf->max_http_version < r->proto_num)) {
+ r->status = HTTP_VERSION_NOT_SUPPORTED;
+ if (r->proto_num == HTTP_VERSION(0, 9)) {
+ /* If we deny 0.9, send error message with 1.x */
+ r->assbackwards = 0;
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02401)
+ "HTTP/%d.%d denied by server configuration",
+ HTTP_VERSION_MAJOR(r->proto_num),
+ HTTP_VERSION_MINOR(r->proto_num));
+ return 0;
+ }
+
return 1;
}