Skip to content

[HttpClient] Header Content-Length missing when using callback as request-body #45965

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
SiebelsTim opened this issue Apr 7, 2022 · 1 comment

Comments

@SiebelsTim
Copy link

SiebelsTim commented Apr 7, 2022

Symfony version(s) affected

5.4.7

Description

In #45814 the HTTP-Client was changed to only set the content-length via the CURLOPT_INFILE option. However, that option is not used for CURLOPT_READFUNCTION. For that we would need CURLOPT_POSTFIELDSIZE which is not exposed in PHP (see php/php-src#8165).

As a result, when using a callback for the request's body, we cannot set the Content-Length header anymore.

In combination with resetting the Transfer-Encoding header to get curl to not send a chunked request, we cannot send a request with a body.

How to reproduce

<?php

use Symfony\Component\HttpClient\CurlHttpClient;

require_once __DIR__ . '/vendor/autoload.php';

$client = new CurlHttpClient([]);

$counter = 0;
$response = $client->request('POST', 'http://localhost:982/iserv/helloworld', [
    'headers' => ['Content-Length' => [10000], 'Transfer-Encoding' => [' ']],
    'body' => static function (int $length) use(&$counter){
        if ($counter++ > 0) {
            return "";
        }

        return str_repeat("A", 10000);
    },
]);

echo $response->getContent();

Possible Solution

No response

Additional Context

No response

@sihagen
Copy link

sihagen commented Apr 10, 2022

I can report a similar issue (also Symfony 5.4.7): When using a file for the body the Content-Length Header is set, but it

  1. is always set to 0 (propably not or wrong calculated) and
  2. cannot be overwritten manually.
$client = new CurlHttpClient();
$response = $client->request('POST', 'https://something', [
    'auth_bearer' => 'xxxxx',
    'headers' => [
        'User-Agent' => 'Custom Agent',
        'Content-Length' => [123456], // without this line the result below stays the same
        'body' => fopen('file', 'r'),
    ],
]);
dump($response);

...results in...

...
body: Resource id #1176
Accept: */*
Authorization: Bearer xxxxx[ ▶]()
User-Agent: Custom Agent
Accept-Encoding: gzip
Content-Length: 0
...

@fabpot fabpot closed this as completed Apr 12, 2022
fabpot added a commit that referenced this issue Apr 12, 2022
… body (nicolas-grekas)

This PR was merged into the 4.4 branch.

Discussion
----------

[HttpClient] Fix sending content-length when streaming the body

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #45965
| License       | MIT
| Doc PR        | -

Follows #45906 and previous PRs on the topic.

This PR partly reverts previous changes but keeps tests added to cover how we manage content-related headers when redirecting.

Relying on curl doesn't work in all cases, so we need to manage them on our own.

Commits
-------

ee57696 [HttpClient] Fix sending content-length when streaming the body
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants