Bug #79991 [Opn->Fbk]: Connection handling mod_php and mod_fcgid
Edit report at https://bugs.php.net/bug.php?id=79991&edit=1
ID: 79991
Updated by: requinix@php.net
Reported by: hoover at gmx dot at
Summary: Connection handling mod_php and mod_fcgid
-Status: Open
+Status: Feedback
Type: Bug
Package: *General Issues
Operating System: Windows Server 2012
PHP Version: 7.2.33
Block user comment: N
Private report: N
New Comment:
Client aborts are essentially client-closed connections, so they aren't detected until you try
to write to that connection and TCP reports failure.
https://www.php.net/manual/en/features.connection-handling.php
> A1) If we do a simple echo of the payload and a flush()
> the client waits until 9) (until the php-script has total
> finished). A client abort, with above functions, is never
> detected.
You have to send output, then check connection_aborted().
> A2) After thousand days of trail and error we noticed that at
> least a content-length header has to be set by the php-script
> to "release the client". So 7) close connection to client
> does work. But again no chance to detect a client abort.
Correct: without a Content-Length the client has no idea how long the response is going to be. It
will hang on until the connection is closed, or
with a chunked Transfer-Encoding (IIRC what PHP does by default) until it receives a 0-length chunk
indicating the end of the response.
If you were using php-fpm (which Apache itself recommends) then you'd have access to
fastcgi_finish_request().
https://cwiki.apache.org/confluence/display/HTTPD/Php-fcgid
https://www.php.net/manual/en/function.fastcgi-finish-request.php
> A3) After thousand days of trail and error we noticed that
> after a content-length and an echo payload and a flush()
> and at least a echo {SPACE} after the flush => detects
> a client abort.
...which satisfies the "have to send output" requirement.
> Analysed with wireshark the {SPACE} fortunately
> gets lost in TCP and not sent to the client.
PHP should not be dropping the space, so presumably your web server is.
> B1) The same thing with mod_fcgid would not work.
I'm not familiar with mod_fcgid but I suspect you're running into FcgidOutputBufferSize.
https://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html#fcgidoutputbuffersize
If mod_fcgid is buffering output then PHP won't know about problems until the buffer gets
flushed. Even then, I don't know how CGI/mod_fcgid handles client aborts.
Previous Comments:
------------------------------------------------------------------------
[2020-08-18 15:05:51] hoover at gmx dot at
Description:
------------
This thing is nearly version independent. The behavior can
be found with 5.4, 7.0 and 7.2.
There are many bug reports for this case but none of them has
a reproducible solution. The bug reports are starting 2005 so
this thing is long lasting.
We have a php-rest-api (no framework) that simplifies a heavy
(java) soap-api.
We have to do a lot of work after the rest/soap-processing. So,
the client of the rest-api gets a response, php should finish
the request and then php should procced with the internal work.
At the point where the client gets the response php should be
aware if client is still alive. So in short:
1) Client - requests
2) PHP - processes
3) PHP - requests soap-server
4) PHP - processes
5) PHP - repsonses to client
6) PHP - should check if client still alive
7) PHP - should close connection to client
8) PHP - processes
9) PHP finished.
So it looks like:
* ignore_user_abort = true
* No use of gzip or ...
* zlib.output_compression = 0
* output_buffering = '0'
* implicit_flush = 1;
* ob_implicit_flush(1);
* Content-Encoding: identity
Functions for connHandling:
connection_aborted()
AND
connection_status()
A) mod_php
A1) If we do a simple echo of the payload and a flush()
the client waits until 9) (until the php-script has total
finished). A client abort, with above functions, is never
detected.
A2) After thousand days of trail and error we noticed that at
least a content-length header has to be set by the php-script
to "release the client". So 7) close connection to client
does work. But again no chance to detect a client abort.
A3) After thousand days of trail and error we noticed that
after a content-length and an echo payload and a flush()
and at least a echo {SPACE} after the flush => detects
a client abort. Analysed with wireshark the {SPACE} fortunately
gets lost in TCP and not sent to the client.
Perfect!
BUT,
B) mod_fcgid
B1) The same thing with mod_fcgid would not work.
It was really hard to find out how connection handling has actually to
be done in this scenario. The php docs are not very helpful here.
Other bug reports are also not very helpful.
So my bug report is at least a question to the php developers:
What is the right and reliable way for connection handling (in
this scenario) wiht mod_php and mod_fcgid?
Regards,
AH
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=79991&edit=1
Thread (4 messages)