curl-and-php
Set content-type for http post upload file not possible
Date: Wed, 12 Dec 2007 14:19:06 -0800
The question has been asked a few times previously, "How can I set the
Content-Type for files in a multipart/form-data post?", but there hasn't
been a definitive answer that I can find. I had the same question, but
now I have the answer.
The goal is to produce something like the following:
[...]
Content-Type: multipart/form-data;
boundary=----------------------------19566f682317
------------------------------19566f682317
Content -Disposition: form-data; name="uploadFile"; filename="filename.pdf"
Content-Type: application/pdf
[...]
The answer to the question, I'm sad to report, is it's not possible.
Curl always seems to send "Content-Type: application/octet-stream",
which for some servers doesn't work. My browser of choice, Firefox, will
send " Content-Type: application/pdf" for the pdf that I'm trying to
upload. The server I'm trying to send data to won't accept the
application/octet-stream type.
It can be accomplished with the curl command line, by adding the
following to the command:
-F "uploadFile=@filename.pdf;type=application/pdf"
The part after the semi-colon specifies the content type for that file.
See http://curl.haxx.se/docs/manual.html in the "POST (HTTP)" section.
However if I try the same syntax with PHP/cURL, I get the error, "failed
creating formpost data" using the following:
<?php
// Set parameters.
$url = "http://www.example.com/";
// Set up the post data.
$postData = array(
'uploadFile' => '@filename.pdf;type=application/pdf',
);
// Create the curl handle with the data to send.
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_URL, $url);
// Get the result.
$result = curl_exec($ch);
// Close the handle.
curl_close($ch);
?>
This happens because the cURL interface for PHP specifically checks for
the existence of the filename after the '@' character. Since it is not
only a file name, it fails. It should be able to parse out the "type="
directives instead of only using a filename.
Another option would be for cURL to automatically figure out the mime
type of the file based on the contents or file extension. It can, but
only for 5 file extensions:
{".gif", "image/gif"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".txt", "text/plain"},
{".html", "text/html"}
If the end of the filename matches one of the extensions, then it will
insert the associated mime type for the "Content-type:". If it isn't one
of the 5, then the mime type is "application/octet-stream". These 6
types are hard-coded into cURL. There is no way to change the set of
mime types without modifying the source code and recompiling it. :-( It
should read some kind of mime.magic file instead.
If either the PHP-curl interface or cURL code were changed to
accommodate this kind of upload, I could get my application to work.
They should both be changed and I hope one day they will be. Until that
time, I'm going to have to come up with some other way of posting to
this server.
I hope this information is able to help someone save themselves a few
hours of hair-pulling.
Morgan Galpin.
_______________________________________________
http://cool.haxx.se/cgi-bin/mailman/listinfo/curl-and-php
Received on 2007-12-12