Skip to content

Commit 8221276

Browse files
[HttpClient] doc how to cancel a request + upload files
1 parent e0a86d1 commit 8221276

File tree

2 files changed

+61
-8
lines changed

2 files changed

+61
-8
lines changed

components/http_client.rst

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ processed automatically when making the requests::
186186
'body' => ['parameter1' => 'value1', '...'],
187187

188188
// using a closure to generate the uploaded data
189-
'body' => function () {
189+
'body' => function (int $size): string {
190190
// ...
191191
},
192192

@@ -199,12 +199,39 @@ When uploading data with the ``POST`` method, if you don't define the
199199
form data and adds the required
200200
``'Content-Type: application/x-www-form-urlencoded'`` header for you.
201201

202-
When uploading JSON payloads, use the ``json`` option instead of ``body``. The
203-
given content will be JSON-encoded automatically and the request will add the
204-
``Content-Type: application/json`` automatically too::
202+
When the `body` option is set as a closure, it will be called several times until
203+
it returns the empty string, which signals the end of the body. Each time, the
204+
closure should return a string smaller than the amount requested as argument.
205205

206-
$response = $httpClient->request('POST', 'https://...', [
207-
'json' => ['param1' => 'value1', '...'],
206+
A generator or any ``Traversable`` can also be used instead of a closure.
207+
208+
.. tip::
209+
210+
When uploading JSON payloads, use the ``json`` option instead of ``body``. The
211+
given content will be JSON-encoded automatically and the request will add the
212+
``Content-Type: application/json`` automatically too::
213+
214+
$response = $httpClient->request('POST', 'https://...', [
215+
'json' => ['param1' => 'value1', '...'],
216+
]);
217+
218+
$decodedPayload = $response->toArray();
219+
220+
To submit a form with file uploads, it is your responsibility to encode the body
221+
according to the ``multipart/form-data`` content-type. The
222+
:doc:`Symfony Mime </components/mime>` component makes it a few lines of code::
223+
224+
use Symfony\Component\Mime\Part\DataPart;
225+
use Symfony\Component\Mime\Part\Multipart\FormDataPart;
226+
227+
$formFields = [
228+
'regular_field' => 'some value',
229+
'file_field' => DataPart::fromPath('/path/to/uploaded/file'),
230+
];
231+
$formData = new FormDataPart($formFields);
232+
$client->request('POST', 'https://...', [
233+
'headers' => $formData->getPreparedHeaders()->toArray(),
234+
'body' => $formData->bodyToIterable(),
208235
]);
209236

210237
Cookies
@@ -257,6 +284,9 @@ following methods::
257284
// gets the response body as a string
258285
$content = $response->getContent();
259286

287+
// cancels the request/response
288+
$response->cancel();
289+
260290
// returns info coming from the transport layer, such as "response_headers",
261291
// "redirect_count", "start_time", "redirect_url", etc.
262292
$httpInfo = $response->getInfo();
@@ -303,6 +333,29 @@ response sequentially instead of waiting for the entire response::
303333
fwrite($fileHandler, $chunk->getContent());
304334
}
305335

336+
Canceling Responses
337+
~~~~~~~~~~~~~~~~~~~
338+
339+
To abort a request (e.g. because it didn't complete in due time, or you want to
340+
fetch only the first bytes of the response, etc.), you can either:
341+
342+
* use the ``cancel()`` method of ``ResponseInterface``::
343+
344+
$response->cancel()
345+
346+
* throw an exception from a progress callback::
347+
348+
$response = $client->request('GET', 'https://..;', [
349+
'on_progress' => function (int $dlNow, int $dlSize, array $info): void {
350+
// ...
351+
352+
throw new \MyException();
353+
},
354+
]);
355+
356+
The exception will be wrapped in a ``TransportExceptionInterface`` and will
357+
abort the request.
358+
306359
Handling Exceptions
307360
~~~~~~~~~~~~~~~~~~~
308361

@@ -529,7 +582,7 @@ PSR-18 Compatibility
529582
--------------------
530583

531584
This component uses and implements abstractions defined by the
532-
``symfony/contracts`` package. It also implements the `PSR-18`_ (HTTP Client)
585+
``symfony/http-client-contracts``. It also implements the `PSR-18`_ (HTTP Client)
533586
specifications via the :class:`Symfony\\Component\\HttpClient\\Psr18Client`
534587
class, which is an adapter to turn a Symfony ``HttpClientInterface`` into a
535588
PSR-18 ``ClientInterface``.

reference/configuration/framework.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ This service can be configured using ``framework.http_client.default_options``:
699699
http_client:
700700
max_host_connections: 10
701701
default_options:
702-
headers: [{ 'X-Powered-By': 'ACME App' }]
702+
headers: { 'X-Powered-By': 'ACME App' }
703703
max_redirects: 7
704704
705705
.. _reference-http-client-scoped-clients:

0 commit comments

Comments
 (0)