Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload file using Guzzle 6 to API endpoint

I am able to upload a file to an API endpoint using Postman.

I am trying to translate that into uploading a file from a form, uploading it using Laravel and posting to the endpoint using Guzzle 6.

Screenshot of how it looks in Postman (I purposely left out the POST URL) enter image description here

Below is the text it generates when you click the "Generate Code" link in POSTMAN:

POST /api/file-submissions HTTP/1.1 Host: strippedhostname.com Authorization: Basic 340r9iu34ontoeioir Cache-Control: no-cache Postman-Token: 6e0c3123-c07c-ce54-8ba1-0a1a402b53f1 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW  ----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="FileContents"; filename="" Content-Type:    ----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="FileInfo"  { "name": "_aaaa.txt", "clientNumber": "102425", "type": "Writeoff" } ----WebKitFormBoundary7MA4YWxkTrZu0gW 

Below is controller function for saving the file and other info. The file uploads correctly, I am able to get the file info.

I think the problem I am having is setting the multipart and headers array with the correct data.

public function fileUploadPost(Request $request) {     $data_posted = $request->input();     $endpoint = "/file-submissions";     $response = array();     $file = $request->file('filename');     $name = time() . '_' . $file->getClientOriginalName();     $path = base_path() .'/public_html/documents/';      $resource = fopen($file,"r") or die("File upload Problems");      $file->move($path, $name);      // { "name": "test_upload.txt", "clientNumber": "102425", "type": "Writeoff" }     $fileinfo = array(         'name'          =>  $name,         'clientNumber'  =>  "102425",         'type'          =>  'Writeoff',     );      $client = new \GuzzleHttp\Client();      $res = $client->request('POST', $this->base_api . $endpoint, [         'auth' => [env('API_USERNAME'), env('API_PASSWORD')],         'multipart' => [             [                 'name'  =>  $name,                 'FileContents'  => fopen($path . $name, 'r'),                 'contents'      => fopen($path . $name, 'r'),                 'FileInfo'      => json_encode($fileinfo),                 'headers'       =>  [                     'Content-Type' => 'text/plain',                     'Content-Disposition'   => 'form-data; name="FileContents"; filename="'. $name .'"',                 ],                 // 'contents' => $resource,             ]         ],     ]);      if($res->getStatusCode() != 200) exit("Something happened, could not retrieve data");      $response = json_decode($res->getBody());      var_dump($response);     exit(); } 

The error I am receiving, screenshot of how it displays using Laravel's debugging view:

enter image description here

like image 855
Brad Avatar asked Jun 30 '16 21:06

Brad


2 Answers

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)         ]     ], ]); 
like image 152
revo Avatar answered Sep 27 '22 22:09

revo


$body = fopen('/path/to/file', 'r'); $r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]); 

http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=file

like image 29
Pawel Avatar answered Sep 27 '22 23:09

Pawel