summaryrefslogtreecommitdiff
path: root/main/http.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/http.c')
-rw-r--r--main/http.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/main/http.c b/main/http.c
index 0c9395d9c..19b0199c8 100644
--- a/main/http.c
+++ b/main/http.c
@@ -71,8 +71,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define DEFAULT_PORT 8088
#define DEFAULT_TLS_PORT 8089
#define DEFAULT_SESSION_LIMIT 100
+#define DEFAULT_SESSION_INACTIVITY 30000 /* (ms) Idle time waiting for data. */
static int session_limit = DEFAULT_SESSION_LIMIT;
+static int session_inactivity = DEFAULT_SESSION_INACTIVITY;
static int session_count = 0;
static struct ast_tls_config http_tls_cfg;
@@ -1297,6 +1299,7 @@ static void *httpd_helper_thread(void *data)
enum ast_http_method http_method = AST_HTTP_UNKNOWN;
const char *transfer_encoding;
int remaining_headers;
+ int flags;
struct protoent *p;
if (ast_atomic_fetchadd_int(&session_count, +1) >= session_limit) {
@@ -1318,7 +1321,14 @@ static void *httpd_helper_thread(void *data)
ast_log(LOG_WARNING, "Some HTTP requests may be slow to respond.\n");
}
- if (!fgets(buf, sizeof(buf), ser->f)) {
+ /* make sure socket is non-blocking */
+ flags = fcntl(ser->fd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(ser->fd, F_SETFL, flags);
+
+ ast_tcptls_stream_set_timeout_inactivity(ser->stream_cookie, session_inactivity);
+
+ if (!fgets(buf, sizeof(buf), ser->f) || feof(ser->f)) {
goto done;
}
@@ -1358,12 +1368,19 @@ static void *httpd_helper_thread(void *data)
/* process "Request Headers" lines */
remaining_headers = MAX_HTTP_REQUEST_HEADERS;
- while (fgets(header_line, sizeof(header_line), ser->f)) {
- char *name, *value;
+ for (;;) {
+ char *name;
+ char *value;
+
+ if (!fgets(header_line, sizeof(header_line), ser->f) || feof(ser->f)) {
+ ast_http_error(ser, 400, "Bad Request", "Timeout");
+ goto done;
+ }
/* Trim trailing characters */
ast_trim_blanks(header_line);
if (ast_strlen_zero(header_line)) {
+ /* A blank line ends the request header section. */
break;
}
@@ -1431,7 +1448,7 @@ done:
ast_variables_destroy(headers);
if (ser->f) {
- fclose(ser->f);
+ ast_tcptls_close_session_file(ser);
}
ao2_ref(ser, -1);
ser = NULL;
@@ -1541,6 +1558,9 @@ static int __ast_http_load(int reload)
ast_sockaddr_setnull(&https_desc.local_address);
+ session_limit = DEFAULT_SESSION_LIMIT;
+ session_inactivity = DEFAULT_SESSION_INACTIVITY;
+
if (cfg) {
v = ast_variable_browse(cfg, "general");
for (; v; v = v->next) {
@@ -1586,6 +1606,12 @@ static int __ast_http_load(int reload)
ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of http.conf\n",
v->name, v->value, v->lineno);
}
+ } else if (!strcasecmp(v->name, "session_inactivity")) {
+ if (ast_parse_arg(v->value, PARSE_INT32 |PARSE_DEFAULT | PARSE_IN_RANGE,
+ &session_inactivity, DEFAULT_SESSION_INACTIVITY, 1, INT_MAX)) {
+ ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of http.conf\n",
+ v->name, v->value, v->lineno);
+ }
} else {
ast_log(LOG_WARNING, "Ignoring unknown option '%s' in http.conf\n", v->name);
}