From 7a5a4a1150979c1565bcd90d771aef936b4d2f17 Mon Sep 17 00:00:00 2001 From: reyk Date: Tue, 5 Aug 2014 18:01:10 +0000 Subject: [PATCH] Add configuration options for the most-important connection limits: max requests (per connection) and timeout. We don't want to add too many button, and there are good defaults, but these ones are kind of mandatory. --- etc/examples/httpd.conf | 9 ++++++- usr.sbin/httpd/config.c | 6 ++++- usr.sbin/httpd/httpd.conf.5 | 20 ++++++++++++-- usr.sbin/httpd/httpd.h | 7 ++--- usr.sbin/httpd/parse.y | 52 +++++++++++++++++++++++++++++++----- usr.sbin/httpd/server_http.c | 4 +-- 6 files changed, 82 insertions(+), 16 deletions(-) diff --git a/etc/examples/httpd.conf b/etc/examples/httpd.conf index 7c949f20d1b..c276797b8be 100644 --- a/etc/examples/httpd.conf +++ b/etc/examples/httpd.conf @@ -1,4 +1,4 @@ -# $OpenBSD: httpd.conf,v 1.8 2014/08/04 17:50:48 reyk Exp $ +# $OpenBSD: httpd.conf,v 1.9 2014/08/05 18:01:10 reyk Exp $ # # Macros @@ -48,6 +48,13 @@ server "www.example.com" { # An HTTPS server using SSL/TLS server "secure.example.com" { listen on 127.0.0.1 port 443 ssl + + # Define server-specific log files relative to /logs + log { access "secure-access.log", error "secure-error.log" } + + # Increase connection limits to extend the lifetime + connection { max requests 500, timeout 3600 } + root "/htdocs/secure.example.com" } diff --git a/usr.sbin/httpd/config.c b/usr.sbin/httpd/config.c index cbb2973bab5..9eb8dd801c1 100644 --- a/usr.sbin/httpd/config.c +++ b/usr.sbin/httpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.18 2014/08/05 15:36:59 reyk Exp $ */ +/* $OpenBSD: config.c,v 1.19 2014/08/05 18:01:10 reyk Exp $ */ /* * Copyright (c) 2011 - 2014 Reyk Floeter @@ -285,6 +285,10 @@ config_getserver_config(struct httpd *env, struct server *srv, sizeof(srv_conf->errorlog)); } + memcpy(&srv_conf->timeout, &srv->srv_conf.timeout, + sizeof(srv_conf->timeout)); + srv_conf->maxrequests = srv->srv_conf.maxrequests; + DPRINTF("%s: %s %d location \"%s\", " "parent \"%s\", flags: %s", __func__, ps->ps_title[privsep_process], ps->ps_instance, diff --git a/usr.sbin/httpd/httpd.conf.5 b/usr.sbin/httpd/httpd.conf.5 index 1dce9f325ea..28ba39346ca 100644 --- a/usr.sbin/httpd/httpd.conf.5 +++ b/usr.sbin/httpd/httpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: httpd.conf.5,v 1.25 2014/08/05 17:13:16 reyk Exp $ +.\" $OpenBSD: httpd.conf.5,v 1.26 2014/08/05 18:01:10 reyk Exp $ .\" .\" Copyright (c) 2014 Reyk Floeter .\" @@ -119,6 +119,21 @@ must have a .Ar name and include one or more lines of the following syntax: .Bl -tag -width Ds +.It Ic connection Ar option +Set the specified options and limits for HTTP connections. +Valid options are: +.Bl -tag -width Ds +.It Ic max requests Ar number +Set the maximum number of requests per persistent HTTP connection. +Persistent connections are negotiated using the Keep-Alive header in +HTTP/1.0 and enabled by default in HTTP/1.1. +The default maximum number of requests per connection is +.Ar 100 . +.It Ic timeout Ar seconds +Specify the inactivity timeout in seconds for accepted sessions. +The default timeout is 600 seconds (10 minutes). +The maximum is 2147483647 seconds (68 years). +.El .It Ic directory Ar option Set the specified options when serving or accessing directories. Valid options are: @@ -152,8 +167,9 @@ Specify server configuration rules for a specific location. The .Ar path argument will be matched against the URL path with shell globbing rules. -A location section may include all of the server configuration rules +A location section may include most of the server configuration rules except +.Ic connection , .Ic listen on , .Ic location and diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h index b99c7c2b634..74fa3c5dbc5 100644 --- a/usr.sbin/httpd/httpd.h +++ b/usr.sbin/httpd/httpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.h,v 1.45 2014/08/05 16:30:35 reyk Exp $ */ +/* $OpenBSD: httpd.h,v 1.46 2014/08/05 18:01:10 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -280,7 +280,7 @@ struct client { off_t clt_toread; size_t clt_headerlen; - int clt_persist; + u_int clt_persist; int clt_line; int clt_done; int clt_chunk; @@ -363,8 +363,9 @@ struct server_config { in_port_t port; struct sockaddr_storage ss; - struct timeval timeout; int prefixlen; + struct timeval timeout; + u_int32_t maxrequests; u_int16_t flags; u_int8_t tcpflags; diff --git a/usr.sbin/httpd/parse.y b/usr.sbin/httpd/parse.y index ed3631c6b5d..91e18bed818 100644 --- a/usr.sbin/httpd/parse.y +++ b/usr.sbin/httpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.27 2014/08/05 17:03:21 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.28 2014/08/05 18:01:10 reyk Exp $ */ /* * Copyright (c) 2007 - 2014 Reyk Floeter @@ -126,13 +126,15 @@ typedef struct { %} %token ACCESS AUTO BACKLOG BUFFER CHROOT COMMON COMBINED CONNECTION -%token DIRECTORY ERR FCGI INDEX IP LISTEN LOCATION LOG NO NODELAY ON PORT -%token PREFORK ROOT SACK SERVER SOCKET SSL STYLE SYSLOG TCP TYPES +%token DIRECTORY ERR FCGI INDEX IP LISTEN LOCATION LOG MAXIMUM NO NODELAY +%token ON PORT PREFORK REQUESTS ROOT SACK SERVER SOCKET SSL STYLE SYSLOG +%token TCP TIMEOUT TYPES %token ERROR INCLUDE %token STRING %token NUMBER %type port %type optssl +%type timeout %% @@ -228,6 +230,7 @@ server : SERVER STRING { sizeof(s->srv_conf.errorlog)); s->srv_conf.id = ++last_server_id; s->srv_conf.timeout.tv_sec = SERVER_TIMEOUT; + s->srv_conf.maxrequests = SERVER_MAXREQUESTS; s->srv_conf.flags |= SRVFLAG_LOG; s->srv_conf.logformat = LOG_FORMAT_COMMON; @@ -302,13 +305,13 @@ serveroptsl : LISTEN ON STRING port optssl { yyerror("tcp flags inside location"); YYERROR; } - } tcpflags - | TCP { + } tcpip + | CONNECTION { if (parentsrv != NULL) { - yyerror("tcp flags inside location"); + yyerror("connection options inside location"); YYERROR; } - } '{' tcpflags_l '}' + } connection | ROOT STRING { if (strlcpy(srv->srv_conf.root, $2, sizeof(srv->srv_conf.root)) >= @@ -436,6 +439,23 @@ fcgiflags : SOCKET STRING { } ; +connection : '{' conflags_l '}' + | conflags + ; + +conflags_l : conflags comma conflags_l + | conflags + ; + +conflags : TIMEOUT timeout { + memcpy(&srv_conf->timeout, &$2, + sizeof(struct timeval)); + } + | MAXIMUM REQUESTS NUMBER { + srv_conf->maxrequests = $3; + } + ; + dirflags_l : dirflags comma dirflags_l | dirflags ; @@ -530,6 +550,10 @@ logstyle : COMMON { } ; +tcpip : '{' tcpflags_l '}' + | tcpflags + ; + tcpflags_l : tcpflags comma tcpflags_l | tcpflags ; @@ -658,6 +682,17 @@ port : PORT STRING { } ; +timeout : NUMBER + { + if ($1 < 0) { + yyerror("invalid timeout: %d\n", $1); + YYERROR; + } + $$.tv_sec = $1; + $$.tv_usec = 0; + } + ; + comma : ',' | nl | /* empty */ @@ -721,11 +756,13 @@ lookup(char *s) { "listen", LISTEN }, { "location", LOCATION }, { "log", LOG }, + { "max", MAXIMUM }, { "no", NO }, { "nodelay", NODELAY }, { "on", ON }, { "port", PORT }, { "prefork", PREFORK }, + { "requests", REQUESTS }, { "root", ROOT }, { "sack", SACK }, { "server", SERVER }, @@ -734,6 +771,7 @@ lookup(char *s) { "style", STYLE }, { "syslog", SYSLOG }, { "tcp", TCP }, + { "timeout", TIMEOUT }, { "types", TYPES } }; const struct keywords *p; diff --git a/usr.sbin/httpd/server_http.c b/usr.sbin/httpd/server_http.c index ed061947758..91e648d3c59 100644 --- a/usr.sbin/httpd/server_http.c +++ b/usr.sbin/httpd/server_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_http.c,v 1.38 2014/08/05 16:30:36 reyk Exp $ */ +/* $OpenBSD: server_http.c,v 1.39 2014/08/05 18:01:10 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter @@ -711,7 +711,7 @@ server_response(struct httpd *httpd, struct client *clt) clt->clt_persist = 0; } - if (clt->clt_persist >= SERVER_MAXREQUESTS) + if (clt->clt_persist >= srv_conf->maxrequests) clt->clt_persist = 0; /* -- 2.20.1