All CURL functions returns null in php - php

php5-curl is installed but curl_exec() returns null, curl_errno() returns 0, curl_error() returns null, curl_getinfo() looks like curl_exec() never fired.
Sample of code
$this->curl = curl_init();
$agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0';
$curlOptions = array(
CURLOPT_URL=>str_replace(' ', '%20', $url),
CURLOPT_RETURNTRANSFER=>true,
CURLOPT_USERAGENT=>$agent,
CURLOPT_BINARYTRANSFER=>true,
CURLOPT_CUSTOMREQUEST=>"GET",
CURLOPT_AUTOREFERER=>true,
CURLOPT_CONNECTTIMEOUT=>5,
CURLOPT_TIMEOUT=>600,
CURLOPT_FOLLOWLOCATION=>true,
CURLOPT_MAXREDIRS=>20,
CURLOPT_SSL_VERIFYPEER=>false
);
curl_setopt_array($this->curl, $curlOptions);
$result = curl_exec($this->curl);
$status = curl_getinfo($this->curl);
$this->log->ToLog('HTTP error on downloading ' .$url.' ; error = ' . curl_errno($this->curl) . " => ". curl_error($this->curl) . ' ; status = '. json_encode($status) , 'info');
In log I can see
HTTP error on downloading https://cdn-a.verkkokauppa.com/576/images/83/2_175586-1250x758.jpeg ; error = 0 => ; status = {"url":"https://cdn-a.verkkokauppa.com/576/images/83/2_175586-1250x758.jpeg","content_type":null,"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,"redirect_url":"","primary_ip":"","certinfo":[],"primary_port":0,"local_ip":"","local_port":0}
But file_get_contents() works fine in this case. What happened? How can I fix it?

Related

2 JSON. Only 1 work. json_decode php

I seriously got gray hair.
I would like to echo the [ask] data for https://api.gdax.com/products/btc-usd/ticker/
But it's return null.
When i try with to use another API with almost the same json, it work perfect.
This example works
<?php
$url = "https://api.bitfinex.com/v1/ticker/btcusd";
$json = json_decode(file_get_contents($url), true);
$ask = $json["ask"];
echo $ask;
This example return null
<?php
$url = "https://api.gdax.com/products/btc-usd/ticker/";
$json = json_decode(file_get_contents($url), true);
$ask = $json["ask"];
echo $ask;
Anybody there has an good explanation, whats wrong with the code returning null
the server of that null result is preventing php agent to connect thus returning http 400 error. you need to specify a user_agent value to your http request.
e.g.
$ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36';
$options = array('http' => array('user_agent' => $ua));
$context = stream_context_create($options);
$url = "https://api.gdax.com/products/btc-usd/ticker/";
$json = json_decode(file_get_contents($url, false, $context), true);
$ask = $json["ask"];
echo $ask;
you can also use any user_agent string you want on the $ua variable, as long as you make sure that your target server allows it.
You can't access this URL without passing arguments. It happen some time when the host is checking from where the request come.
$ch = curl_init();
$header=array('GET products/btc-usd/ticker/ HTTP/1.1',
'Host: api.gdax.com',
'Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language:en-US,en;q=0.8',
'Cache-Control:max-age=0',
'Connection:keep-alive',
'Host:adfoc.us',
'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36',
);
curl_setopt($ch,CURLOPT_URL,"https://api.gdax.com/products/btc-usd/ticker/");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,0);
curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
$result=curl_exec($ch);
Then you can use json_decode() on $result !

powershell -Certificate on php

Hello I have this powershell working:
$dnsname = "xxx.yyy.cat"
$cert = get-childitem -path cert:\currentuser\My\* | where Subject -eq "CN=$($dnsname)"
$subscriptionID = "25b92657-61a3-4dd1-bada-xxxxxxxxxxxx"
$url = "https://tenantpublicapi.xxxxx.cat"
$webspacename = "defaultwebspace"
$websitename = xxxxx
$webrequest = [string]::Format('{0}/{1}/services/webspaces/{2}/sites/{3}',$url,$subscriptionID,$webspacename,$websitename)
(curl -Uri $webrequest -Certificate $Cert -Method Get).content
I need to do this with php but i cant make de curl call work with certificate:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_SSL_VERIFYPEER=>true,
CURLOPT_SSL_VERIFYHOST=> 2,
CURLOPT_CAINFO=> getcwd() . "/xxxx.xxxx.cat.crt",
CURLOPT_SSLKEY=> getcwd() . "/xxxx.xxxx.cat.key",
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_USERAGENT=> 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2',
CURLOPT_URL => 'https://tenantpublicapi.xxxxxxx.cat/25b92657-61a3-4dd1-bada-xxxxxx/services/webspaces/defaultwebspace/sites',));
$resp = curl_exec($curl);
curl_close($curl);
print_r($resp);
Any idea on what I'm missing?

Shopware REST Api - Invalid or missing auth

I'm trying to access the REST api of Shopware. I'm using version 5.1.3 of Shopware. I'm using the code of the documentation.
I always get a http code 400 (Invalid or missing auth) back.
When I try to access the API via Google Chrome it works after login with http authentication, so the credentials should be OK.
I guess the Authentication header Chrome sends differs from the one I send with PHP curl.
With Chrome:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
Authorization:Digest username="demo", realm="Shopware REST-API", nonce="7aa6aa7e8089c60e5930cb45ead39197", uri="/api/articles", algorithm=MD5, response="cee77e425508605dfbcf2deda8f83938", opaque="d75db7b160fe72d1346d2bd1f67bfd10", qop=auth, nc=0000001e, cnonce="8b5121e862c4fce1"
Cache-Control:max-age=0
Connection:keep-alive
Cookie:session-1=2d0cb2941684d2767e76ffeb48c7337706cba39c
Host:shopware.example.com
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
With PHP Curl
GET /api/articles? HTTP/1.1\r\n
Host: shopware.example.com\r\n
Authorization: Digest username="demo",realm="",nonce="806c9770a53bf2f82b87734a9d8eb98c",uri="/api/articles?",cnonce="60e6c8db046db8f4e63fece37e38f92e",nc=00000001,algorithm=MD5,response="299069d4659af386a4ec7058796267c2",qop="auth",opaque="d75db7b160fe72d1346d2bd1f67bfd10"\r\n
User-Agent: Shopware shopwareApiClient\r\n
Accept: */*\r\n
Content-Type: application/json; charset=utf-8\r\n
Content-Length: 2\r\n
Extra PHP curl directives to get header information:
curl_setopt($this->cURL, CURLINFO_HEADER_OUT, true);
print_r(curl_getinfo($this->cURL, CURLINFO_HEADER_OUT ));
The code I use:
<?php
namespace App;
class shopwareApiClient
{
const METHOD_GET = 'GET';
const METHOD_PUT = 'PUT';
const METHOD_POST = 'POST';
const METHOD_DELETE = 'DELETE';
protected $validMethods = array(
self::METHOD_GET,
self::METHOD_PUT,
self::METHOD_POST,
self::METHOD_DELETE
);
protected $apiUrl;
protected $cURL;
public function __construct($apiUrl, $username, $apiKey)
{
$this->apiUrl = rtrim($apiUrl, '/') . '/';
//Initializes the cURL instance
$this->cURL = curl_init();
curl_setopt($this->cURL, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->cURL, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($this->cURL, CURLOPT_USERAGENT, 'Shopware shopwareApiClient');
curl_setopt($this->cURL, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_setopt($this->cURL, CURLOPT_USERPWD, $username . ':' . $apiKey);
curl_setopt($this->cURL, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=utf-8',
));
curl_setopt($this->cURL, CURLINFO_HEADER_OUT, true);
}
public function call($url, $method = self::METHOD_GET, $data = array(), $params = array())
{
if (!in_array($method, $this->validMethods))
{
throw new Exception('Invalid HTTP-Methode: ' . $method);
}
$queryString = '';
if (!empty($params))
{
$queryString = http_build_query($params);
}
$url = rtrim($url, '?') . '?';
$url = $this->apiUrl . $url . $queryString;
$dataString = json_encode($data);
curl_setopt($this->cURL, CURLOPT_URL, $url);
curl_setopt($this->cURL, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($this->cURL, CURLOPT_POSTFIELDS, $dataString);
$result = curl_exec($this->cURL);
dd(curl_getinfo($this->cURL, CURLINFO_HEADER_OUT ));
$httpCode = curl_getinfo($this->cURL, CURLINFO_HTTP_CODE);
return $this->prepareResponse($result, $httpCode);
}
public function get($url, $params = array())
{
return $this->call($url, self::METHOD_GET, array(), $params);
}
public function post($url, $data = array(), $params = array())
{
return $this->call($url, self::METHOD_POST, $data, $params);
}
public function put($url, $data = array(), $params = array())
{
return $this->call($url, self::METHOD_PUT, $data, $params);
}
public function delete($url, $params = array())
{
return $this->call($url, self::METHOD_DELETE, array(), $params);
}
protected function prepareResponse($result, $httpCode)
{
echo "<h2>HTTP: $httpCode</h2>";
if (null === $decodedResult = json_decode($result, true))
{
$jsonErrors = array(
JSON_ERROR_NONE => 'No error occurred',
JSON_ERROR_DEPTH => 'The maximum stack depth has been reached',
JSON_ERROR_CTRL_CHAR => 'Control character issue, maybe wrong encoded',
JSON_ERROR_SYNTAX => 'Syntaxerror',
);
echo "<h2>Could not decode json</h2>";
echo "json_last_error: " . $jsonErrors[json_last_error()];
echo "<br>Raw:<br>";
echo "<pre>" . print_r($result, true) . "</pre>";
return;
}
if (!isset($decodedResult['success']))
{
echo "Invalid Response";
return;
}
if (!$decodedResult['success'])
{
echo "<h2>No Success</h2>";
echo "<p>" . $decodedResult['message'] . "</p>";
return;
}
echo "<h2>Success</h2>";
if (isset($decodedResult['data']))
{
echo "<pre>" . print_r($decodedResult['data'], true) . "</pre>";
}
return $decodedResult;
}
}
Edit: Found a php bug report which states there is a bug in PHP with Windows on version 5.6 and above. I'm using XAMP on Windows. I'm going to try it on linux to see if it does work.
The bug report was correct. I was using XAMP with PHP 5.6 on Windows.
After putting my PHP code on a linux machine, the code works.
Quote bug report:
[2015-07-19 09:51 UTC] roeycohen at gmail dot com
Description:
trying to use curl_exec with digest authentication does not work properly.
running the test script always fails to pass the security challenge.
using the browser or wget directly works perfectly.
also, trying to run the same test on another server of mine, works from an amazon linux with php 5.5.21 but does not work from my windows 7 x64 machine with php 5.6.11.
trying to run the test with php 5.5 or 5.4 using CLI on several windows machines caused a complete crush of the php executable.
it seems like bug #69088 is related, but this bug also happens on linux (5.5).
Test script:
<?
$curl = curl_init();
$curl_options = [
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_USERPWD => 'test_user:password',
CURLOPT_URL => 'http://test_user:password#httpbin.org/digest-auth/auth/user/password',
CURLOPT_HEADER => true,
];
curl_setopt_array($curl, $curl_options);
curl_exec($curl);
curl_close($curl);
Expected result:
{
"authenticated": true,
"user": "user"
}
Actual result:
"Authentication failed" (with header 401)
[2015-12-28 16:33 UTC] gohel at basicguru dot de
I have the same problem with PHP-clients/scripts and the CalDAV/SabreDAV-framework (also included in Owncloud, Baikal, etc.) on my Apache 2.4.17 (Win32/VC11 from Apachelounge on Win7/64).
I've played a little bit with different versions of the PHP 5.6.x releases and found the following:
php_curl.dll <= v5.6.4 - no problems
php_curl.dll v5.6.5/v5.6.6 - crash with Auth_Digest
php_curl.dll => v5.6.7 - Auth_Digest failed
The bug is also in the PHP 5.5 release and PHP 5.4 (last stable PHP_CURL.DLL I've found in v5.4.36)

PHP CURL 412 error

I'm triying to register on a website using PHP CURL. Everything is okay, but when I execute my code I get an error from the host:
HTTP/1.1 412 Precondition Failed
Date: Mon, 15 Feb 2016 20:54:58 GMT
Server: Varnish
X-Varnish: 317635174
Content-Length: 0
Array ( [header] => 1 [body] => [res] => 1 )
After doing some research on this website, I've found this:
If you look at RFC 2616 you'll see a number of request headers that
can be used to apply conditions to a request:
If-Match If-Modified-Since If-None-Match If-Range If-Unmodified-Since
These headers contain 'preconditions', allowing the client to tell the
server to only complete the request if certain conditions are met. For
example, you use a PUT request to update the state of a resource, but
you only want the PUT to be actioned if the resource has not been
modified by someone else since your most recent GET.
The response status code 412 (Precondition Failed) is typically used
when these preconditions fail.
(source: When is it appropriate to respond with a HTTP 412 error?)
So I've added these headers
<?php
function register() {
$curl = curl_init();
$post = "name=username&email=".urlencode("email#email.com")."&password=thepassword&repassword=thepassword&parrain=test";
$useragent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36';
curl_setopt($curl, CURLOPT_URL, '[the website]');
curl_setopt($curl, CURLOPT_POST, "5");
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Connection: keep-alive",
"Content-Length: 43",
"Cache-Control: max-age=0",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Upgrade-Insecure-Requests: 1",
"Content-Type: application/x-www-form-urlencoded",
"Accept-Encoding: gzip, deflate",
"Accept-Language: fr,fr-FR;q=0.8,en;q=0.6,en-US;q=0.",
"If-Match: 1",
"If-Modified-Since: 1",
"If-None-Match: 1",
"If-Range: 1",
"If-Unmodified-Since: 1"
));
curl_setopt($curl, CURLOPT_HEADER, true);
$result = curl_exec($curl);
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$header = substr($result, 0, $header_size);
$body = substr($result, $header_size);
curl_close($curl);
return array(
"header" => $header,
"body" => $body,
"res" => $result
);
}
print_r(register());
?>
but It doesn't work. How can I solve it?
Generally, if you're interacting with a website that does authentication, you will need the cookiejar parameters for cURL to save session info. If you don't send session info back to the host it will most likely cause problems with your registration.
Here's a class I use to authenticate users remotely via cURL.
/* Makes an HTTP request
* #param String $url - The URL to request
* #param Mixed $params - string or array to POST
* #param String - filename to download
*/
public static function request($url, $params = array(), $filename = "") {
// Initiate cURL
$ch = curl_init();
$curlOpts = array(
CURLOPT_URL => $url,
CURLOPT_USERAGENT =>
'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true
);
// Send the cookies if we're logged in
if (!empty(self::$cookiejar)) {
$curlOpts[CURLOPT_COOKIEJAR] = self::$cookiejar;
$curlOpts[CURLOPT_COOKIEFILE] = self::$cookiejar;
}
// If $filename exists, save content to file
if (!empty($filename)) {
$file2 = fopen($filename, 'w+') or die("Error[" . __FILE__ . ":" . __LINE__ . "] Could not open file: $filename");
$curlOpts[CURLOPT_FILE] = $file2;
}
// Send POST values if there are any
if (!empty($params)) {
$curlOpts[CURLOPT_POST] = true;
$curlOpts[CURLOPT_POSTFIELDS] = is_array($params) ?
http_build_query($params) : $params;
}
// Send the request
curl_setopt_array($ch, $curlOpts);
$answer = curl_exec($ch);
// Errors?
if (curl_error($ch)) die($url . " || " . curl_error($ch));
// Close connection and return response
curl_close($ch);
if(!empty($filename)) fclose($file2);
return $answer;
}
1: curl_setopt($ch, CURLOPT_HTTPHEADER, array());
needs $curl instead of $ch.
2: curl_setopt($curl, CURLOPT_POST, "5");
doesn't expect 5, it needs TRUE or FALSE, see curlopt_post (php.net).
2.1: CURLOPT_FOLLOWLOCATION also expects TRUE or FALSE.
Edit: My mistake, 1 and 0 are booleans too

Curl - Request with wp_remote_get() responds 500, curl_exec responds 200

I am getting an odd server php curl error in both my local and production servers (Ubuntu 14.04.2 LTS, PHP 5.5.9-1ubuntu4.11, Apache 2.4.7).
Basically, a curl request to a remote API returns a status code 500 response, ONLY in wp_remote_get(), where it returns status 200 in both curl_exec() and a browser request.
My debug code:
<?php
$url = 'https://yoast.com?edd_action=activate_license&license=my-license-key-here&item_name=WooCommerce+Yoast+SEO&url=https://google.com';
// this return status 200:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
echo '<pre>' . print_r($result, true) . '</pre>';
// this return status 500:
$testResp = wp_remote_get($url);
echo '<pre>' . print_r($testResp, true) . '</pre>';
I cannot figure out why it responds 500 for wp_remote_get(). I've tried adjusting args passed to wp_remote_get(), but still a 500 with it.
I've also disabled all plugins in debugging.
Any Ideas?
OK, after a bit of debugging, I believe the issue is the default User-Agent string Wordpress sets in wp-includes/class-http.php, set when creating an http request for wp_remote_get().
The option has a filter, but the default is created like so:
'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) ),
So in my case, the 'user-agent' header value was: "Wordpress/4.3.1; http://myurl.com"
When I hook into the filter http_headers_useragent and return an empty string, or even a different user-agent string such as: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8) AppleWebKit/535.6.2 (KHTML, like Gecko) Version/5.2 Safari/535.6.2', the request will return a successful 200 response.
Not sure if the semicolon is the true culprit, but if I remove it and set the user-agent string to just "Wordpress/4.3.1", the request is successful as well.
I had the same problems - wp_remote_get was not working while the classic Curl calls were making the calls. Indeed the problem is on 'user agent' . This is my solution based on "chuuke" findings
$args = array(
'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8) AppleWebKit/535.6.2 (KHTML, like Gecko) Version/5.2 Safari/535.6.2',
);
$data = wp_remote_get($new_url_signed,$args);
Thanks

Categories