Skip to content

Commit ed771e2

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

File tree

1 file changed

+59
-7
lines changed

1 file changed

+59
-7
lines changed

components/http_client.rst

Lines changed: 59 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,38 @@ 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.
205+
A generator can also be passed instead.
205206

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

210236
Cookies
@@ -257,6 +283,9 @@ following methods::
257283
// gets the response body as a string
258284
$content = $response->getContent();
259285

286+
// cancels the request/response
287+
$response->cancel();
288+
260289
// returns info coming from the transport layer, such as "response_headers",
261290
// "redirect_count", "start_time", "redirect_url", etc.
262291
$httpInfo = $response->getInfo();
@@ -303,6 +332,29 @@ response sequentially instead of waiting for the entire response::
303332
fwrite($fileHandler, $chunk->getContent());
304333
}
305334

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

@@ -529,7 +581,7 @@ PSR-18 Compatibility
529581
--------------------
530582

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

0 commit comments

Comments
 (0)