3

I'm trying to upload a file to my server and then send that file to Zendesk. The Zendesk docs show how:

curl "https://{subdomain}.zendesk.com/api/v2/uploads.json?filename=myfile.dat&token={optional_token}" \
  -v -u {email_address}:{password} \
  -H "Content-Type: application/binary" \
  --data-binary @file.dat -X POST

This works fine. I now have to rewrite this with Guzzle (version 6). I'm using Symfony 2.7:

$file = $request->files->get('file');

$urlAttachments = $this->params['base_url']."/api/v2/uploads.json?filename=".$file->getClientOriginalName();

$body = [
        'auth' => [$this->params['user'], $this->params['pass']],
        'multipart' => [
        [
            'name'     => $archivo->getClientOriginalName(),
            'contents' => fopen($file->getRealPath(), "r"),
        ],
    ]
];

$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $urlAttachments, $body);
$response = json_decode($response->getBody(), true);

The file is getting uploaded, but when I download it, it also gets some some metadata in it's content (breaking some other file types). I guess I'm not uploading it correclty as the other way with curls works fine.

--5b8003c370f19
Content-Disposition: form-data; name="test.txt"; filename="php6wiix1"
Content-Length: 1040

... The rest of the original content of the test file...

--5b8003c370f19--

I don't know why this data is also sent as part of the file (which I don't want to), or if it is ok to use multipart for this.

Thanks for any help!

monstercode
  • 944
  • 6
  • 25

1 Answers1

9

It can be OK to use multipart, but the server has to handle it correctly. It is a different request-body whether you use it or not.

It is often used in HTML forms with (multiple) file uploads. Files are named (thus the meta infos), so there can be multiple files. There could also be normal form fields (text) along the files. You can probably find a better explanation of it by searching, just wanted to give a brief explanation.

And it seems in your case the server doesn't handle the multipart form data differently from a "binary post", so it saves it all, including the meta info.

Use body to pass a raw body and produce an identical request to your curl with Guzzle:

$urlAttachments = $this->params['base_url']."/api/v2/uploads.json?filename=".$file->getClientOriginalName();

$opts = [
    // auth
    'body' => fopen($file->getRealPath(), "r"),
    'headers' => ['Content-Type' => 'application/binary'],
];

$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $urlAttachments, $opts);
Tobias K.
  • 2,997
  • 2
  • 12
  • 29