I've written some code to get a file via curl. I only want the headers and not the actual file itself
$info = curl_init() or die('error 1');
curl_setopt($info, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($info, CURLOPT_PORT , 8089);
curl_setopt($info, CURLOPT_URL, $url);
curl_setopt($info, CURLOPT_HEADER,true);
curl_setopt($info, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($info, CURLOPT_NOBODY, true);
//curl_setopt($info, CURLOPT_SSL_VERIFYPEER, 0);
curl_exec($info);
if(!curl_errno($info)){
$response = curl_getinfo($info);
echo "<pre>";
print_r(get_headers($response));
echo "</pre>";
}else{
echo "error!";
echo "<br>" . curl_error($info);
}
However the response returned by this doesn't contain any of the information that should be in a header - e.g filename
array(26) {
["url"]=>
string(55) "https://www.filepicker.io/api/file/CjDfxG0WSmGiY3O2eKDE"
["content_type"]=>
string(9) "image/png"
["http_code"]=>
int(200)
["header_size"]=>
int(840)
["request_size"]=>
int(86)
["filetime"]=>
int(-1)
["ssl_verify_result"]=>
int(0)
["redirect_count"]=>
int(0)
["total_time"]=>
float(1.578048)
["namelookup_time"]=>
float(0.000494)
["connect_time"]=>
float(0.026931)
["pretransfer_time"]=>
float(0.13615)
["size_upload"]=>
float(0)
["size_download"]=>
float(0)
["speed_download"]=>
float(0)
["speed_upload"]=>
float(0)
["download_content_length"]=>
float(965985)
["upload_content_length"]=>
float(0)
["starttransfer_time"]=>
float(1.578002)
["redirect_time"]=>
float(0)
["certinfo"]=>
array(0) {
}
["primary_ip"]=>
string(11) "79.125.4.68"
["primary_port"]=>
int(443)
["local_ip"]=>
string(11) "192.168.0.9"
["local_port"]=>
int(53950)
["redirect_url"]=>
string(0) ""
}
So how can I get the actual header itself?
The reason this was happening is because I was discarding the input of curl_exec. I changed that section of the code to:
$headers=curl_exec($info);
Related
I am used cURL in PHP for uploading a video to Wistia. Everything works fine in my local server. But in dev server , the video is not uploading. Using the var_dump(curl_getinfo($ch)), I can see the content_type is different from local to dev server. I am confused about it.Can any one help me to resolve this problem.
Here is my code:
public function video_upload($filePath)
{
$data = array(
'api_password' => '0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5',
'file' => '#'.$filePath,
);
$url = 'https://upload.wistia.com';
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HEADER => false,
CURLOPT_RETURNTRANSFER => true,
));
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
$response = curl_exec($ch);
var_dump(curl_getinfo($ch));
var_dump(curl_errno($ch));
curl_close($ch);
return $response;
}
Response received in my local server:
array(27) {
["url"]=> string(26) "https://upload.wistia.com/"
**["content_type"]=> string(30) "application/json;charset=utf-8"**
["http_code"]=> int(200)
["header_size"]=> int(688)
["request_size"]=> int(189)
["filetime"]=> int(-1)
["ssl_verify_result"]=> int(0)
["redirect_count"]=> int(0)
["total_time"]=> float(17.850026)
["namelookup_time"]=> float(0.252903)
["connect_time"]=> float(0.253271)
["pretransfer_time"]=> float(1.903306)
["size_upload"]=> float(279250)
["size_download"]=> float(417)
["speed_download"]=> float(23)
["speed_upload"]=> float(15644)
["download_content_length"]=> float(417)
["upload_content_length"]=> float(279250)
["starttransfer_time"]=> float(2.173591)
["redirect_time"]=> float(0)
["redirect_url"]=> string(0) ""
["primary_ip"]=> string(13) "162.209.95.19"
["certinfo"]=> array(0) { }
["primary_port"]=> int(443)
["local_ip"]=> string(13) "192.168.1.157"
["local_port"]=> int(54999)
["request_header"]=> string(189) "POST / HTTP/1.1 Host: upload.wistia.com Accept: */* Content-Length: 279250 Expect: 100-continue Content-Type: multipart/form-data; boundary=------------------------370a5719d6336ecc "
} int(0)
Response received in my dev server :
array(27) {
["url"]=> string(26) "https://upload.wistia.com/"
**["content_type"]=> string(23) "text/html;charset=utf-8"**
["http_code"]=> int(500)
["header_size"]=> int(718)
["request_size"]=> int(186)
["filetime"]=> int(-1)
["ssl_verify_result"]=> int(0)
["redirect_count"]=> int(0)
["total_time"]=> float(0.437061)
["namelookup_time"]=> float(0.004766)
["connect_time"]=> float(0.023656)
["pretransfer_time"]=> float(0.194844)
["size_upload"]=> float(319)
["size_download"]=> float(30)
["speed_download"]=> float(68)
["speed_upload"]=> float(729)
["download_content_length"]=> float(30)
["upload_content_length"]=> float(319)
["starttransfer_time"]=> float(0.216544)
["redirect_time"]=> float(0)
["redirect_url"]=> string(0) ""
["primary_ip"]=> string(15) "162.242.168.223"
["certinfo"]=> array(0) { }
["primary_port"]=> int(443)
["local_ip"]=> string(14) "224.178.240.48"
["local_port"]=> int(55164)
["request_header"]=> string(186) "POST / HTTP/1.1 Host: upload.wistia.com Accept: */* Content-Length: 319 Expect: 100-continue Content-Type: multipart/form-data; boundary=----------------------------d45c07c28860 "
} int(0)
It's hard to say why it is not working, but the response you get from the server includes a 500 http status code, which indicates that something is wrong on the server.
It is possible that there is something wrong on your end, but without more information from the server, it's really hard to tell what is going wrong. In general, 500 responses from the server indicates a server (wistia) error, not a client (you) error.
You might want to send the information to wistia to get more details.
You are getting a 500 error from the server in the second response. That's why it is not json.
I bet you're doing a different POST request altogether,
do like
$verbosefileh=tmpfile();
$verbosefile=stream_get_meta_data($verbosefileh)['uri'];
curl_setopt_array($ch,array(
CURLOPT_CERTINFO=>true,
CURLOPT_VERBOSE=>true,
CURLOPT_STDERR=>$verbosefileh
));
curl_exec($ch);
$postrequest=file_get_contents($verbosefile);
then study the post request closely, what's the difference between the request sent by the 2 servers? i bet there is something.. unless you're blocked out of IP ban
edit: a common gotcha, on some installations curl has a default useragent, and on some installations, curl doesn't. (like in debian 6, its something like "curl/7.21.3 (x86_64-unknown-linux-gnu) libcurl/7.21.3 OpenSSL/1.0.0c zlib/1.2.5", while in debian 8, there IS no default string.. or was it the other way around?), and many websites will block requests that doesn't contain a useragent. to ensure you have a useragent, you can use curl_setopt($ch,CURLOPT_USERAGENT,'curl php');
I have been trying to use the AIDA disambiguation service. Their posted cURL example works fine through the terminal. However, when I try to implement it through PHP, I get an empty response immediately. To top it all off, I'm trying to access this resource essentially from Javascript, but as far as I've found, going through PHP is the best way to access resources from another domain.
My PHP code:
<?php
//set POST variables
$url = $_POST['url'];
unset($_POST['url']);
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL,$url);
curl_setopt($curl,CURLOPT_POST,count($_POST));
curl_setopt($curl,CURLOPT_HTTPHEADER,array('Expect:'));
curl_setopt($curl,CURLOPT_POSTFIELDS,$_POST);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
$a = curl_exec($curl);
error_log('Status: '.var_dump(curl_getinfo($curl)));
curl_close($curl);
?>
The curl_getinfo:
array(26) {
["url"]=>
string(56) "https://gate.d5.mpi-inf.mpg.de/aida/service/disambiguate"
["content_type"]=>
NULL
["http_code"]=>
int(0)
["header_size"]=>
int(0)
["request_size"]=>
int(0)
["filetime"]=>
int(-1)
["ssl_verify_result"]=>
int(0)
["redirect_count"]=>
int(0)
["total_time"]=>
float(0.125)
["namelookup_time"]=>
float(0)
["connect_time"]=>
float(0.063)
["pretransfer_time"]=>
float(0)
["size_upload"]=>
float(0)
["size_download"]=>
float(0)
["speed_download"]=>
float(0)
["speed_upload"]=>
float(0)
["download_content_length"]=>
float(-1)
["upload_content_length"]=>
float(-1)
["starttransfer_time"]=>
float(0)
["redirect_time"]=>
float(0)
["redirect_url"]=>
string(0) ""
["primary_ip"]=>
string(12) "139.19.87.30"
["certinfo"]=>
array(0) {
}
$a is just empty. $url is set properly. The only other variable, text, seems to be set properly as well. Anyone know what might be going wrong here?
with something like that i have the answer from AIDA web service.
In $result post the text you want to disambiguate.
<?php
$url = "https://gate.d5.mpi-inf.mpg.de/aida/service/disambiguate";
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_POST, true); // tell curl you want to post something
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_POSTFIELDS, "text='".$result."'");
curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
$a = curl_exec($curl);
curl_close($curl);
var_dump($a);
?>
I hope that will help you
I'm trying to set up a curl request for getting remote files only if they are been modified since my stored timestamp.
I want to manage the http code of my cURL request, here is an example.
I have stored a timestamp of the last download of file XX. 2014-12-08 06:56:03.
My cURL request
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FILETIME, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEVALUE, strtotime($timestamp));
curl_setopt($ch, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
$res = curl_exec($ch);
$info = curl_getinfo($ch);
As the documentation says
CURLOPT_TIMECONDITION
How CURLOPT_TIMEVALUE is treated. Use CURL_TIMECOND_IFMODSINCE to return the page only if it has been modified since the time specified in CURLOPT_TIMEVALUE. If it hasn't been modified, a "304 Not Modified" header will be returned assuming CURLOPT_HEADER is TRUE. Use CURL_TIMECOND_IFUNMODSINCE for the reverse effect. CURL_TIMECOND_IFMODSINCE is the default.
So, if my timestamp is 2014-12-08 06:56:03 and the filetime of the remote file is 2014-12-08 04:59:03 it has to return an http code of 304, but I'm getting always an http code of 200.
Have I misunderstood the docs?
These are the timestamps in seconds
local file 1418021941
remote file 1418014742
and this are the info of the above curl request
array(26) {
["url"]=> string(32) "XXX"
["content_type"]=> string(24) "application/octet-stream"
["http_code"]=> int(200)
["header_size"]=> int(251)
["request_size"]=> int(113)
["filetime"]=> int(1418014742)
["ssl_verify_result"]=> int(0)
["redirect_count"]=> int(0)
["total_time"]=> float(0.100412)
["namelookup_time"]=> float(0.010285)
["connect_time"]=> float(0.05576)
["pretransfer_time"]=> float(0.055878)
["size_upload"]=> float(0)
["size_download"]=> float(0)
["speed_download"]=> float(0)
["speed_upload"]=> float(0)
["download_content_length"]=> float(371712)
["upload_content_length"]=> float(0)
["starttransfer_time"]=> float(0.100382)
["redirect_time"]=> float(0)
["redirect_url"]=> string(0) ""
["primary_ip"]=> string(11) "XXX"
["certinfo"]=> array(0) { }
["primary_port"]=> int(80)
["local_ip"]=> string(11) "XXX"
["local_port"]=> int(XX)
}
These are the info if I change the timestamp of my local file to be less than the remote one 2014-12-06 06:56:03
array(26) {
["url"]=> string(32) "XXX"
["content_type"]=> string(24) "application/octet-stream"
["http_code"]=> int(200)
["header_size"]=> int(251)
["request_size"]=> int(113)
["filetime"]=> int(1418014742)
["ssl_verify_result"]=> int(0)
["redirect_count"]=> int(0)
["total_time"]=> float(0.583712)
["namelookup_time"]=> float(0.011975)
["connect_time"]=> float(0.056813)
["pretransfer_time"]=> float(0.056977)
["size_upload"]=> float(0)
["size_download"]=> float(371712)
["speed_download"]=> float(636807)
["speed_upload"]=> float(0)
["download_content_length"]=> float(371712)
["upload_content_length"]=> float(0)
["starttransfer_time"]=> float(0.103772)
["redirect_time"]=> float(0)
["redirect_url"]=> string(0) ""
["primary_ip"]=> string(11) "XXX"
["certinfo"]=> array(0) { }
["primary_port"]=> int(80)
["local_ip"]=> string(11) "XX"
["local_port"]=> int(XX)
}
As you can see there is a difference between the two, the [size download], =0 in the first one, >0 in the second one.
Any suggestion? I will always get an http code = 200?
--------- edit
This is the header I get back with local timestamp 2014-12-08 06:59:01
HTTP/1.1 200 OK Server: nginx Date: Mon, 08 Dec 2014 10:23:06 GMT Content-Type: application/octet-stream Content-Length: 371712 Last-Modified: Mon, 08 Dec 2014 04:59:02 GMT Connection: keep-alive ETag: "54853016-5ac00" Accept-Ranges: bytes
Yes, you misunderstood the dosc.
If it hasn't been modified, a "304 Not Modified" header will be returned assuming CURLOPT_HEADER is TRUE.
No change -> Return a "304 Not Modified" header.
Modified -> Return 200
---------round 2---------
File's Last-Modified: Thu, 18 Dec 2014 05:37:48 GMT.
date_default_timezone_set("Etc/GMT");
$url = "...";
$timestamp = "2014-12-18 05:37:48";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_TIMEVALUE, strtotime($timestamp));
curl_setopt($ch, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
$res = curl_exec($ch);
1, if i use above test code, it will return a head like this:
HTTP/1.1 304 Not Modified
Date: Thu, 18 Dec 2014 08:27:55 GMT
Server: Apache/2.4.7 (Ubuntu)
ETag: "17c-50a76fe108d7a"
2, when i change the $timestamp, it will return this:
HTTP/1.1 200 OK
Date: Thu, 18 Dec 2014 08:31:02 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Thu, 18 Dec 2014 05:37:48 GMT
ETag: "17c-50a76fe108d7a"
Accept-Ranges: bytes
Content-Length: 380
Vary: Accept-Encoding
Content-Type: text/html
I think you should set the timezone, if i don't set the timezone it always return 200.
I'm using PHP cURL-multi to make HTTP requests on another server. The scripts on the other server are in Perl/CGI. In the case of a fatal error on that end, I'd like to throw back a 500 Server Error (unless there's a better method).
Here's my PHP. Note that fb() is a procedural call to FirePHP's logger.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://otherserver.com/cgi-bin/myCgiScript.cgi");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// grab URL and pass it to the browser
$result = curl_exec($ch);
if ($result === false) {
$errno = curl_errno($ch);
$error = curl_error($ch);
print "errno:\n";
var_dump($errno);
print "error:\n";
var_dump($error);
} else {
print "result:\n";
var_dump($result);
}
$info = curl_getinfo($ch);
print "info:\n";
var_dump($info);
curl_close($ch);
And here is a sample Perl CGI file from the other server:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use Try::Tiny;
my $q = new CGI();
try {
# Code that might die().
print $q->header({
-type => "application/json",
-status => "200 OK"
});
print $results;
} catch {
my $message = $_;
chomp($message);
print $q->header({
-type => "application/json",
-status => "500 Server Error",
-message => $message
});
};
But no matter what I do, I can't seem to get the "message" text out of cURL. (Nor can I get the "Server Error" portion of the "500 Server Error". I get the fact that I got a 500 error, but no text to go along with it.
Edit:
I simplified the PHP example.
Now it's not following the "failure" path... i.e. it's simply returning "" if I have CURLOPT_HEADER = 0, or the text of the 500 Server Error if CURLOPT_HEADER = 1:
result:
string(398) "HTTP/1.1 500 Server Error
Date: Fri, 22 Aug 2014 15:32:38 GMT
Server: Apache/2.2.21 (Unix) DAV/2 mod_ssl/2.2.21 OpenSSL/1.0.0e
Message: malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)") at /opt/apache/cgi-bin/CSU_SIGNUP_2.0/getCsuAttributes.cgi line 45
Content-Length: 0
Connection: close
Content-Type: application/json
"
info:
array(20) {
["url"]=>
string(46) "http://otherserver.com/cgi-bin/myCgiScript.cgi"
["content_type"]=>
string(16) "application/json"
["http_code"]=>
int(500)
["header_size"]=>
int(398)
["request_size"]=>
int(113)
["filetime"]=>
int(-1)
["ssl_verify_result"]=>
int(0)
["redirect_count"]=>
int(0)
["total_time"]=>
float(1.117776)
["namelookup_time"]=>
float(0.006001)
["connect_time"]=>
float(0.008552)
["pretransfer_time"]=>
float(0.266607)
["size_upload"]=>
float(0)
["size_download"]=>
float(0)
["speed_download"]=>
float(0)
["speed_upload"]=>
float(0)
["download_content_length"]=>
float(0)
["upload_content_length"]=>
float(0)
["starttransfer_time"]=>
float(1.11773)
["redirect_time"]=>
float(0)
}
Can you do a redirect something like this...
header( 'Location: http://www.yoursite.com/error.php?error=5000' ) ;
And let your php and use $_GET[error']; and let php do the work from there?
You've said your content-type is JSON, but it isn't ("malformed JSON string"). Set a content-type of text for the error and you should be OK.
$curl = new Curl();
$data = 'Email='.urlencode('MYEMAIL#EMAIL.COM').'&Passwd='.urlencode('MYPASSWORD').'&accountType=GOOGLE&source=Google-cURL-Example&service=jotspot';
$curl->post('https://www.google.com/accounts/ClientLogin',$data);
//match authorization token
preg_match("!Auth=(.*)!",$curl->response,$match);
$auth = $match[1];
//set curl headers
$curl->set_headers(array(
'Content-Type: application/atom+xml; charset=utf-8',
'Host: sites.google.com',
'GData-Version: 1.4',
'Authorization: GoogleLogin auth='. trim($auth)));
//get a list of sites associated with my domain
$curl->get('https://sites.google.com/feeds/site/clevertechie.mygbiz.com');
//contains data returned by $curl->get();
echo $curl->response;
So instead of getting the list of sites from $curl->response, I get a message - "Content is not allowed in prolog." I've looked everywhere and haven't been able to find a solution, please help! Thanks! :)
This is the XML that is supposed to be returned by the response:
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007' xmlns:sites='http://schemas.google.com/sites/2008' xmlns:gs='http://schemas.google.com/spreadsheets/2006' xmlns:dc='http://purl.org/dc/terms' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'>
<updated>2012-10-31T19:00:17.297Z</updated>
<app:edited xmlns:app='http://www.w3.org/2007/app'>2012-10-31T19:00:17.297Z</app:edited>
<title>My Site Title</title>
<summary>My Site Summary</summary>
<sites:siteName>my-site-title</sites:siteName>
<sites:theme>slate</sites:theme>
</entry>
I can't paste the source of "https://sites.google.com/feeds/site/clevertechie.mygbiz.com" because it can't be accessed directly without authorization token, which is specified in the headers. The only way to retrieve its data is by using the token in the headers which I've done. Instead of getting above XML, I'm getting "Content is not allowed in prolog".
var_dump of $curl:
object(Curl)#1 (11) { ["curl_resource":protected]=> resource(4) of type (Unknown) ["proxy":protected]=> bool(false)
["proxy_type":protected]=> NULL ["response"]=> string(33) "Content is not allowed in prolog." ["time"]=> float(249)
["info"]=> array(26) { ["url"]=> string(59) "https://sites.google.com/feeds/site/clevertechie.mygbiz.com"
["content_type"]=> string(24) "text/html; charset=UTF-8" ["http_code"]=> int(400) ["header_size"]=> int(676)
["request_size"]=> int(1935) ["filetime"]=> int(-1) ["ssl_verify_result"]=> int(20) ["redirect_count"]=> int(0)
["total_time"]=> float(0.249) ["namelookup_time"]=> float(0.015) ["connect_time"]=> float(0.046)
["pretransfer_time"]=> float(0.109) ["size_upload"]=> float(111) ["size_download"]=> float(33)
["speed_download"]=> float(132) ["speed_upload"]=> float(445) ["download_content_length"]=> float(-1)
["upload_content_length"]=> float(111) ["starttransfer_time"]=> float(0.249) ["redirect_time"]=> float(0)
["certinfo"]=> array(0) { } ["primary_ip"]=> string(14) "74.125.224.194" ["primary_port"]=> int(443)
["local_ip"]=> string(13) "192.168.1.133" ["local_port"]=> int(61985) ["redirect_url"]=> string(0) "" }
["error"]=> NULL ["custom_headers"]=> NULL ["cookie_file"]=> string(46) "cookies.txt"
["custom_curl_options":protected]=> array(3) { [47]=> int(1) [10015]=> string(111)
"Email=MYEMAIL&Passwd=MYPASSWORD&accountType=GOOGLE&source=Google-cURL-Example&service=jotspot"
[10023]=> array(4) { [0]=> string(49) "Content-Type: application/atom+xml; charset=utf-8"
[1]=> string(22) "Host: sites.google.com" [2]=> string(18) "GData-Version: 1.4" [3]=> string(320)
"Authorization: GoogleLogin auth=DQAAAMMAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" } } ["curl_options":protected]=> array(9) { [10018]=> string(74)
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1" [10016]=> string(22)
"http://www.google.com/" [13]=> int(60) [78]=> int(60) [19913]=> int(1) [52]=> int(1) [64]=> int(0) [81]=> int(0) [42]=> int(0) } }
$auth is just a string, its not supposed to be formatted as XML. I verified that there are no extra spaces or characters and it exactly matches the one returned by the first $curl->post request.
Leave the request type as a POST (with the content being the atom xml payload), set the content type to “application/atom+xml” but pass all of the oAuth as a GET, i.e. as escaped (urlEncoded) values on the URL query string.