get remote file size (without using Content-Length field) - php

I need to get size of remote file without download. I use this code, but headers from some sites doesn't contain Content-Length: field. How can I get filesize in that cases?
$ch = curl_init("http://wordpress.org/latest.zip");
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$data = curl_exec($ch);
curl_close($ch);
$contentLength = 'unknown';
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
$contentLength = (int)$matches[1];
}
echo $contentLength;
this is result of echo $data;
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 10 Apr 2012 11:32:20 GMT
Content-Type: application/zip
Connection: close
Pragma: no-cache
Cache-control: private
Content-Description: File Transfer
Content-Disposition: attachment; filename=wordpress-3.3.1.zip
Content-MD5: d6332c76ec09fdc13db412ca0b024df9
X-nc: EXPIRED luv 139

If Content-Length header is not present, that means that file size is unknown. In your case you have Content-Disposition header, wich means that downloadable file is an attachment to server response (same as email attachment). So here if you have no Content-Length header you can't get the size.

Related

PHP Curl - eBay CSV FileExchange

I've tried to send a CSV File to eBay FileExchange Service.
I'm writing an application to update a lot of products on eBay at the same time.
When I upload the test.csv by using the eBay CSV-Manager the update will be success, but with the script nothing will happens after post the data.
I've treid the following steps:
Create a separate token for FileExchange.
https://signin.ebay.de/ws/eBayISAPI.dll?SignIn&runame=F-FILEEXL51P1EHH6L899Q9B969GE134DK-FileUpload
Then I use the following script:
$token = 'AgAAAA**AQAAAA**aAAAAA************';
$ebay_url = 'https://bulksell.ebay.com/ws/eBayISAPI.dll?FileExchangeUpload';
$sendheaders = array(
'User-Agent: My Client App v1.0'
);
$fields = array(
'token' => $token,
'file' => '#test.csv'
);
$ch = curl_init($ebay_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 1); // set to 0 to eliminate header info from response
curl_setopt($ch, CURLOPT_NOBODY, 0); // set to 1 to eliminate body info from response
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); // use HTTP/1.0 instead of 1.1
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response. ###
curl_setopt($ch, CURLOPT_HTTPHEADER, $sendheaders);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); // use HTTP POST to send form data
$resp = curl_exec($ch); //execute post and get results
if(!curl_exec($ch)) {
die('Error: ' . curl_error($ch) . ' - Code: ' . curl_errno($ch));
}
curl_close ($ch);
I've used this csv File-format (test.csv)
Action;ItemID;DispatchTimeMax
Revise;28*********916;30
The results after post:
print_r($resp);
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: dp1=bu1p/QEBfX0BAX19AQA**617d3da3^bl/DE617d3da3^; Domain=.ebay.com; Expires=Sat, 30-Oct-2021 12:42:11 GMT; Path=/
Set-Cookie: s=CgAD4ACBdvCgjMjFkNjZkMDcxNmUwYTBmMTc1MTA0ZmEwZmZmYjEyZWFY39RE; Domain=.ebay.com; Path=/
Set-Cookie: nonsession=CgADKACBhfT2jMjFkNjZkMDcxNmUwYTBmMTc1MTA0ZmEwZmZmYjEyZWIAywABXbrdqzHTwXKU; Domain=.ebay.com; Expires=Sat, 30-Oct-2021 12:42:11 GMT; Path=/
Cache-Control: private
Pragma: no-cache
Content-Type: text/html;charset=UTF-8
Content-Length: 731
Date: Thu, 31 Oct 2019 12:42:11 GMT
Connection: keep-alive
File upload successful. Your ref # is .
Close
Thanks for helping me.
I have found a solution:
Obviously at php 7.1 the # has no effect, and the file post ist empty to ebay.
I use the curl_file_create function and it's work.
if (!function_exists('curl_file_create'))
{
function curl_file_create($filename, $mimetype = '')
{
return "#$filename;filename="
. ($mimetype ? ";type=$mimetype" : '');
}
}
$fields = array(
"token" => $token,
"file" => curl_file_create ($_GET['filename'], 'text/csv')
);
Hope that help's anybody.

Php curl headers default content type not changing

In curl default content type not changing 'application/json' in output.
$headers = array();
$headers[] = 'Accept: application/xml';
$headers[] = 'Content-Type: application/xml';
$url = url('someurl here');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response=curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
Output:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Request-Time: 295
Date: Wed, 28 Jun 2017 07:41:58 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Connection: Transfer-Encoding
am i done any mistake in that above code? I need output in xml format only.
There is no mistake. Content-type header that you setted is a request header. It defines type of content that you're sending to a server. Which make no sense in GET requests type.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
Is a response headers. Content type here shows format of the server response.
Maybe you didn't pass some parameter that tells server to return xml data instead of json.

How to perform a PUT operation using CURL in PHP?

I would like to perform a PUT operation on a webservice using CURL. Let's assume that:
webservice url: http://stageapi.myprepaid.co.za/api/ConsumerRegisterRequest/cac52674-1711-e311-b4a8-00155d4905d3
municipality= NMBM
sgc= 12345
I've written the code below, but it outputs this error message: "ExceptionMessage":"Object reference not set to an instance of an object.". Any help would be so much appreciated. Thanks!
<?php
function sendJSONRequest($url, $data)
{
$data_string = json_encode($data);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Accept: application/json',
'X-MP-Version: 10072013')
);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
ob_start();
$result = curl_exec($ch);
$info = curl_getinfo($ch);
if ($result === false || $info['http_code'] == 400) {
return $result;
} else {
return $result;
}
ob_end_clean();
curl_close($ch);
}
$mun = $_GET['municipality'];
$sgc = $_GET['sgc'];
$req = $_GET['req']; //cac52674-1711-e311-b4a8-00155d4905d3
//myPrepaid PUT URL
echo $mpurl = "http://stageapi.myprepaid.co.za/api/ConsumerRegisterRequest/$req";
// Set Variables
$data = array("Municipality" => "$mun", "SGC" => "$sgc");
//Get Response
echo $response = sendJSONRequest($mpurl, $data);
?>
I copied your code, but changed it so it pointed at a very basic HTTP server on my localhost. Your code is working correctly, and making the following request:
PUT /api/ConsumerRegisterRequest/cac52674-1711-e311-b4a8-00155d4905d3 HTTP/1.1
Host: localhost:9420
Content-Type: application/json
Accept: application/json
X-MP-Version: 10072013
Content-Length: 37
{"Municipality":"NMBM","SGC":"12345"}
The error message you're receiving is coming from the stageapi.myprepaid.co.za server. This is the full response when I point it back to them:
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 30 Aug 2013 04:30:41 GMT
Connection: close
Content-Length: 867
{"Message":"An error has occurred.","ExceptionMessage":"Object reference not set to an instance of an object.","ExceptionType":"System.NullReferenceException","StackTrace":" at MyPrepaidApi.Controllers.ConsumerRegisterRequestController.Put(CrmRegisterRequest value) in c:\\Workspace\\MyPrepaid\\Prepaid Vending System\\PrepaidCloud\\WebApi\\Controllers\\ConsumerRegisterRequestController.cs:line 190\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)\r\n at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)"}
You may want to check out the API to make sure you're passing them the correct information. If you are, the problem could be on their end.
And while I realize this isn't part of your question and this is in development, please remember to sanitize any data from $_GET. :)
Try with:
curl_setopt($ch, CURLOPT_PUT, true);

how to handle box.net download responce in php

i am trying to download a file using box.net using API in php.
As per the documentation i wrote up the code.
but in response i am getting some strange texts.
here's my code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.box.com/2.0/files/3934139624/content ");
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPGET,true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: BoxAuth api_key={MyApikey}&auth_token={Mytoken}"));
$result = curl_exec($ch);
die('DIE');
I am getting response something like this:
PK!Ðòš-[Content_Types].xml ¢( ´UËNÃ0¼#ñ‘¯¨qË!Ô´G¨Dù×Þ´‰mÙÛ×ß³IšA›ˆ†^"EÑÎÌÎÎnÆÓ]žEðA[“°QH¯~ÉŸb üv8¼ãÒƒ,0ØdüF¼VÍ„ÇW‘ßZ¯xj-‹b‚cÑcUWP'L8—i)„óQ?H6Mµeå:'ª¸€sÞJZ˳¸¾) ùdü©Xg=ïH[e‡‡,üõÐfL•¥²°Ò.´0´·uPvÒž¦»v˜3Üis¡M­ÿ¤³ÎàÉ×ÿSÝ)"à>»DP*ÜNz0êBI­‘Û$мfÞºÀi+zŠ P ´0"f3°£\…ȾTºI S‘ÌõŒ«º¾ÇôWš™¦ÚY igï#µÇX6_Ö]7~ fïØˉÈaoÙ.b*lIÆrj)õ,l0Ï%‘b¬ 6ài¢ÕõDÿ_‹Ž…, ¡ ‰Ïó|uœZ^tÙ¢yǯ;!Y,}{ûCƒ³/h>ÿÿPK!¿hJä1>word/rels/document.xml.rels ¢( ¬”ËNÃ0E÷HüCä=qR q'æ>¾ƒ“‘ˆsµà©WÃ-ŽÌEî›nâ>ðÍqã¨Í§y±3ÆóüükeìE±ty’àÕ³üÍ黦ÏÖ¤KLÏhóÊŸi¾IàˆpzÒŽ¹ç?}xÛxx;ùgïÐ¥f7Yô KéMèwÄÆÇÐEïúÃF§³ß9ètÏ7ÌKWxÐ/žñ¡“ùéâ;W…—Ô•¯bú%B×óù§ìv îã㡈“ô£ 8ÜílìÐqq~x|!Ã4Á1Nâ ñaãVš+¾•ËÓr¤ØLe'õc"ójS“Œ(ñR'»>wbriê’6œ,•ôçPøH†.ÔO«<çµ¼G›[¯ ‹Ÿ~ëÈŒcñ)“ )ò<­4/nÌ—­ôEÛþßpÄÙ÷æ¬Û?xg«\ÖîЃSäÀ•Ç°tÒ(¾‹³ƒwïg˜³ÕKøŒ;ù¾.†ì, l©´ªµÐm¯]‰ŠTíßnÁ¿·ß¤/ë»–ª”짓6õ“^Qð-wô—Qð]6bé à²#ÆûÍ#¡™˜×Fa'™Â†êMî'ÂÛ¿U*XÆÞ/¾\ÁÜl X5HñKÕ˜sØ8EÌ/!вÃÐeq”µ±dº¨É…⛂R—7ЊU¹iØF:h±FÎç¢àõð¾ôÈ!˜&æ',ADSÈP¸L‘M.úìäpow½Ý(¥Ú·R ãpK0è7^;¿Lë4f¤P­3Ì…#M s´ï¡Ü:…(#à(1ß;9|÷S½°T4ϹF²ì%“$åÁf“tÖة⼪R&˜nn†)#éóÒfŽBC?‰ð€()ÄÝ(%LNËñ)V^«ÞÛ¶[5+Í>jÀ£WlŽ÷¡¿)ÁoôFBû›CÕ©ë­Ü™ÖI¦æÖQ×ƤHX-ijž^ÀDûs“ …Ø}
Can any one tell me how can i handle such kind of response?
thanks in advance.
As per box.net api documentation:
The response to this request will simply be the complete data of the
file itself.
So all you need to save file content locally.
In response header, you need to check content-type, right now it is XML
$result = curl_exec($ch);
$fp = fopen('test.xml','wb');
fwrite($fp, $result);
fclose($fp);
#GBD following comes in response header:
HTTP/1.1 302 Found
Server: nginx
Date: Wed, 14 Nov 2012 09:11:51 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Cache-control: private
Location: https://dl.boxcloud.com/bc/1/85f471520cf611a05025a5f/JolueqOGpciD6dgYhecNBoVpYxkvmYe1ZLheZor6BF4DUBIelMQTkFwYIys3nIibNIIEHUp447tBZLaXDzIbNQ,,/a44510a2b21219463fade41d6b36dabf/
Content-Length: 0
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 14 Nov 2012 09:11:52 GMT
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Content-Length: 19944
Connection: keep-alive
Cache-control: private
Accept-Ranges: bytes
Content-Disposition: attachment;filename="cloud computing proposal.docx";filename*=UTF-8''cloud%20computing%20proposal.docx
X-Content-Type-Options: nosniff
Accept-Ranges: bytes
And saving file in xml also,couldn't b opened.

Getting just the Location from Header of cURL Request

I'm trying to retrieve the location URL of an image after a redirect, but I can't seem to get it to work. I've never used cURL before, but from the research I've done it looks like I need it to get an image from Facebook. Here's my code so far:
function getImage($url) {
$ch = curl_init();
// Only calling the head
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
$image = explode("Location: ", getImage("http://graph.facebook.com/553451657/picture?type=large"));
print_r($image);
But my response is:
HTTP/1.1 302 Found Access-Control-Allow-Origin: * Cache-Control: private, no-cache, no-store, must-revalidate Content-Type: image/jpeg Expires: Sat, 01 Jan 2000 00:00:00 GMT Location: http://profile.ak.fbcdn.net/hprofile-ak-snc4/161877_553451657_798840908_n.jpg Pragma: no-cache X-FB-Rev: 590433 X-FB-Debug: WH1uJvIjUqiLT8ezVPdude8VKYnXjAHRlFaP8gqF9fI= Date: Fri, 13 Jul 2012 17:56:09 GMT Connection: keep-alive Content-Length: 0 Array ( [0] => 1 )
How do I JUST get the Location part ("http://profile.ak.fbcdn.net/hprofile-ak-snc4/161877_553451657_798840908_n.jpg")?
You can do a function on the headers:
$headers = [];
curl_setopt($curl, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$headers) {
$matches = array();
if ( preg_match('/^([^:]+)\s*:\s*([^\x0D\x0A]*)\x0D?\x0A?$/', $header, $matches) )
{
$headers[$matches[1]][] = $matches[2];
}
return strlen($header);
});
(seen here)
Then you get it stored in $headers["Location"][0].
I am also, like you, trying to get the fb page image this way, it seems no PHP SDK, App priviledges or access_token is needed for that, but there might be some limitations (anybody knows?)
How do I JUST get the Location part
Getting that Location header is not you’re primary goal, right? You want to get the image from the address that’s being redirected to, correct?
So just set the option CURLOPT_FOLLOWLOCATION, and cURL will follow that redirect automatically and fetch the real image for you.

Categories