Upload File Using Guzzle 6 to API Endpoint

Upload file using Guzzle 6 to API endpoint

The way you are POSTing data is wrong, hence received data is malformed.

Guzzle docs:

The value of multipart is an array of associative arrays, each
containing the following key value pairs:

name: (string, required) the form field name

contents:(StreamInterface/resource/string, required) The data to use in the
form element.

headers: (array) Optional associative array of custom headers to use with the form element.

filename: (string) Optional
string to send as the filename in the part.

Using keys out of above list and setting unnecessary headers without separating each field into one array will result in making a bad request.

$res = $client->request('POST', $this->base_api . $endpoint, [
'auth' => [ env('API_USERNAME'), env('API_PASSWORD') ],
'multipart' => [
[
'name' => 'FileContents',
'contents' => file_get_contents($path . $name),
'filename' => $name
],
[
'name' => 'FileInfo',
'contents' => json_encode($fileinfo)
]
],
]);

send file to an api using guzzle http client

Your class Product doesnt have the method getPath() declared

file_get_contents($product_details->getPath())

Change it so it uses the path you used above that line

file_get_contents(public_path() . "/images/product/$product_id/".$filename)

Upload file using Guzzle 6 to ebay FEED_API endpoint

My mistake was to manually insert the content-type in the headers.

This is my working code:
My mistake was to manually insert the content-type in the headers.

This is my working code:

$client = new GuzzleHttp\Client(['base_uri' => 'https://api.ebay.com']);

$client->request('POST', '/sell/feed/v1/task/task-40-XXXXXXXXXX/upload_file', [
'headers' => [
'Authorization' => 'Bearer ' . $this->getToken($ebayStore)
],
'multipart' => [
[
'name' => 'file',
'contents' => fopen($file, 'r'),
'filename' => basename($file),
'headers' => [
'Content-Disposition' => 'form-data; name="file"; fileName="'.basename($file).'"; type="form-data"'
]
]
]
]);

How to send files with Guzzle without loading them into memory

I finally managed to make this work by changing

'contents' => file_get_contents($file->path()),

to

'contents' => \GuzzleHttp\Psr7\stream_for(fopen($file->path(), 'r'))

With this change files were not loaded into memory and I was able to send bigger files

Post data and file together to Laravel API using Guzzle

Well I finally figured it out. The second example from above is the way to go also be sure to check the headers of the request and the client...

As this API has been running for quite some time and was only doing json type requests, the Client was instantiated with

$options = [
headers => [ 'Content-Type' => 'application/json']
]

Which, as stated in multiple answers across the internet, prevents Guzzle to automatically set the Content-Type depending of the request options.

In my case, removing this line made Guzzle enable to set it properly when provided with 'multipart' option.

Also, as all other requests are using the 'json' options, Guzzle also works it's magic and set 'Content-Type' => 'application/json' as well.



Related Topics



Leave a reply



Submit