I need your help with multipart/form-data and uploading image with curl.
I have this code for generating and sending data:
$boundary = '----WebKitFormBoundaryLZI2dppfUIcXxqT0';
$eol = "\r\n";
$postdata = '';
$postdata .= '--'.$boundary.$eol;
$postdata .= 'Content-Disposition: form-data; name="scrid"'.$eol.$eol;
$postdata .= $scrid.$eol;
$postdata .= '--'.$boundary.$eol;
$postdata .= 'Content-Disposition: form-data; name="file"; filename="'.$filepath.'"'.$eol;
$postdata .= "Content-Type: {$imginfo['mime']}".$eol.$eol;
$postdata .= $img.$eol;
$postdata .= '--'.$boundary.'--';
$headers = array(
"Content-Length: " . strlen($postdata),
"Content-Type: multipart/form-data;boundary=----WebKitFormBoundaryLZI2dppfUIcXxqT0",
"X-Requested-With: XMLHttpRequest",
"Origin:http://www.ebayclassifieds.com",
"Accept-Encoding: gzip, deflate",
"Accept:application/json, text/javascript, */*;",
);
curl_setopt($this->_ch, CURLOPT_URL, 'http://www.ebayclassifieds.com/m/ImageUpload');
curl_setopt($this->_ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($this->_ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($this->_ch, CURLOPT_POST, 1);
curl_setopt($this->_ch, CURLOPT_COOKIESESSION, TRUE);
curl_setopt($this->_ch, CURLOPT_COOKIEJAR, $this->_cookieFilePath);
curl_setopt($this->_ch, CURLOPT_COOKIEFILE, $this->_cookieFilePath);
curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->_ch, CURLOPT_REFERER, "http://www.ebayclassifieds.com/m/PostAd?scrid=$scrid");
$imageForm = curl_exec($this->_ch);
and i have request payload:
------WebKitFormBoundaryibLm7G5cqxCOuAFy
Content-Disposition: form-data; name="file"; filename="1-g-0-032- oz-silver-valcambi-bullion-bar-999-rev.jpg"
Content-Type: image/jpeg
Here appears the souce of the image itself like "ÿØÿàÿØÿàÿØÿàÿØÿàÿØÿàÿØÿà"
------WebKitFormBoundaryibLm7G5cqxCOuAFy
Content-Disposition: form-data; name="scrid"
32482346-7100587438898460646
------WebKitFormBoundaryibLm7G5cqxCOuAFy--
How can i get source of image?
I trying to get source: $imgSource = file_get_contents($filepath), but after send this text, server return error 417.
If send not valid parament for image, server return json request with error messages(this in normally)
Resolved.
Need send Expect: 0 in headers.
Related
How to send Accept Encoding header with with curl in PHP
$data=json_encode($data);
$url = 'url to send';
$headers = array(
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSLVERSION, 4);
$datas = curl_exec($ch);
curl_close($ch);
How to Decompress the response
You can use CURLOPT_ENCODING:
curl_setopt($ch, CURLOPT_ENCODING, "");
The contents of the "Accept-Encoding: " header. This enables decoding
of the response. Supported encodings are "identity", "deflate", and
"gzip". If an empty string, "", is set, a header containing all
supported encoding types is sent.
http://php.net/manual/en/function.curl-setopt.php
Alternatively, you can send an header:
$headers = array(
'Accept: text/plain'
);
To force the response in text/plain
If you mean how to ungzip the response I did it like this:
<?php
....
$headers = array(
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding: gzip, deflate",
"Accept-Charset: utf-8;q=0.7,*;q=0.3",
"Accept-Language:en-US;q=0.6,en;q=0.4",
"Connection: keep-alive",
);
....
$response = curl_exec($curl);
// check for curl errors
if ( strlen($response) && (curl_errno($curl)==CURLE_OK) && (curl_getinfo($curl, CURLINFO_HTTP_CODE)==200) ) {
// check for gzipped content
if ( (ord($response[0])==0x1f) && (ord($response[1])==0x8b) ) {
// skip header and ungzip the data
$response = gzinflate(substr($response,10));
}
}
// now $response has plain text (html / json / or something else)
I am trying to upload document via curl-put method. But when I call this file its just generate 0 byte file not uploading file.
I am consuming third party's web service.
What is missing here ?Is there something in header ?
In file-name do we need to pass file-name or path ?
PHP Code
$data = json_encode($this->data);
$file_url = $filepath;
$f = array($filepath);
$eol = "\r\n";
$BOUNDARY = md5(time());
$BODY=""; //init my curl body
$BODY.= '--'.$BOUNDARY. $eol; //start param header
$BODY .= 'Content-Disposition: form-data; name="Appointment"' . $eol . $eol; // last Content with 2 $eol, in this case is only 1 content.
$BODY.= '--'.$BOUNDARY. $eol; // start 2nd param,
$BODY.= 'Content-Disposition: form-data; filename='.$filepath. $eol ; //first Content data for post file, remember you only put 1 when you are going to add more Contents, and 2 on the last, to close the Content Instance
$BODY.= 'Content-Type: application/pdf' . $eol; //Same before row
$BODY.= chunk_split(base64_encode(file_get_contents($file_url))) . $eol; // we write the Base64 File Content and the $eol to finish the data,
$BODY.= '--'.$BOUNDARY .'--' . $eol. $eol; // we close the param and the post width "--" and 2 $eol at the end of our boundary header.
$header[] = 'Authorization: WRAP access_token="'.$this->accesstoken.'"';
$header[] = 'Content-Type: multipart/form-data; boundary='.$BOUNDARY;
print_r($BODY);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$this->baseAddress);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); // tell curl you want to post something
curl_setopt($ch, CURLOPT_POSTFIELDS, $BODY); // define what you want to post
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_ENCODING, '');
curl_setopt($ch, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1);
$output = curl_exec ($ch); // execute
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($output, 0, $header_size);
$this->response = substr($output, $header_size);
$info = curl_getinfo($ch);
$this->responsecode = $info['http_code'];
curl_close ($ch); // close curl
I also tried to send file by creating object. In this case it gives below error.
$cfile = new CURLFile(realpath('testcp.txt'),'text/plain');
$uploadPost = array (
'file' => $cfile
);
$eol = "\r\n";
$BOUNDARY = md5(time());
$BODY=""; //init my curl body
$BODY.= '--'.$BOUNDARY. $eol; //start param header
$BODY.= '--'.$BOUNDARY. $eol; // start 2nd param,
$BODY.= '--'.$BOUNDARY .'--' . $eol. $eol; // we close the param and the post width "--" and 2 $eol at the end of our boundary header.
$header[] = 'Authorization: WRAP access_token="'.$this->accesstoken.'"';
$header[] = 'Content-Type: multipart/form-data; boundary='.$BOUNDARY;
print_r($BODY);
//ECHO $this->accesstoken;EXIT;
$ch = curl_init();
//echo $this->baseAddress;exit;
curl_setopt($ch, CURLOPT_URL,$this->baseAddress);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); // tell curl you want to post something
// curl_setopt($ch, CURLOPT_POSTFIELDS, ($data)); // define what you want to post
curl_setopt($ch, CURLOPT_POSTFIELDS, $uploadPost); // define what you want to post
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_ENCODING, '');
curl_setopt($ch, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1);
$output = curl_exec ($ch); // execute
echo 'OUTPUT ---';print_r($output);exit;
curl_close ($ch);
Error :
Unexpected end of MIME multipart stream. MIME multipart message is not
complete.
Try this:
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array("body" => $BODY)));
Or at least URL-encode $BODY;
This headers sends by my programs to a adress:
--55ae49448a20c
Content-Disposition: form-data; name="chat_id"
Content-Length: 9
108432389
--55ae49448a20c
Content-Disposition: form-data; name="photo"; filename="Untitled.png"
Content-Length: 16252
Content-Type: image/png
PNG
I want to POST 2 varibles (chat_id) and (photo) by the following code.
Attempted Code:
<?php
$params = "Content-Disposition: form-data; name=\"chat_id\"\r\n"
. "Content-Length: 9\r\n\r\n"
. "\r\n"
. "Content-Disposition: form-data; name=\"photo\"; filename=\"Untitled.png\"\r\n"
. "Content-Length: ".filesize("Untitled.png")."\r\n"
. "Content-Type: image/png\r\n\r\n"
. file_get_contents("Untitled.png");
$request_headers = array();
$request_headers[] = 'Content-Length: ' . strlen($params);
$url = 'http://example.com';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_PROXY, '127.0.0.1:8888');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
$reply = curl_exec($ch);
?>
Is there any other way for do that !?
My attempted code gives me 400 Bad Gatway error..
That's TOTALLY unnecessary. You're doing way too much that CURL can do far better (and properly) itself.
$post = array(
'chat_id' => 108432389,
'photo' => '#Untitled.jpg'
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
old-school php curl used # in the value field to signify a file to be uploaded. Newer versions use curlfile instead.
I've reviewed the old questions posted here on Stackoverflow about this issue.
But I didn't find any example for php integration.
Here is a sample of my code to do that but it's failing
$url = 'https://connect.squareup.com/v1/me/items/9999999/image';
$auth_bearer = 'Authorization: Bearer ' . $this->accessToken;
$image_data = base64_encode(file_get_contents('image.jpeg'));
$header = array(
$auth_bearer,
'Accept: application/json',
'Content-Type: multipart/form-data; boundary=BOUNDARY',
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'files=' . $image_data);
$head = curl_exec($ch);
curl_close($ch);
$response = json_decode($head);
echo "<pre>";
print_r($response);
echo "</pre>";
And nothing happens... any help here?
Thanks
You need to post the raw image data (not base64 encoded) with the proper multipart header for a file object. Here's a working example (replace ACCESS_TOKEN, ITEM_ID, and IMAGE_FILE).
<?php
function uploadItemImage($url, $access_token, $image_file) {
$headers = ["Authorization: Bearer $access_token"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['image_data' => "#$image_file"]);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
$return_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
print "POST to $url with status $return_status\n";
curl_close($ch);
return $data ? json_decode($data) : false;
}
print_r(
uploadItemImage(
'https://connect.squareup.com/v1/me/items/ITEM_ID/image',
'ACCESS_TOKEN',
'IMAGE_FILE.jpg'
)
);
?>
Here is my PHP implementation for uploading a PNG image. Sometimes a different code view helps.
As #Troy stated, the important field to include for images is 'Content-Type: multipart/form-data'. Everything else I upload to Square uses 'Content-Type: application/json'.
$square_url = 'https://connect.squareup.com/v1/me/items/' . $square_item_id . '/image';
$cfile = new CURLFile($image_path_on_server, 'image/png', 'image_data');
$image_data = array('image_data' => $cfile);
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer ' . $access_token,
'Content-Type: multipart/form-data',
'Accept: application/json'
));
curl_setopt($curl, CURLOPT_POSTFIELDS, $image_data);
curl_setopt($curl, CURLOPT_URL, $square_url);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, TRUE);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
$json = curl_exec($curl);
curl_close($curl);
Strictly speaking Square API documentation, their method can be implemented keeping a few things in mind.
-- Your request must be enclosed in a boundary and contain the Content disposition, name, filename, content type like the sample below.
--BOUNDARY
Content-Disposition: form-data; name="image_data"; filename="MyImage.png"
Content-Type: image/png
{BLANK LINE IS REQUIRED}
IMAGE BINARY DATA GOES HERE
--BOUNDARY--
In essence, the format of the request must be exactly as specified in the sample. This includes the 'boundary', the newline characters, the necessary headers, a blank line between the headers (for some reason nothing works if the line isn't present), and the actual image binary data. NOTE: the boundary can be any string that you choose, but it must be used consistently. In code, this would look something like this:
$boundary = "---------------------" . md5(mt_rand() . microtime());
$imageToUpload = "--{$boundary}" . "\r\n" .
"Content-Disposition: form-data; name=\"image_data\"; filename=\"" . $full_path_to_image_file . "\"" . "\r\n" .
"Content-Type: image/jpeg" . "\r\n" .
"\r\n" . // <- empty line is required
(file_get_contents($full_path_to_image_file)) . "\r\n" .
"--{$boundary}--";
The above will produce a request that looks like this:
-----------------------51b62743876b1201aee47ff4b1910e49
Content-Disposition: form-data; name="image_data"; filename="/some/directory/image.jpg"
Content-Type: image/jpeg
����
-----------------------51b62743876b1201aee47ff4b1910e49--
-- Technically speaking, the Content-Type in the request must change with the type of image you're uploading (image/jpeg or image/png). You can set the content type to application/octet-stream to cover all basis.
-----------------------51b62743876b1201aee47ff4b1910e49
Content-Disposition: form-data; name="image_data"; filename="/some/directory/image.jpg"
Content-Type: application/octet-stream
����
-----------------------51b62743876b1201aee47ff4b1910e49--
The two examples above will upload an image.
-- 'Image binary data' can be misleading as my every search showed that an image binary is obtained by using the base64_encode function. In my experiments, the base64_encoding doesn't do anything. You only need to open the file with the file_get_contents.
-- In your cURL request, must have the header's Content-Type set to multipart/form-data and have the same boundary as the request. Example below:
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $personalAccessToken, 'Content-Type: multipart/form-data; boundary=' . $boundary ));
So this adds another solution to the mix.
Troy's solution using # is deprecated and I was unable to get it to work. Byron's solution works with the CURLOPT_POST before the CURLOPT_POSTFIELDS (see Mavooks comment at https://www.php.net/manual/en/function.curl-setopt.php) and removing the Content-Type from the header. That is because it is automatically multipart if CURLOPTS_POSTFIELDS is an array and manually including it seems to override it, but then it is missing the boundary.
$square_url = 'https://connect.squareup.com/v1/me/items/' . $square_item_id . '/image';
$cfile = new CURLFile($image_path_on_server, 'image/png', 'image_data');
$image_data = array('image_data' => $cfile);
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer ' . $access_token,
'Accept: application/json'
));
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $image_data);
curl_setopt($curl, CURLOPT_URL, $square_url);
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, TRUE);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
$json = curl_exec($curl);
curl_close($curl);
salam
i want to get some xml responses from a server
but this server accept only xml request
i have this example of code
<?php
$url = "http://www.pj.ma/phonexmlfeeds";
$post_string = '<?xml version="1.0 encoding="UTF-8" ?><search_requests> <search_request id="req1"><content>statut=1 AND linguistic_expansion2(lingex_qui_quoi,1,0,"qui_quoi","Restaurant",LIN_EXACT|LIN_LEM0|LIN_LEM1|LIN_LEM2|LIN_SYN1|LIN_SYN2|LIN_PHO1|LIN_ORT)</content><code>sortBy(casanet_perfect(lingex_qui_quoi));filterBy(casanet_perfect_filter(lingex_qui_quoi));setSortAttribute(indice,sortDirection,sortDirectionDesc);sortBy(indice,score2(lingex_qui_quoi,lingex_ou,matrice), ordered(lingex_qui_quoi),ordered(lingex_ou),rs);catalogBy(libniv3);sendxref(rs);sendxref(crs);sendxref(nomcomm);sendxref(activite);sendxref(libniv3);sendxref(villep);sendxref(adrp);sendxref(nomvoie);sendxref(numtel_typetel);sendxref(internet);sendxref(pub);sendxref(marque);sendXrefHighlights();</code><options><option name="maxFiles">10</option><option name="startFiles">11</option><option name="highlight_zone_start">{match}</option><option name="highlight_zone_end">{/match}</option></options><metadata><meta name="base">Pages Jaunes</meta></metadata></search_request></search_requests>';
$header = "POST /phonexmlfeeds HTTP/1.1";
$header = "Connection: close";
$header .= "Content-Type: text/xml";
$header .= "User-Agent: Dalvik/1.4.0 (Linux; U; Android 2.3.3; GT-S5830 Build/GINGERBREAD)";
$header .= "Host: www.pj.ma";
$header .= "Content-Length: 1053";
$header .= "Accept-Encoding: gzip";
$header .= $post_string;
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 4);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $header);
$data = curl_exec($ch);
if(curl_errno($ch))
print curl_error($ch);
else
curl_close($ch);
echo $data;
?>
but it give this response
Your browser sent a request that this server could not understand.
here i post a example of request captured by wifisnifer
POST /phonexmlfeeds HTTP/1.1 Connection: close Content-Type: text/xml
User-Agent: Dalvik/1.4.0 (Linux; U; Android 2.3.3; GT-S5830
Build/GINGERBREAD) Host: www.pj.ma Content-Length: 1052
Accept-Encoding: gzip
<?xml version="1.0 encoding="UTF-8" ?><search_requests> <search_request id="req1"><content>statut=1 AND linguistic_expansion2(lingex_qui_quoi,1,0,"qui_quoi","Restaurant",LIN_EXACT|LIN_LEM0|LIN_LEM1|LIN_LEM2|LIN_SYN1|LIN_SYN2|LIN_PHO1|LIN_ORT)</content><code>sortBy(casanet_perfect(lingex_qui_quoi));filterBy(casanet_perfect_filter(lingex_qui_quoi));setSortAttribute(indice,sortDirection,sortDirectionDesc);sortBy(indice,score2(lingex_qui_quoi,lingex_ou,matrice), ordered(lingex_qui_quoi),ordered(lingex_ou),rs);catalogBy(libniv3);sendxref(rs);sendxref(crs);sendxref(nomcomm);sendxref(activite);sendxref(libniv3);sendxref(villep);sendxref(adrp);sendxref(nomvoie);sendxref(numtel_typetel);sendxref(internet);sendxref(pub);sendxref(marque);sendXrefHighlights();</code><options><option name="maxFiles">10</option><option name="startFiles">1</option><option name="highlight_zone_start">{match}</option><option name="highlight_zone_end">{/match}</option></options><metadata><meta name="base">Pages Jaunes</meta></metadata></search_request></search_requests>
For custom headers add line breaks (\r\n).
Or consider using http://us3.php.net/curl_setopt for headers, eg:
curl_setopt($ch, CURLOPT_HTTPHEADERS, array(
'POST /phonexmlfeeds HTTP/1.1',
'Connection: close',
'Content-Type: text/xml',
etc...
));
Edit this line --
$header .= "Connection: close";
as you have--
$header = "Connection: close";