diff options
Diffstat (limited to 'main/http.c')
-rw-r--r-- | main/http.c | 34 |
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); } |