Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Implement GH-12385: flush headers without body when calling flush() #12785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nielsdos wants to merge 1 commit into php:master from nielsdos:flush-headers

Conversation

Copy link
Member

@nielsdos nielsdos commented Nov 25, 2023
edited
Loading

I confirmed in my testing that two FCGI packets will be sent: one for the header and one for the content, which is what is requested.

I did notice however that on my nginx setup only one time it sends HTTP content to my browser.
However, that seems already to be the case with the flush functionality with normal body content. If we have only few bytes to flush then nginx waits for more bytes to send in the TCP packet. When creating a very large header is do see two times nginx sending HTTP data to my browser. I guess this is configurable in some way but just wanted to point out that this might have limited usefulness depending on the configuration.

Comment on lines +24 to +33
flush();
var_dump(headers_sent());
PHP;

$tester = new FPM\Tester($cfg, $code);
$tester->start();
$tester->expectLogStartNotices();
$response = $tester->request();
$response->expectHeader("X-Test", "12345");
$response->expectBody("bool(true)");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
flush();
var_dump(headers_sent());
PHP;
$tester = new FPM\Tester($cfg, $code);
$tester->start();
$tester->expectLogStartNotices();
$response = $tester->request();
$response->expectHeader("X-Test", "12345");
$response->expectBody("bool(true)");
$headersSentBeforeFlush = headers_sent();
flush();
$headersSentAfterFlush = headers_sent();
var_dump($headersSentBeforeFlush);
var_dump($headersSentAfterFlush);
PHP;
$tester = new FPM\Tester($cfg, $code);
$tester->start();
$tester->expectLogStartNotices();
$response = $tester->request();
$response->expectHeader("X-Test", "12345");
$response->expectBody("bool(false)\nbool(true)");

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't this this is necessary. We don't need to test what's given which is that headers are not sent at the beginning of request.

nielsdos reacted with thumbs up emoji
@@ -0,0 +1,46 @@
--TEST--
GH-12385 (flush with fastcgi does not force headers to be sent)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirmed in my testing that two FCGI packets will be sent: one for the header and one for the content, which is what is requested.

The feature request is about sending headers when flush() is called. I am not sure exactly what you meant by the cited sentence, but if the response buffer/body is empty, no (empty) packet for data should be sent.

If we have only few bytes to flush then nginx waits for more bytes to send in the TCP packet.

Am I understanding you right, headers are always sent with flush() (even with empty body) but small body is not sent even if flush() is called?

related discussion https://serverfault.com/questions/488767/how-do-i-enable-php-s-flush-with-nginxphp-fpm

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure exactly what you meant by the cited sentence, but if the response buffer/body is empty, no (empty) packet for data should be sent.

It means that an FCGI packet is sent for the header and body to the web server; whereas previously it would only send one. This implements the behaviour you want.

Am I understanding you right, headers are always sent with flush() (even with empty body) but small body is not sent even if flush() is called?

No. FPM will send it to the web server separately, but it all depends on what your web server does with it then, this is outside of the hands of PHP. The discussion link indeed summarizes it well.
Basically if you only send little data (be it headers or body content, doesn't matter) to nginx then it will wait for more data in the default configuration before sending data to the browser. That's what I wanted to highlight: that the usability highly depends of the behaviour of the web server.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah nginx buffers responses by default. You would need to disable buffering (fastcgi_buffering off) to potentially see impact of this.

Copy link
Contributor

@mvorisek mvorisek Dec 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@bukka bukka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Just one minor suggestion re the test name.

@@ -0,0 +1,46 @@
--TEST--
GH-12385 (flush with fastcgi does not force headers to be sent)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
GH-12385 (flush with fastcgi does not force headers to be sent)
FPM: GH-12385 - flush with fastcgi does not force headers to be sent

that's the format that I use for other FPM tests (mostly)

nielsdos reacted with thumbs up emoji
Comment on lines +24 to +33
flush();
var_dump(headers_sent());
PHP;

$tester = new FPM\Tester($cfg, $code);
$tester->start();
$tester->expectLogStartNotices();
$response = $tester->request();
$response->expectHeader("X-Test", "12345");
$response->expectBody("bool(true)");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't this this is necessary. We don't need to test what's given which is that headers are not sent at the beginning of request.

nielsdos reacted with thumbs up emoji
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@bukka bukka bukka approved these changes

+1 more reviewer

@mvorisek mvorisek mvorisek left review comments

Reviewers whose approvals may not affect merge requirements
Assignees
No one assigned
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

flush with fastcgi does not force headers to be sent

AltStyle によって変換されたページ (->オリジナル) /