From 8033504e79cf197d99ab20a6d89161a2f6a71a81 Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Mon, 15 Aug 2016 20:57:36 +0200 Subject: If you see any problem connecting to httpd fastcgi, stalled connections, please have a look at the log files for: "server_response: request %d in %s not finished" where %d is the request number in a persistent connection and %s is either server_file or server_fcgi. The server_fcgi.c code also includes "//"-commented code for two possible solutions: either reset after each FCGI_END_REQUEST or after finishing the end request or any possible padding. --- httpd/httpd.h | 3 ++- httpd/server_fcgi.c | 12 ++++++++++++ httpd/server_file.c | 8 ++++---- httpd/server_http.c | 9 ++++++++- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/httpd/httpd.h b/httpd/httpd.h index 595cce9..7b4b93e 100644 --- a/httpd/httpd.h +++ b/httpd/httpd.h @@ -302,6 +302,7 @@ struct client { off_t clt_toread; size_t clt_headerlen; unsigned int clt_persist; + const char *clt_persist_running; int clt_line; int clt_done; int clt_chunk; @@ -586,7 +587,7 @@ int server_headers(struct client *, void *, int server_writeresponse_http(struct client *); int server_response_http(struct client *, unsigned int, struct media_type *, off_t, time_t); -void server_reset_http(struct client *); +void server_reset_http(struct client *, const char *); void server_close_http(struct client *); int server_response(struct httpd *, struct client *); const char * diff --git a/httpd/server_fcgi.c b/httpd/server_fcgi.c index 21ebeed..47cfbf1 100644 --- a/httpd/server_fcgi.c +++ b/httpd/server_fcgi.c @@ -99,6 +99,8 @@ server_fcgi(struct httpd *env, struct client *clt) const char *stripped, *p, *alias, *errstr = NULL; char *str, *script = NULL; + clt->clt_persist_running = __func__; + if (srv_conf->socket[0] == ':') { struct sockaddr_storage ss; in_port_t port; @@ -575,11 +577,18 @@ server_fcgi_read(struct bufferevent *bev, void *arg) clt->clt_fcgi_state = FCGI_READ_HEADER; clt->clt_fcgi_toread = sizeof(struct fcgi_record_header); +// variant a 1/2: +// if (clt->clt_fcgi_end) +// server_reset_http(clt, +// "FCGI_READ_CONTENT"); } else { clt->clt_fcgi_state = FCGI_READ_PADDING; clt->clt_fcgi_toread = clt->clt_fcgi_padding_len; } +// variant b 1/1: +// if (clt->clt_fcgi_type == FCGI_END_REQUEST) +// server_reset_http(clt, "FCGI_END_REQUEST"); break; case FCGI_READ_PADDING: evbuffer_drain(clt->clt_srvevb, @@ -587,6 +596,9 @@ server_fcgi_read(struct bufferevent *bev, void *arg) clt->clt_fcgi_state = FCGI_READ_HEADER; clt->clt_fcgi_toread = sizeof(struct fcgi_record_header); +// variant a 2/2: +// if (clt->clt_fcgi_end) +// server_reset_http(clt, "FCGI_READ_PADDING"); break; } } while (len > 0); diff --git a/httpd/server_file.c b/httpd/server_file.c index 48ecbb5..b2496d7 100644 --- a/httpd/server_file.c +++ b/httpd/server_file.c @@ -280,7 +280,7 @@ server_file_request(struct httpd *env, struct client *clt, char *path, bufferevent_disable(clt->clt_bev, EV_READ); done: - server_reset_http(clt); + server_reset_http(clt, __func__); return (0); fail: bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE); @@ -420,7 +420,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path, clt->clt_done = 0; done: - server_reset_http(clt); + server_reset_http(clt, __func__); return (0); fail: bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE); @@ -583,7 +583,7 @@ server_file_index(struct httpd *env, struct client *clt, struct stat *st) clt->clt_done = 0; done: - server_reset_http(clt); + server_reset_http(clt, __func__); return (0); fail: bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE); @@ -627,7 +627,7 @@ server_file_error(struct bufferevent *bev, short error, void *arg) close(clt->clt_fd); clt->clt_fd = -1; clt->clt_toread = TOREAD_HTTP_HEADER; - server_reset_http(clt); + server_reset_http(clt, __func__); bufferevent_enable(clt->clt_bev, EV_READ|EV_WRITE); return; } diff --git a/httpd/server_http.c b/httpd/server_http.c index b69805a..4ea20ab 100644 --- a/httpd/server_http.c +++ b/httpd/server_http.c @@ -615,10 +615,13 @@ server_read_httpchunks(struct bufferevent *bev, void *arg) } void -server_reset_http(struct client *clt) +server_reset_http(struct client *clt, const char *from) { struct server *srv = clt->clt_srv; + log_debug("%s: called from %s", __func__, from); + clt->clt_persist_running = NULL; + server_log(clt, NULL); server_httpdesc_free(clt->clt_descreq); @@ -1092,6 +1095,10 @@ server_response(struct httpd *httpd, struct client *clt) clt->clt_persist = 0; } + if (clt->clt_persist_running) + log_warnx("%s: request %d in %s not finished", + __func__, clt->clt_persist, clt->clt_persist_running); + if (clt->clt_persist >= srv_conf->maxrequests) clt->clt_persist = 0; -- cgit v1.2.3-54-g00ecf