cURL works in CLI, but not in PHP? - php

This is the code I am using:
curl -k https://www.ashleydirect.com/graphics/ad_images/T908-6.jpg
This works fine (the "-k" flag is necessary for it to work or it times out)
I then use this code in PHP:
$ch = curl_init("https://www.ashleydirect.com/graphics/ad_images/T908-6.jpg");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
And it times out -- I've tried a ton of variations, but $result is always false.
This is the PHP cURL information when I do phpinfo():
cURL support enabled
cURL Information 7.38.0
Age 3
Features
AsynchDNS No
Debug No
GSS-Negotiate No
IDN Yes
IPv6 Yes
Largefile Yes
NTLM Yes
SPNEGO No
SSL Yes
SSPI No
krb4 No
libz Yes
CharConv No
Protocols dict, file, ftp, ftps, gopher, http, https, imap, imaps, pop3, pop3s, rtsp, smtp, smtps, telnet, tftp
Host x86_64-unknown-linux-gnu
SSL Version OpenSSL/1.0.1e
ZLib Version 1.2.3
Any ideas would be greatly appreciated.
UPDATE
Here is the information from curl_getinfo($ch):
array (
'url' => 'https://www.ashleydirect.com/graphics/ad_images/T908-6.jpg',
'content_type' => NULL,
'http_code' => 0,
'header_size' => 0,
'request_size' => 0,
'filetime' => -1,
'ssl_verify_result' => 1,
'redirect_count' => 0,
'total_time' => 59.27538100000000298450686386786401271820068359375,
'namelookup_time' => 0.00975999999999999957867036215475309290923178195953369140625,
'connect_time' => 0.05170500000000000095923269327613525092601776123046875,
'pretransfer_time' => 0,
'size_upload' => 0,
'size_download' => 0,
'speed_download' => 0,
'speed_upload' => 0,
'download_content_length' => -1,
'upload_content_length' => -1,
'starttransfer_time' => 0,
'redirect_time' => 0,
'certinfo' =>
array (
),
'primary_ip' => '65.207.240.29',
'primary_port' => 443,
'local_ip' => '172.24.32.132',
'local_port' => 54461,
'redirect_url' => '',
)
UPDATE 2
Response from curl_error:
Unknown SSL protocol error in connection to www.ashleydirect.com:443
UPDATE 3 - Solution
I wanted to clearly put the solution I came up with, thanks to #Valery Viktorovsky who pointed out they only accept TLS 1.0.
The solution, then was to add this:
// Set to TLS 1.0 (CURL_SSLVERSION_TLSv1_0)
curl_setopt($ch, CURLOPT_SSLVERSION, 4);
More information here

Your php code is fine. Do a curl_getinfo($ch) and curl_error($ch) aftercurl_exec to see the response code returned by the server.
Update: I tested ashleydirect.com SSL certificate and it supports only TLS 1.0. So make sure your php version supports TLSv1.0.

It works fine for me, both the command line without -k and the PHP code.
If for some reason it times out you can set a bigger timeout:
// if it times out on establishing the connection
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // seconds
// if it times out while waiting for the response
curl_setopt($ch, CURLOPT_TIMEOUT, 60); // seconds
Also, the call curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false) is usually accompanied by:
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
to get the complete effect.

Related

Curl - can't get the content of a page and/or post data on that page

I'm trying to get a webpage using curl but i get only a blank page, no output. Here is how i'm trying to do it:
curl_setopt($ch, CURLOPT_URL, 'https://example.com/b2b/');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
curl_setopt($ch, CURLOPT_USERAGENT,"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 " );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
After some research i tried to add this like:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Encoding: gzip'));
And also this is how i'm trying to echo it out after adding the last line:
$response = curl_exec($ch);
$content = #gzdecode($response);
echo ($content !== false) ? $content : $response;
Am i doing something wrong? I mean this works if i change the url with another website's url :(.
P.S This is what i get if i print_r curl_getinfo():
Array
(
[url] => https://example.com/b2b/
[content_type] =>
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0
[namelookup_time] => 0
[connect_time] => 0
[pretransfer_time] => 0
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[redirect_url] =>
[primary_ip] =>
[certinfo] => Array
(
)
[primary_port] => 0
[local_ip] =>
[local_port] => 0
)
Thank you!
This is a more technical than practical answer but I'll explain what is happening here and why the requested webpage cannot be fetched by cURL.
Please note that this seems to be an edge case. It might work on your system while it does not work on other systems. See Symantec PKI Distrust for more information.
What is happening?
To see what is happing when making the cURL call one should enable CURLOPT_VERBOSE logging:
* Hostname [REDACTED] was found in DNS cache
* Trying [REDACTED]...
* TCP_NODELAY set
* Connected to [REDACTED] ([REDACTED]) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL certificate problem: unable to get local issuer certificate
* stopped the pause stream!
* Closing connection 0
From this we can conclude that the certificate used to issue the TLS certificate of the website cannot be found in the CA truststore of cURL (located in /etc/ssl/certs/ca-certificates.crt on this system).
Now one might wonder why this is the case. Well that is because of the distrust of the CA certificate that issues the certificate for this website. The website uses a RapidSSL TLS certificate, which is issued before the 1st of December 2017. This means it falls withing the distrust section of old RapidSSL certificates.
How can this be solved?
Well you cannot really do anything. It is up to the owner of the website to update their TLS certificates. They should really be doing this because Chrome will start throwing nasty errors real soon. (Errors should already be appearing in the M70 beta versions. After the 16th of October all releases [>M70] will throw big nasty errors.)
Except that you can bypass the SSL/TLS certificate checks in cURL.
I DO NOT RECOMMEND THIS, YOU SHOULD NEVER DISABLE THE CERTIFICATE CHECKS!
You can use
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
to disable the checks and after that cURL will return the webpage:
<?php
$url = "https://[REDACTED]";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // one should never do this
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // or this!!!
$output = curl_exec($ch);
curl_close($ch);
echo $output;
// all kinds of HTML and other things
?>
Conclusion
The requested website uses a certificate that will be distrusted/is already distrusted and therefore cURL cannot complete the TLS handshake to establish a secure connection to the website. This is all due to the Distrust of the Symantec PKI.
Please note (again) that one should never disable the security checks.

PHP cURL is not working on Xampp Windows 10

I am using curl to fetch data from different web service hosted on different location on the web. I am trying to fetch the data to my localhost.
$token1="SOMETOKENXX";
$mobileNumber= $_POST['number'];
$postData = array(
'mobile' =>$mobileNumber
);
$service_url ='http://api.hashtagloyalty.in/merchants/users/users_profile';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $service_url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_PORT, 8080);
curl_setopt($curl, CURLOPT_USERAGENT , "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17");
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postData));
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json','Authorization:'.$token1));
$curl_response = curl_exec($curl);
// echo($curl_response);
if ($curl_response === false)
{
$info = curl_getinfo($curl);
die('error occured during curl exec. Additioanl info: ' . var_export($info));
}else{
echo "TRUE";
}
curl_close($curl);
I am not able to fetch the result on xampp localhost but working on GoDaddy live server.
I am working on latest version of xampp 7.2.6 and Windows 10 OS
I am accessing my localhost on port 8080 means my localhots url is localhost:8080 .
How can I know if something is blocking my request?
There is no result and giving empty result.
Please help
error
array ( 'url' => 'http://api.hashtagloyalty.in/merchants/users/users_profile', 'content_type' => NULL, 'http_code' => 0, 'header_size' => 0, 'request_size' => 0, 'filetime' => -1, 'ssl_verify_result' => 0, 'redirect_count' => 0, 'total_time' => 20.204, 'namelookup_time' => 1.0E-6, 'connect_time' => 0.0, 'pretransfer_time' => 0.0, 'size_upload' => 0.0, 'size_download' => 0.0, 'speed_download' => 0.0, 'speed_upload' => 0.0, 'download_content_length' => -1.0, 'upload_content_length' => -1.0, 'starttransfer_time' => 0.0, 'redirect_time' => 0.0, 'redirect_url' => '', 'primary_ip' => '', 'certinfo' => array ( ), 'primary_port' => 0, 'local_ip' => '', 'local_port' => 0, )error occured during curl exec. Additioanl info:
Probably a firewall issue
cURL uses port 1080 which is probably not open
Several fixes:
Open port 1080 in your firewall/router
or
Specify a (working) port for cURL
curl_setopt($curl, CURLOPT_PORT, PortYouWantHere)
curl is not working because my organisation's proxy is blocking the request. So I have added the below code and it worked like charm :)
curl_setopt($ch, CURLOPT_PROXY, $proxyhostandpass);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyusernamepass);

Pushover cURL-code gives error

I have this code:
curl_setopt_array($ch = curl_init(), array(
CURLOPT_URL => "https://api.pushover.net/1/messages.json",
CURLOPT_POSTFIELDS => array(
"token" => "XXX",
"user" => "XXX",
"message" => $msg,
),
CURLOPT_SAFE_UPLOAD => true,
));
curl_exec($ch);
curl_close($ch);
But is gives me this error:
Array keys must be CURLOPT constants or equivalent integer values in /etc/noiphp/run.php on line 73
Any ideas?
cURL-version info:
curl 7.29.0 (mips-openwrt-linux-gnu) libcurl/7.29.0 OpenSSL/1.0.1h zlib/1.2.7
Protocols: file ftp ftps http https imap imaps pop3 pop3s rtsp smtp smtps tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
CURLOPT_SAFE_UPLOAD is only supported on PHP >= 5.5.0, remove that option and you should be good to go, also, it wasn't an error, just a warning.
curl_setopt_array($ch = curl_init(), array(
CURLOPT_URL => "https://api.pushover.net/1/messages.json",
CURLOPT_POSTFIELDS => array(
"token" => "XXX",
"user" => "XXX",
"message" => $msg,
)
));
curl_exec($ch);
curl_close($ch);
CURLOPT_SAFE_UPLOAD
TRUE to disable support for the # prefix for uploading files in
CURLOPT_POSTFIELDS, which means that values starting with # can be
safely passed as fields. CURLFile may be used for uploads instead.
Added on PHP 5.5.0 with FALSE as the default value. PHP 5.6.0 changes the
default value to TRUE.
http://php.net/manual/en/function.curl-setopt.php

curl not working on certain networks

I seem to be facing a weird problem. I have a PHP script in laptop (running under wamp) which uses 'curl' and works perfectly fine at work. But when at home and connected to my ISP, the same
script fails to return any data. Even a sample code like below fails:
$ch = curl_init("http://www.yahoo.com/");
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
var_dump(curl_getinfo($ch));
curl_getinfo dows not provide any clues to further debug. The HTTP CODE is zero. Do I need to add any headers>
I am able to access example.com through the browser, so no network issues I guess. curl_err and curl_errno is null.
<pre>
array (size=22)
'url' => string 'http://www.example.com/' (length=23)
'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
'namelookup_time' => float 0
'connect_time' => float 0
'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
'certinfo' =>
array (size=0)
empty
'redirect_url' => string '' (length=0)
</pre>
null
null
After thinking this through I think this is what you should do:
Ensure you can connect to the site from PHP:
<?php
$urlNoHttp = 'www.example.com'; // try 'example.com', too
$hostIP = gethostbyname($urlNoHttp);
var_dump($hostIP);
If it does not get the IP you have connection issues, so proceed to point 2.
Otherwise - it's not the network issues, it's curl setting itself - try point 3 and following.
Try pinging/wget'ting your destination from command line (ping www.example.com). If you get responses - your host is reachable for your OS and not the PHP, so
If you got the IP - then try reading about curl_setopt() int PHP docs. I'd start with setting proper HTTP headers (like Content-type, User-Agent, non-empty body to the request etc.). Also, try adding curl_setopt($c, CURLOPT_FRESH_CONNECT, 1); which forces not using a cached version of the url.
If it's still not working - try mixing in some proxy options, like curl_setopt($c, CURLOPT_HTTPPROXYTUNNEL, TRUE); to force "transparcence" of proxies, if there are any.
Generally you have to figure out what changes when you switch network environments. You have to know if there are any proxies involved, some strange NAT systems or maybe your router's firewall has some strange settings, that assume this kind of request as insecure and block it.
Hope this helps.

Unable to make php curl request with port number

I am unable to make a php curl request with port number , without port number i am getting response properly.
Through terminal when i do curl http://www.sample.com:8088 i am getting response back properly. But not through php curl on doing curl_inf()
i am getting
Array ( [url] => http://www.sample.com:8088/ [content_type] => [http_code] => 0 [header_size] => 0 [request_size] => 0 [filetime] => 0 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0 [namelookup_time] => 0 [connect_time] => 0 [pretransfer_time] => 0 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => -1 [upload_content_length] => -1 [starttransfer_time] => 0 [redirect_time] => 0 [certinfo] => Array ( ) )
My code
$url = "http://www.sample.com:8088/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_TIMEOUT, 400);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, True);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, True);
$report=curl_getinfo($ch);
print_r($report);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
this code give me response from ubuntu , but not giving response from cent os if port number is specified.
Please let me know the how to fix it.
THanks in advance.
Try to set the port like this:
curl_setopt($ch, CURLOPT_PORT, $_SERVER['SERVER_PORT']);
or:
curl_setopt($ch, CURLOPT_PORT, 8088);
Try to set
curl_setopt($ch,CURLOPT_PORT, 8088);
See more info http://php.net/manual/en/function.curl-setopt.php
Add
curl_setopt($ch, CURLOPT_PORT, 8088);
Curl_setopt reference
"setsebool httpd_can_network_connect on" resolves the problem for me
Make sure that the port 8080 is enabled in Cent OS
and try this curl_setopt($ch, CURLOPT_PORT, 8088);
I went to server admin with this problem and he changed configuration in centos
in folder /etc/sysconfig/
he edited file selinux and change SELINUX=disabled and restated it.
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
and my problem got solved.

Categories