how to upload a file to java server(MultipartEntity) using curl php - php

I'm developing a web portal which is consuming the REST API from java. By using curl I'm able to send post request and receive response easily but I'm not able to send file using CURL, it shows the error "HTTP Status 500 - Could find no Content-Disposition header within part":
Here is my code:
$filename = $_FILES['uploadedfile']['tmp_name'];
$handle = fopen($filename, "r");
$data = '#'.fread($handle, filesize($filename));
$dat = base64_encode($data);
$POST_DATA = array(
'imageName' => $dat,
"Id" => "690",
);
$boundary = '--myboundary-xxx';
var_dump($POST_DATA);
$params = json_encode($POST_DATA);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://localhost.com/Project/REST/webservice/saveImage');
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type:multipart/form-data; boundary=$boundary; ',
'Content-Disposition: attachment; filename:"$filename";',
'Content-Length: ' . strlen($params)
));
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($curl);
var_dump(curl_getinfo($curl));
curl_close ($curl);
var_dump($response);
echo $response;
}

Did you try
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type:multipart/form-data; boundary='.$boundary.'; ',
'Content-Disposition: attachment; filename='.$filename.';',
'Content-Length: ' . strlen($params)
));

Related

DROPBOX API Not uploading more than 150MB File

Hi Please first read full question then answer.
I am trying to upload the files using Dropbox API But now I came to know that I cannot upload more than 150MB file with that method.
Here are my Codes.
<?php
define ('SITE_ROOT', realpath(dirname(__FILE__)));
$filename = SITE_ROOT.'BRINDABELLA.zip';
$MainPath = '/2020 events/';
$api_url = 'https://content.dropboxapi.com/2/files/upload';
$token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$headers = array('Authorization: Bearer '. $token,
'Content-Type: application/octet-stream',
'Dropbox-API-Arg: '.
json_encode(
array(
"path"=> $MainPath.basename($filename),
"mode" => "add",
"autorename" => true,
"mute" => false
)
)
);
$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
$path = $filename;
$fp = fopen($path, 'rb');
$filesize = filesize($path);
curl_setopt($ch, CURLOPT_POSTFIELDS, fread($fp, $filesize));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, 1); // debug
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo($response.'<br/>');
echo($http_code.'<br/>');
curl_close($ch);
?>
I Know I can upload more than 150MB files using upload session method.
Reference Link https://www.dropbox.com/developers/documentation/http/documentation#files-upload_session-start
Now I just want to alter my these codes only. Please help me how I can do it. I dont want to use any external API. Just the way I used CURL

How to publish media (image) on Mastodon using API?

I'm trying to POST an image on Mastodon (specifically on Humblr) but I cannot get the media_id, the response is null, but I'm not sure where the problem is.
I can publish text, no problem, so the authentication part is fine, I only have the problem with the image, the only difference I can see in the documentation is that "Media file encoded using multipart/form-data".
Here's my code so far...
$headers = ['Authorization: Bearer '.$settings['access_token'] , 'Content-Type: multipart/form-data'];
$mime_type = mime_content_type($urlImage);
$cf = curl_file_create($urlImage,$mime_type,'file');
$media_data = array( "file" => $cf);
$ch_status = curl_init();
curl_setopt($ch_status, CURLOPT_URL, "https://humblr.social/api/v1/media");
curl_setopt($ch_status, CURLOPT_POST, 1);
curl_setopt($ch_status, CURLOPT_POSTFIELDS, $media_data);
curl_setopt($ch_status, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch_status, CURLOPT_HTTPHEADER, $headers);
$media_status = json_decode(curl_exec($ch_status));
echo "Response: ".json_encode($media_status);
From this I want to extract the $media_status-> media_id
I don't really know much about 'multipart/form-data' to be honest.
Am I missing something?
This took some trial and error for me as well. Here's what worked for me (PHP 7.3):
$curl_file = curl_file_create('/path/to/file.jpg','image/jpg','file.jpg');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://instanceurl.com/api/v1/media');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer YOUR_TOKEN_HERE',
'Content-Type: multipart/form-data'
]);
$body = [
'file' => $curl_file
];
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
$response = curl_exec($ch);
if (!$response) {
die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}
echo 'HTTP Status Code: ' . curl_getinfo($ch, CURLINFO_HTTP_CODE) . PHP_EOL;
echo 'Response Body: ' . $response . PHP_EOL;
curl_close($ch);

Is there any PHP.ini setting for curl status code 415?

I have tried to call API for send image file using CURL .But I am getting below error:
"statusCode":415,
"error":"Unsupported Media Type"
Please help me.
I have attached code here:
$filename = "screenshot.jpg";
$handle = fopen($filename, "r");
$xml = fread($handle, filesize($filename));
fclose($handle);
$jwt_token = "xxx";
$authorization = "Authorization:".$jwt_token;
$url = "https://prod0-commerce-api.sprinklr.com/media_upload";
$headers = array(
"Content-Type: image/jpg]",
"Cache-Control: no-cache",
"Pragma: no-cache",
$authorization
);
$postdata = array('fileName' => '#'.$filename,
'type' => 'IMAGE'); //<-------------
$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, $url);
//curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 60);
//curl_setopt($soap_do, CURLOPT_TIMEOUT, 60);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true );
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($soap_do, CURLOPT_POST, true );
curl_setopt($soap_do, CURLOPT_POSTFIELDS, $postdata); //<-----------
curl_setopt($soap_do, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($soap_do);
// Check for errors and display the error message
curl_close($soap_do);
$httpcode = curl_getinfo($soap_do, CURLINFO_HTTP_CODE);
echo $httpcode;
echo "<pre>";
var_dump($result);
if($errno = curl_errno($soap_do)) {
$error_message = curl_strerror($errno);
echo "cURL error ({$errno}):\n {$error_message}";
}
echo "string";exit();
print_r($result);
The problem is in this block:
$postdata = array('fileName' => '#'.$filename,
'type' => 'IMAGE'); //<-------------
The value of type should be a valid MIME type (aka "media type" or "content type").
A MIME type is an identifier composed of two parts (the type and the subtype) joined by slash (/).
The type identifies the category of content (text, image, audio, video, application etc). The subtype identifies more accurate the content inside the category.
For images, the type is image and there are several subtypes: gif, jpeg, png etc.
A correct MIME type for an image file looks like image/jpeg or image/png and not just IMAGE. This is why the server rejects your query.
The PHP function getimagesize() can be used to find the MIME type of a image stored in a file.
Your code should be like this:
$imgInfo = getimagesize($filename);
$postdata = array('fileName' => '#'.$filename,
'type' => $imgInfo['mime']);
And no, there is no setting in php.ini that writes correct code for you.
I have solved using this solution
<?php
$file = "http://localhost/xxx/screenshot.jpg";
$boundary = md5(time());
$eol = "\r\n";
$params = "----".$boundary.$eol
. "Content-Disposition: form-data;name=\"type\"".$eol
. $eol
. "IMAGE"
. $eol
. "----".$boundary.$eol
. "Content-Disposition: form-data;name=\"file\"; filename=\"screenshot.jpg\"".$eol
. '"Content-Type: image/jpeg\"'.$eol
. $eol
. file_get_contents($file) .$eol
. "----".$boundary."--";
$jwt_token = "xxxx";
$authorization = "Authorization:".$jwt_token;
$first_newline = strpos($params, $eol);
$multipart_boundary = substr($params, 2, $first_newline - 2);
$request_headers = array();
$request_headers[] = $authorization;
$request_headers[] = 'Accept: application/json';
$request_headers[] = 'Content-Length: ' . strlen($params);
$request_headers[] = 'Content-Type: multipart/form-data; boundary='. $multipart_boundary;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'xxx');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
echo "<pre>";
print_r($result);
exit();
Most of time a error 415 appears when you don't set properly the Content-Type. Maybe you can put Content-Type:
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: image/jpg"));

PHP cURL: how to set body to binary data?

I'm using an API that wants me to send a POST with the binary data from a file as the body of the request. How can I accomplish this using PHP cURL?
The command line equivalent of what I'm trying to achieve is:
curl --request POST --data-binary "#myimage.jpg" https://myapiurl
You can just set your body in CURLOPT_POSTFIELDS.
Example:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://url/url/url" );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, "body goes here" );
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/plain'));
$result=curl_exec ($ch);
Taken from here
Of course, set your own header type, and just do file_get_contents('/path/to/file') for body.
This can be done through CURLFile instance:
$uploadFilePath = __DIR__ . '/resource/file.txt';
if (!file_exists($uploadFilePath)) {
throw new Exception('File not found: ' . $uploadFilePath);
}
$uploadFileMimeType = mime_content_type($uploadFilePath);
$uploadFilePostKey = 'file';
$uploadFile = new CURLFile(
$uploadFilePath,
$uploadFileMimeType,
$uploadFilePostKey
);
$curlHandler = curl_init();
curl_setopt_array($curlHandler, [
CURLOPT_URL => 'https://postman-echo.com/post',
CURLOPT_RETURNTRANSFER => true,
/**
* Specify POST method
*/
CURLOPT_POST => true,
/**
* Specify array of form fields
*/
CURLOPT_POSTFIELDS => [
$uploadFilePostKey => $uploadFile,
],
]);
$response = curl_exec($curlHandler);
curl_close($curlHandler);
echo($response);
See - https://github.com/andriichuk/php-curl-cookbook#upload-file
to set body to binary data and upload without multipart/form-data, the key is to cheat curl, first we tell him to PUT, then to POST:
<?php
$file_local_full = '/tmp/foobar.png';
$content_type = mime_content_type($file_local_full);
$headers = array(
"Content-Type: $content_type", // or whatever you want
);
$filesize = filesize($file_local_full);
$stream = fopen($file_local_full, 'r');
$curl_opts = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_PUT => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => $headers,
CURLOPT_INFILE => $stream,
CURLOPT_INFILESIZE => $filesize,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1
);
$curl = curl_init();
curl_setopt_array($curl, $curl_opts);
$response = curl_exec($curl);
fclose($stream);
if (curl_errno($curl)) {
$error_msg = curl_error($curl);
throw new \Exception($error_msg);
}
curl_close($curl);
credits: How to POST a large amount of data within PHP curl without memory overhead?
Try this:
$postfields = array(
'upload_file' => '#'.$tmpFile
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url.'/instances');
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);//require php 5.6^
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$postResult = curl_exec($ch);
if (curl_errno($ch)) {
print curl_error($ch);
}
curl_close($ch);
Below solution worked fine for me.
$ch = curl_init();
$post_url = "https://api_url/"
curl_setopt($ch, CURLOPT_URL, $post_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
$post = array(
'file' => '#' .realpath('PATH_TO_DOWNLOADED_ZIP_FILE')
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$headers = array();
$headers[] = 'Authorization: Bearer YOUR_ACCESS_TOKEN';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
refered: curl to php-curl
You need to provide appropriate header to send a POST with the binary data.
$header = array('Content-Type: multipart/form-data');
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($resource, CURLOPT_POSTFIELDS, $arr_containing_file);
Your $arr_containing_file can for example contain file as expected (I mean, you need to provide appropriate expected field by the API service).
$arr_containing_file = array('datafile' => '#inputfile.ext');

Using PHP to upload an activity to Strava using API v3

I'm working on an application in which I'd like to be able to upload activities (GPX files) to Strava using it's API v3.
My application successfully handles the OAuth process - I'm able to request activities, etc, successfully.
However, when I try to upload an activity - it fails.
Here's the relevant sample of my code:
// $filename is the name of the GPX file
// $actual_file contains the full path
$actual_file = realpath($filename);
$url="https://www.strava.com/api/v3/uploads";
$postdata = "activity_type=ride&file=". "#" . $actual_file . ";filename=" . $filename . "&data_type=gpx";
$headers = array('Authorization: Bearer ' . $strava_access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_POST, 3);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec ($ch);
Here's what I get in response:
{"message":"Bad Request", "errors":[{"resource":"Upload", "field":"file","code":"not a file"}]}
I then tried this:
// $filename is the name of the GPX file
// $actual_file contains the full path
$actual_file = realpath($filename);
$url="https://www.strava.com/api/v3/uploads";
$postfields = array(
"activity_type" => "ride",
"data_type" => "gpx",
"file" => "#" . $filename
);
$postdata = http_build_query($postfields);
$headers = array('Authorization: Bearer ' . $strava_access_token, "Content-Type: application/octet-stream");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_POST, count($postfields));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$fp = fopen($filename, 'r');
curl_setopt($ch, CURLOPT_INFILE, $fp);
$json = curl_exec ($ch);
$error = curl_error ($ch);
Here's what I get in response:
{"message":"Bad Request", "errors":[{"resource":"Upload", "field":"data","code":"empty"}]}
Clearly, I'm doing something wrong when trying to pass the GPX file.
Is it possible to provide a bit of sample PHP code to show how this should work?
For what it's worth - I'm fairly certain the GPX file is valid (it's actually a file I downloaded using Strava's export feature).
I hope that answering my own question less than one day after posting it isn't bad form. But I've got it working, so I may as well, just in case anyone else finds it useful...
// $filename is the name of the file
// $actual_file includes the filename and the full path to the file
// $strava_access_token contains the access token
$actual_file = realpath($filename);
$url="https://www.strava.com/api/v3/uploads";
$postfields = array(
"activity_type" => "ride",
"data_type" => "gpx",
"file" => '#' . $actual_file . ";type=application/xml"
);
$headers = array('Authorization: Bearer ' . $strava_access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec ($ch);
Apparently, it's important not to include the CURLOPT_POST option.
Here is also a working Python example
import os
import requests
headers = {
'accept': 'application/json',
'authorization': 'Bearer <Token>',
}
dir = os.getcwd() + '/files/'
for filename in os.listdir(dir):
file = open(dir + filename, 'rb')
files = {
"file": (filename, file, 'application/gpx+xml'),
"data_type": (None, 'gpx'),
}
try:
response = requests.post('http://www.strava.com/api/v3/uploads',files=files, headers=headers)
print(filename)
print(response.text)
print(response.headers)
except requests.exceptions.RequestException as e: # This is the correct syntax
print(e)
sys.exit(1)

Categories