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
Related
When I try to send a cURL request, I get the following error:
* SSL certificate verify ok.
> * SSL_write() error: error:1409F07F:SSL routines:ssl3_write_pending:bad write retry
* Closing connection 0
this is the request I am sending:
$url = 'https://example.com/services/service-name';
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postData,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2,
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $fp,
));
$response = curl_exec($curl);
Sometimes it works, but other times it gives me the SSL error "Curl Error Number 55".
Curl version: 7.84.0
SSL version: OpenSSL/1.1.1p
On localhost, it works all the time, but on production server "Linux" it keeps giving me the SSL error. Any help is greatly appreciated
After trying everything I know, the problem was related to DNS using IPv6 instead of IPv4. I forced the cURL request to use IPv4 and haven't received any error since
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
I appreciate this has been asked a number of times but after looking through the answers I'm still getting the following error:
Curl error: Peer certificate cannot be authenticated with known CA certificates
I have the below code, which works on a non-https version of the site (different server), however, it won't work on the live site running https. My assumption is that it's trying to verify against the SSL certificate on the site, rather than the .pem file specified in $cert_path.
I'll be honest, I'm a bit confused between SSLCERT and the CAINFO however I have added the following to my php.ini file and checked to make sure they're set correctly, which they are.
// php.ini
curl.cainfo = "/path/to/.pem";
openssl.cafile = "/path/to/.pem";
As I said before, the following works on the stage version of the site, just not the live one. Any help would be greatly appreciated.
// php curl snippet
$cert_path = '/path/to/.pem';
$options = array(
CURLOPT_SSL_VERIFYHOST => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSLCERT => $cert_path,
CURLOPT_SSLCERTPASSWD => $password,
CURLOPT_CAINFO => $cert_path,
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $xml_post_string,
CURLOPT_HTTPHEADER => $headers
);
curl_setopt_array( $ch, $options );
If I set VERIFYPEER to false it does connect but my assumption is that this wouldn't be passing the data securely?
Thank you.
I've managed to get this working however there are a few things to note which may help someone in the future.
The site was hosted with 123reg and I was informed by their support that third-party SSL certificates are not accepted. Although I was told this ultimately my code below did work.
I regenerated my .pem file so this too could have worked in my favour.
My final code as as follows: I also stripped out the php.ini code entirely.
// These two variables will differ depending on your payload for Curl
$xml_post_string = '...';
$headers = array();
// This will differ based on your endpoint
$url = 'endpoint.url';
$password = 'password';
$cert_path = '/path/to/.pem';
$ch = curl_init();
$options = array(
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSLCERT => $cert_path,
CURLOPT_SSLCERTTYPE => "PEM",
CURLOPT_SSLCERTPASSWD => $password,
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $xml_post_string,
CURLOPT_HTTPHEADER => $headers
);
curl_setopt_array( $ch, $options );
$response = curl_exec($ch);
curl_close($ch);
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.
I am working with Rightmove and their realtime data feed, we received a (self-signed?) certificate (.p12 file) that we had to insert into our browser/PC to connect to the testserver, this is all working great.
Now we are writing our own script, and connecting to the test server via CURL, however we are loading this script from our server and it does not have access to the test server (handshake failed - authentication, after research looks like it is expecting certificate which makes sense), but how do we get access? They are not of great help and I am wondering if we need to add this certificate to our domain/server as well to gain authentication?
Hope you can help!
You would use the CURLOPT_SSLCERT & CURLOPT_SSLCERTPASSWD options with your CURL command. e.g
$url = "https://www.example.com";
$cert_file = 'certificate_file.pem';
$cert_password = 'password';
$ch = curl_init();
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => 'Useragent',
CURLOPT_URL => $url ,
CURLOPT_SSLCERT => $cert_file ,
CURLOPT_SSLCERTPASSWD => $cert_password ,
);
curl_setopt_array($ch , $options);
$output = curl_exec($ch);
I'm building a personal stock platform (not distributed). A component I would like to have is the EPS graph on this page:
https://eresearch.fidelity.com/eresearch/evaluate/fundamentals/earnings.jhtml?stockspage=earnings&symbols=AAPL&showPriceLine=yes
As you can see, the page is https, so after days of hammering things out, I enabled openssl and now it seems to work for all https pages such as the homepages of facebook and twitter, however it is still not working for the one I need.
file_get_contents('https://facebook.com'); /* works */
file_get_contents('https://twittercom'); /* works */
file_get_contents('https://eresearch.fidelity.com/eresearch/evaluate/fundamentals/earnings.jhtml?stockspage=earnings&symbols=AAPL&showPriceLine=yes');
I'm getting the warning:
Warning: file_get_contents(): SSL: crypto enabling timeout in C:\xampp\htdocs\index.php on line 3
Warning: file_get_contents(): Failed to enable crypto in C:\xampp\htdocs\index.php on line 3
Warning: file_get_contents(https://eresearch.fidelity.com/eresearch/evaluate/fundamentals/earnings.jhtml?stockspage=earnings&symbols=AAPL&showPriceLine=yes): failed to open stream: operation failed in C:\xampp\htdocs\index.php on line 3
Fatal error: Maximum execution time of 30 seconds exceeded in C:\xampp\htdocs\index.php on line 3
The only difference I can see is that the fidelity page has a triangle near the https label.
Ok I have found a solution. The problem is that the site uses SSLv3. And I know that there are some problems in the openssl module. Some time ago I had the same problem with the SSL versions.
<?php
function getSSLPage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSLVERSION,3);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
var_dump(getSSLPage("https://eresearch.fidelity.com/eresearch/evaluate/analystsOpinionsReport.jhtml?symbols=api"));
?>
When you set the SSL Version with curl to v3 then it works.
Edit:
Another problem under Windows is that you don't have access to the certificates. So put the root certificates directly to curl.
http://curl.haxx.se/docs/caextract.html
here you can download the root certificates.
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/certs/cacert.pem");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
Then you can use the CURLOPT_SSL_VERIFYPEER option with true otherwise you get an error.
Had same problem - it was somewhere in the ca certificate, so I used the ca bundle used for curl, and it worked. You can download the curl ca bundle here: https://curl.haxx.se/docs/caextract.html
For encryption and security issues see this helpful article:
https://www.venditan.com/labs/2014/06/26/ssl-and-php-streams-part-1-you-are-doing-it-wrongtm/432
Here is the example:
$url = 'https://www.example.com/api/list';
$cn_match = 'www.example.com';
$data = array (
'apikey' => '[example api key here]',
'limit' => intval($limit),
'offset' => intval($offset)
);
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
, 'ssl' => array(
'verify_peer' => true,
'cafile' => [path to file] . "cacert.pem",
'ciphers' => 'HIGH:TLSv1.2:TLSv1.1:TLSv1.0:!SSLv3:!SSLv2',
'CN_match' => $cn_match,
'disable_compression' => true,
)
);
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
Hope that helps
A workaround that works for me is to disable peer verification. Be careful when you use it because it shouldn't be use in production.
$arrContextOptions = array(
"ssl" => array(
"verify_peer" => false,
"verify_peer_name" => false,
)
);
$context = stream_context_create($arrContextOptions);
$contents = file_get_contents($url,false,$context);