Skip to content

Conversation

@susnux
Copy link
Contributor

@susnux susnux commented Sep 4, 2025

Summary

Context: Using Transfer-Encoding: chunked of HTTP 1.1

PHP-FPM has a bug1 where the request body is not passed to PHP if the Content-Length header is missing, while FastCGI in general allows this (I could reproduce that FastCGI passed the request stream from NGinx) PHP-FPM does not forward this to the PHP application.

This means when using PHP-FPM we get an empty request body and thus every PUT will be an empty file.

I tested that mod_php is not affected, while it also has no Content-Length header, it correctly passed the stream and thus also works without buffering the request.

Only PHP-FPM needs buffering of the request so that a Content-Length header can be generated.

To enable this on Apache set: SetEnvIfNoCase Transfer-Encoding "chunked" proxy-sendcl=1
On NGinx: fastcgi_request_buffering on;.

ref: #7995

Checklist

Context: Using `Transfer-Encoding: chunked` of HTTP 1.1

PHP-FPM has a bug[1] where the request body is not passed to PHP
if the `Content-Length` header is missing, while FastCGI in general
allows this (I could reproduce that FastCGI passed the request stream
from NGinx) PHP-FPM does not forward this to the PHP application.

This means when using PHP-FPM we get an empty request body and thus
every `PUT` will be an empty file.

I tested that `mod_php` is not affected, while it also has no
`Content-Length` header, it correctly passed the stream and thus also
works without buffering the request.

Only PHP-FPM needs buffering of the request so that a `Content-Length`
header can be generated.

To enable this on Apache set: `SetEnvIfNoCase Transfer-Encoding "chunked" proxy-sendcl=1`
On NGinx: `fastcgi_request_buffering on;`.

[1]: php/php-src#9441
ref: #7995

Signed-off-by: Ferdinand Thiessen <[email protected]>
@susnux susnux added this to the Nextcloud 33 milestone Sep 4, 2025
@susnux susnux requested a review from a team as a code owner September 4, 2025 23:16
@susnux susnux requested review from come-nc, icewind1991 and yemkareems and removed request for a team September 4, 2025 23:16
@susnux susnux added enhancement 3. to review Waiting for reviews labels Sep 4, 2025
@susnux
Copy link
Contributor Author

susnux commented Sep 4, 2025

/backport to stable32

@susnux
Copy link
Contributor Author

susnux commented Sep 4, 2025

/backport to stable31

$url = $this->urlGenerator->linkToRoute('settings.CheckSetup.checkContentLengthHeader');
foreach ($this->runRequest('PUT', $url, ['ignoreSSL' => true, 'options' => $options]) as $response) {
$contentType = $response->getHeader('Content-Type');
if (!str_contains(strtolower($contentType), 'application/json')) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I’d like a comment for this one, what does it mean if content type is something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Then its not a Nextcloud response - some safe guard for reverse proxys so the following check on the response can be done.

. $this->l10n->t('Due to a limitation of PHP-FPM chunked requests will not be passed to Nextcloud if the server does not buffer such requests.'),
);
} else {
// Not using FPM but we are on CLI so we do not know if FPM is used
Copy link
Contributor

Choose a reason for hiding this comment

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

The endpoint could return $usingFPM while we’re at it, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants