Framework: Http Client multipart request

Created on 21 Mar 2020  路  4Comments  路  Source: laravel/framework

  • Laravel Version: ^7.2
  • PHP Version: 7.3.11
  • Database Driver & Version: MySQL 5.0.12

Description:

Http Client throws an error when passing both file and body params into POST request.

Steps To Reproduce:

$photo = fopen(public_path('/storage/') . $this->photoPath, 'r');

$response = Http::withToken($this->token)
    ->withHeaders([
        'X-Header' => $this->header
    ])
    ->attach('photo', $photo)
    ->post($url, [
        'name' => 'test'
    ]);

Request above ends up with throwing the following error:

TypeError: Argument 2 passed to GuzzleHttp\Psr7\MultipartStream::addElement() must be of the type array, string given, called in /vendor/guzzlehttp/psr7/src/MultipartStream.php on line 70 in file /vendor/guzzlehttp/psr7/src/MultipartStream.php on line 79

bug

Most helpful comment

@lumore It seems that during the process of creating Guzzle options array, if you have an ::attach in your flow, even though the body format is set to 'multipart', the post array data is not formatted but it is merged into options as it is. So in your example you should do as below, each post parameter should be introduced as an array with two keys ("name" and "contents"):

$photo = fopen(public_path('/storage/') . $this->photoPath, 'r');

$response = Http::withToken($this->token)
    ->withHeaders([
        'X-Header' => $this->header
    ])
    ->attach('photo', $photo)
    ->post($url, [
                [
                       'name' => 'param_1',
                       'contents' => 'param_1 contents'
                ],
                ....
    ]);

Note: I would personally say that this "issue" must be fixed (@laravel-internals ).

All 4 comments

Hey there,

Can you first please try one of the support channels below? If you can actually identify this as a bug, feel free to report back and I'll gladly help you out and re-open this issue.

Thanks!

@lumore It seems that during the process of creating Guzzle options array, if you have an ::attach in your flow, even though the body format is set to 'multipart', the post array data is not formatted but it is merged into options as it is. So in your example you should do as below, each post parameter should be introduced as an array with two keys ("name" and "contents"):

$photo = fopen(public_path('/storage/') . $this->photoPath, 'r');

$response = Http::withToken($this->token)
    ->withHeaders([
        'X-Header' => $this->header
    ])
    ->attach('photo', $photo)
    ->post($url, [
                [
                       'name' => 'param_1',
                       'contents' => 'param_1 contents'
                ],
                ....
    ]);

Note: I would personally say that this "issue" must be fixed (@laravel-internals ).

@driesvints This is definitely a bug and I can confirm I have reproduced it. The above solution works but should not be necessary. We should be able to do the following:

photo = fopen(public_path('/storage/') . $this->photoPath, 'r');

$response = Http::withToken($this->token)
    ->withHeaders([
        'X-Header' => $this->header
    ])
    ->attach('photo', $photo)
    ->post($url, [
                   'param_1' => 'param_1 contents',
                    ...
            ]);

This would bring it in line with the format of every other post request.

Okay re-opening. Feel free to send in a PR.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

digirew picture digirew  路  3Comments

gabriellimo picture gabriellimo  路  3Comments

felixsanz picture felixsanz  路  3Comments

shopblocks picture shopblocks  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments