I use a PUT request with curl php in one of my scripts to upload a file to an external file repository using a REST API. However, the uploaded files contain information about the Content-Disposition, the Content-Type and some alpha-numeric code at both the beginning and the end of the file, rendering the useless unless manually enditing again.
The unnecessary overhead looks like this:
--------------------------e876c4b8eee91562 Content-Disposition: form-data; name="test_file"; filename="test_3.xlsx" Content-Type: application/octet-stream
The code I use to do the request is:
$ch = curl_init($upload_url);
$cfile = new CURLFile($file_realpath, 'application/octet-stream', $base_file_name);
$data = array ('test_file' => $cfile);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept:application/json',
'Content-Type:application/octet-stream',
));
b2share_ignore_certificates($ch);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$headerSent = curl_getinfo($ch, CURLINFO_HEADER_OUT);
curl_close($ch);
I can't change the request to POST, as the REST API on the other side needs a PUT request. Any ideas on how to get rid of the overhead?
OK. I found the answer to the question here: PHP Curl post a file without header
Thus changing the line
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
to
curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents($file_realpath));
fixes the issue. This is probably not a very "clean" solution, but it works. I'd be glad to hear about better solutions though.
Just as a note (I don't have enough points yet to make comments).
I think @stopopol answer is actually the right one. I am no PHP expert but it seems to me that you were indeed sending a key/value form-data. B2SHARE API expects a binary content and saves exactly what you send to it as a file. The Headers are ok. The 'Accept:application/json' DOES NOT specify the content-type of the file you are sending but the type you are expecting in return, i.e. the answer from the server.
Note also that there is an error in the curl command given in the B2SHARE documentation. It will be fixed soon. The file upload should use --data-binary
:
curl -X PUT -H 'Accept:application/json' -H 'Content-Type:application/octet-stream' --data-binary @TestFileToBeUploaded.txt https://$HOSTNAME/api/files/$FILE_BUCKET_ID/TestFileToBeUploaded.txt?access_token=$ACCESS_TOKEN