Skip to content

[HttpClient] Data collection fails when sending a resource array body to unreachable URL #62696

@Kern046

Description

@Kern046

Symfony version(s) affected

From 6.1 to 8.1

Description

I was trying to send a file through the HTTP Client, using an array body like described in the documentation.

$httpClient->request('POST', 'http://localhast:8000/receive-file', [
    'body' => [
        'file' => fopen($projectDir . '/test_upload_file.txt', 'r'),
    ]
]);

In the case of an unreachable host, I would normally get Could not resolve host error. But with the array body with the Web Profiler enabled, I get a PHP error: explode(): Argument #2 ($string) must be of type string, Closure given.

This happens in HttpClientDataCollector::getCurlCommand() method when collecting data for the Profiler. It tries to get data from the body by using HttpClientTrait::normalizeBody, which returns a Closure.

The result is used as the second argument of the explode function, which expects a string.

How to reproduce

You can install this reproducer and follow its README.md instructions.

Possible Solution

In a more regular case, when not using an array or not sending resources, the HttpClient manages to display the right error : Could not resolve host:.

Maybe we could test the normalized body type and execute the closure when this case occurs ? I don't know yet if it would allow the Http Client to return the host resolving error properly.

Not really sure about the nice solution but I would be delighted to contribute on closing this issue !

Additional Context

Stack Trace

explode(): Argument #2 ($string) must be of type string, Closure given
TypeError:
explode(): Argument #2 ($string) must be of type string, Closure given

at ./vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php:206
at explode('&', object(Closure))
(./vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php:206)
at Symfony\Component\HttpClient\DataCollector\HttpClientDataCollector->getCurlCommand(array('method' => 'POST', 'url' => 'http://localhast:8000/receive-file', 'options' => array('body' => array('file' => resource)), 'info' => array('url' => 'http://localhast:8000/receive-file', 'content_type' => null, 'http_code' => 0, 'header_size' => 0, 'request_size' => 0, 'filetime' => -1, 'ssl_verify_result' => 0, 'redirect_count' => 0, 'total_time' => 0.017094, 'namelookup_time' => 0.0, 'connect_time' => 0.0, 'pretransfer_time' => 0.0, 'size_upload' => 0.0, 'size_download' => 0.0, 'speed_download' => 0.0, 'speed_upload' => 0.0, 'download_content_length' => -1.0, 'upload_content_length' => -1.0, 'starttransfer_time' => 0.0, 'redirect_time' => 0.0, 'redirect_url' => '', 'primary_ip' => '', 'certinfo' => array(), 'primary_port' => -1, 'local_ip' => '', 'local_port' => -1, 'http_version' => 0, 'protocol' => 1, 'ssl_verifyresult' => 0, 'scheme' => 'http', 'appconnect_time_us' => 0, 'connect_time_us' => 0, 'namelookup_time_us' => 0, 'pretransfer_time_us' => 0, 'redirect_time_us' => 0, 'starttransfer_time_us' => 0, 'total_time_us' => 17094, 'response_headers' => array(), 'error' => null, 'canceled' => false, 'http_method' => 'POST', 'user_data' => null, 'max_duration' => 0.0, 'start_time' => 1765209785.578974, 'original_url' => 'http://localhast:8000/receive-file', 'pause_handler' => object(Closure), 'debug' => ''), 'content' => null))
(./vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php:173)
at Symfony\Component\HttpClient\DataCollector\HttpClientDataCollector->collectOnClient(object(TraceableHttpClient))
(./vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php:53)
at Symfony\Component\HttpClient\DataCollector\HttpClientDataCollector->lateCollect()
(./vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php:43)
at Symfony\Component\HttpClient\DataCollector\HttpClientDataCollector->collect(object(Request), object(Response), object(TypeError))
(./vendor/symfony/http-kernel/Profiler/Profiler.php:169)
at Symfony\Component\HttpKernel\Profiler\Profiler->collect(object(Request), object(Response), object(TypeError))
(./vendor/symfony/http-kernel/EventListener/ProfilerListener.php:108)
at Symfony\Component\HttpKernel\EventListener\ProfilerListener->onKernelResponse(object(ResponseEvent), 'kernel.response', object(TraceableEventDispatcher))
(./vendor/symfony/event-dispatcher/Debug/WrappedListener.php:116)
at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(ResponseEvent), 'kernel.response', object(TraceableEventDispatcher))
(./vendor/symfony/event-dispatcher/EventDispatcher.php:220)
at Symfony\Component\EventDispatcher\EventDispatcher->callListeners(array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.response', object(ResponseEvent))
(./vendor/symfony/event-dispatcher/EventDispatcher.php:56)
at Symfony\Component\EventDispatcher\EventDispatcher->dispatch(object(ResponseEvent), 'kernel.response')
(./vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:139)
at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch(object(ResponseEvent), 'kernel.response')
(./vendor/symfony/http-kernel/HttpKernel.php:214)
at Symfony\Component\HttpKernel\HttpKernel->filterResponse(object(Response), object(Request), 2)
(./vendor/symfony/http-kernel/HttpKernel.php:202)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 2)
(./vendor/symfony/http-kernel/HttpKernel.php:76)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 2, false)
(./vendor/symfony/http-kernel/EventListener/ErrorListener.php:117)
at Symfony\Component\HttpKernel\EventListener\ErrorListener->onKernelException(object(ExceptionEvent), 'kernel.exception', object(TraceableEventDispatcher))
(./vendor/symfony/event-dispatcher/Debug/WrappedListener.php:116)
at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(ExceptionEvent), 'kernel.exception', object(TraceableEventDispatcher))
(./vendor/symfony/event-dispatcher/EventDispatcher.php:220)
at Symfony\Component\EventDispatcher\EventDispatcher->callListeners(array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.exception', object(ExceptionEvent))
(./vendor/symfony/event-dispatcher/EventDispatcher.php:56)
at Symfony\Component\EventDispatcher\EventDispatcher->dispatch(object(ExceptionEvent), 'kernel.exception')
(./vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:139)
at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch(object(ExceptionEvent), 'kernel.exception')
(./vendor/symfony/http-kernel/HttpKernel.php:239)
at Symfony\Component\HttpKernel\HttpKernel->handleThrowable(object(TypeError), object(Request), 1)
(./vendor/symfony/http-kernel/HttpKernel.php:132)
at Symfony\Component\HttpKernel\HttpKernel->terminateWithException(object(TypeError), object(Request))
(./vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php:84)
at Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::Symfony\Component\HttpKernel\EventListener{closure}(object(TypeError))
(./vendor/symfony/error-handler/ErrorHandler.php:538)
at Symfony\Component\ErrorHandler\ErrorHandler->handleException(object(TypeError))

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions