Ok, I've got a Drupal site which I'm deploying on Azure. My App perform an API call to Marketo to trigger an action in Marketo's API.
On my local dev and on a Debian server (regular lamp stack) all works fine.
When I deploy the site to Azure, it doesn't work and all I get is NULL
.
Here's my code:
public function postData(){
$url = $this->host . "/rest/v1/campaigns/" . $this->id . "/schedule.json?access_token=" . $this->getToken();
$ch = curl_init($url);
$requestBody = $this->bodyBuilder();
print_r($requestBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('accept: application/json','Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_getinfo($ch);
$response = curl_exec($ch);
dvm($response, $name = NULL);
return $response;
}
private function getToken(){
$ch = curl_init($this->host . "/identity/oauth/token?grant_type=client_credentials&client_id=" . $this->clientId . "&client_secret=" . $this->clientSecret);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('accept: application/json',));
curl_setopt($ch, CURLOPT_VERBOSE, true);
$response = json_decode(curl_exec($ch));
curl_close($ch);
$token = $response->access_token;
dvm($response, $name = NULL);
return $token;
}
Please note:
There are 2 calls: one to get the access_token and another the actual trigger.
dvm($response, $name = NULL);
in simplistic terms is a Drupal equivalent to print_r
This exact same code works on my local machine (OS X, Apache, PHP5.6) and on Debian (Apache, PHP 5.6).
I'm using SQLite which is not exactly relevant but I though I should add just in case.
When I execute this code locally or on the Debian server I get the $result
variable printed which tells me whether it was successful or not. On Azure I get just NULL
for the first FALSE
to the second.
The variables ($this->id
, $this->getToken()
, etc) are correctly set and I can I print them fine. Like I said, all works locally.
What am I missing?
Default settings on Azure has CURLOPT_SSL_VERIFYPEER set equal to TRUE. If you dont have an SSL there could be an issue.
The following was taken from a post on MSDN (http://blogs.msdn.com/b/azureossds/archive/2015/06/12/verify-peer-certificate-from-php-curl-for-azure-apps.aspx)
Common error messages related to SSL_VERIFYPEER option could be:
SSL certificate problem, verify that the CA cert is OK SSL certificate problem: unable to get local issuer certificate
The error is usually caused by missing or having invalid SSL certificate in cURL option. If you see these messages, consider to validate SSL certificate, and check the path to CA certificate file. CA certificate must be in PEM format, for more detail about CA extract, visit http://curl.haxx.se/docs/caextract.html
Do not turn off CURLOPT_SSL_VERIFYPEER unless your cURL connect to non certificate protected server.
There are two ways that you can specify certificate info for cURL in PHP environment.
Specify CURLOPT_CAINFO in cURL option: (sample code)
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "\cert\ca-bundle.crt");
Note: getcwd() . "\cert\ca-bundle.crt" returns absolute path of your ca-bundle.crt. Make sure ca-bundle is installed at correct path.
Set curl.cainfo in php.ini
In php.ini file, find [curl] section, add this directive (sample code):
curl.cainfo ="D:\home\site\wwwroot\cert\ca-bundle.crt"
Note: Restart you web app after the change.
“curl.cainfo” is system level directive which has to be set in php.ini, not in .user.ini. To use this approach, need to have customer php.ini.
Refer to the link to setup customer php.ini, https://github.com/projectkudu/kudu/wiki/Xdt-transform-samples#using-a-custom-phpini
CURLOPT_SSL_VERIFYHOST option is used along with verify peer, default value of this option is 2, to check the existence of a common name and also verify that it matches the hostname provided (more detail at http://php.net/manual/en/function.curl-setopt.php)