From f346bd6ee6a9eecb3666071d3afd30216439367d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 7 Jan 2017 22:42:45 +0100 Subject: [PATCH 1/2] Rename fcgi_request.closed to .ended "closed" refers to whether FCGI_END_REQUEST has been sent, while the "close" operation does something entirely different. It gets extra confusing when fcgi_is_closed() does not actually return fcgi_request.closed... --- main/fastcgi.c | 12 ++++++------ main/fastcgi.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/main/fastcgi.c b/main/fastcgi.c index bf4eb6ca26a..c52d222df5c 100644 --- a/main/fastcgi.c +++ b/main/fastcgi.c @@ -216,7 +216,7 @@ struct _fcgi_request { #ifdef TCP_NODELAY int nodelay; #endif - int closed; + int ended; int in_len; int in_pad; @@ -1045,7 +1045,7 @@ static int fcgi_read_request(fcgi_request *req) unsigned char buf[FCGI_MAX_LENGTH+8]; req->keep = 0; - req->closed = 0; + req->ended = 0; req->in_len = 0; req->out_hdr = NULL; req->out_pos = req->out_buf; @@ -1503,7 +1503,7 @@ static inline void close_packet(fcgi_request *req) } } -int fcgi_flush(fcgi_request *req, int close) +int fcgi_flush(fcgi_request *req, int end) { int len; @@ -1511,7 +1511,7 @@ int fcgi_flush(fcgi_request *req, int close) len = (int)(req->out_pos - req->out_buf); - if (close) { + if (end) { fcgi_end_request_rec *rec = (fcgi_end_request_rec*)(req->out_pos); fcgi_make_header(&rec->hdr, FCGI_END_REQUEST, req->id, sizeof(fcgi_end_request)); @@ -1650,9 +1650,9 @@ int fcgi_finish_request(fcgi_request *req, int force_close) int ret = 1; if (req->fd >= 0) { - if (!req->closed) { + if (!req->ended) { ret = fcgi_flush(req, 1); - req->closed = 1; + req->ended = 1; } fcgi_close(req, force_close, 1); } diff --git a/main/fastcgi.h b/main/fastcgi.h index 460ace5624d..fbc70c31cf2 100644 --- a/main/fastcgi.h +++ b/main/fastcgi.h @@ -118,7 +118,7 @@ void fcgi_loadenv(fcgi_request *req, fcgi_apply_func load_func, zval *array); int fcgi_read(fcgi_request *req, char *str, int len); int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len); -int fcgi_flush(fcgi_request *req, int close); +int fcgi_flush(fcgi_request *req, int end); #ifdef PHP_WIN32 void fcgi_impersonate(void); From a46bbdda2e082070bd67ecdc500d9671bf1ab823 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 7 Jan 2017 22:51:18 +0100 Subject: [PATCH 2/2] Fixed bug #67583 As fcgi_request is an opaque struct as of PHP 7, expose a new API function fcgi_end() which does fcgi_flush() with end=1 and checks/ sets the ->ended flag. --- NEWS | 4 ++++ main/fastcgi.c | 14 ++++++++++---- main/fastcgi.h | 1 + sapi/fpm/fpm/fpm_main.c | 3 +-- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index ba821fd202c..8a297b98f22 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2017 PHP 7.0.16 +- FPM: + . Fixed bug #67583 (double fastcgi_end_request on max_children limit). + (Dmitry Saprykin) + - OpenSSL: . Fixed bug #71519 (add serial hex to return value array). (xrobau) diff --git a/main/fastcgi.c b/main/fastcgi.c index c52d222df5c..dd7c7ddeb9b 100644 --- a/main/fastcgi.c +++ b/main/fastcgi.c @@ -1645,15 +1645,21 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l return len; } +int fcgi_end(fcgi_request *req) { + int ret = 1; + if (!req->ended) { + ret = fcgi_flush(req, 1); + req->ended = 1; + } + return ret; +} + int fcgi_finish_request(fcgi_request *req, int force_close) { int ret = 1; if (req->fd >= 0) { - if (!req->ended) { - ret = fcgi_flush(req, 1); - req->ended = 1; - } + ret = fcgi_end(req); fcgi_close(req, force_close, 1); } return ret; diff --git a/main/fastcgi.h b/main/fastcgi.h index fbc70c31cf2..bba64016d89 100644 --- a/main/fastcgi.h +++ b/main/fastcgi.h @@ -119,6 +119,7 @@ int fcgi_read(fcgi_request *req, char *str, int len); int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len); int fcgi_flush(fcgi_request *req, int end); +int fcgi_end(fcgi_request *req); #ifdef PHP_WIN32 void fcgi_impersonate(void); diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 5e09877eefc..3ab92b30704 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1533,11 +1533,10 @@ PHP_FUNCTION(fastcgi_finish_request) /* {{{ */ fcgi_request *request = (fcgi_request*) SG(server_context); if (!fcgi_is_closed(request)) { - php_output_end_all(); php_header(); - fcgi_flush(request, 1); + fcgi_end(request); fcgi_close(request, 0, 0); RETURN_TRUE; }