Zend_Http_Client - Why does my POST request send the wrong content-type header?

3.3k views Asked by At

I'm making a call to an external service using the Zend Http client. The service allows me to upload files to their storage system. It requires relevant params (userid, etc.) to be sent in the query string, and the file upload content should be sent in the POST body with a content-type of "application/zip" (I'm sending it a zip file with various things in it).

To do this, I set the params in the query string using the zend client's setParameterGet() function. I then set the file upload content using the setFileUpload() function:

$this->client->setFileUpload($zipFilePath, 'content', null, 'application/zip');

However, the service is telling me that I'm sending it the wrong content type, which is "multipart/form-data"

Here are the raw headers that the Zend client is sending to the service (note that I've removed bits of sensitive information, replacing them with item names enclosed in [] brackets)

POST https://[ServiceURL]?cmd=[COMMAND]&enrollmentid=[ENROLLMENTID]&itemid=[ITEMID]

HTTP/1.1

Host: [HOST] Accept-encoding: gzip, deflate

User-Agent: Zend_Http_Client Cookie:

AZT=9cMFAIBgG-eM1K|Bw7Qxlw7pBuPJwm0PCHryD;

Content-Type: multipart/form-data; boundary=---ZENDHTTPCLIENT-05535ba63b5130ab41d9c75859f678d8

Content-Length: 2967

-----ZENDHTTPCLIENT-05535ba63b5130ab41d9c75859f678d8

Content-Disposition: form-data; name="content"; filename="agilixContent.zip"

Content-Type: application/zip

[RAW FILE DATA HERE]

So basically, even though I've set the POST content type header, my external service is telling me I've sent the wrong content type, because there is another content-type header with the value "multipart/form-data". I've tried changing/removing that content header, but to no avail. How can I remove that header so that I won't have these two duplicate "content-type" headers in my requests?

2

There are 2 answers

1
shevron On BEST ANSWER

If you want to upload a file using "application/zip" as content type you should not use ->setFileUpload() but rather ->setRawData(). setFileUpload() is used to mimick HTML form based file uploads which is not what you need.

See http://framework.zend.com/manual/en/zend.http.client.advanced.html#zend.http.client.raw_post_data for more information. What you need (based on your original example) will be something like:

$zipFileData = file_get_contents($zipFilePath);
$this->client->setRawData($zipFileData, 'application/zip');
$response = $this->client->request('POST');

Note that if your ZIP file may be very big (say more than a few megabytes) you may want to use ZHC's streaming support features, so avoid memory hogging. If you know your files are always less than 5-10 megabytes, I wouldn't bother with it though.

1
deej On

I am not sure how you can do that with Zend HTTP Client but I am sure you could do that with plain cURL. As you must be knowing cURL gives you lot of flexibility and I have not dig in to Zend but there are chances that Zend might be using cURL internally.

<?php

// URL on which we have to post data
$url = "http://localhost/tutorials/post.php";
// Any other field you might want to catch
$post_data = "khan";
// File you want to upload/post
//$post_data['zip_file'] = "@c:/foobar.zip";

$headers[] = "Content-Type: application/zip";

// Initialize cURL
$ch = curl_init();
// Set URL on which you want to post the Form and/or data
curl_setopt($ch, CURLOPT_URL, $url);
// Data+Files to be posted
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// Set any custom header you may want to set or override defaults
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
// Pass TRUE or 1 if you want to wait for and catch the response against the request made
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// For Debug mode; shows up any error encountered during the operation
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Execute the request
$response = curl_exec($ch);

// Just for debug: to see response
echo $response;

I hope above snippet will work for you. That's bit modified code from my blog post mentioned below.

Reference: http://blogs.digitss.com/php/curl-php/posting-or-uploading-files-using-curl-with-php/