Development Guides Home >> Quickstart Development Guide
This tutorial creates custom code to call UAPI's SSL::install_ssl function.
Due to their inherent complexities, SSL-related functions often present problems for third-party developers. This tutorial provides explanations for the additional steps required in order to successfully call SSL functions.
These declarations instruct Perl to return errors if the file contains potentially-unsafe code. You can omit the warnings declaration in production code, but we strongly recommend that you use it during development.
# Return errors if Perl experiences problems.
use strict;
use warnings;We recommend that you set a dependency for one or more modules that allow you to perform web requests.
- This tutorial uses the
LWP::UserAgentandLWP::Protocol::httpsmodules. - The
HTTP::Tinymodule also fulfills this need.
# Allow my code to perform web requests.
use LWP::UserAgent;
use LWP::Protocol::https;You must use UTF-8 encoding when you call UAPI functions. If you do not use the correct encoding, your code may result in wide character warnings.
# Use the correct encoding to prevent wide character warnings.
use Encode;
use utf8;Declare the use of JSON formatting, to ensure that your code can properly decode JSON.
# Properly decode JSON.
use JSON;Declare the use of the MIME::Base64 module, which ensures that your code properly interacts with Base64-encoded authentication headers.
# Function properly with Base64 authentication headers.
use MIME::Base64;Declare the variables for your cPanel account username and password in order to allow your code to authenticate with cPanel & WHM.
# Authentication information.
my $username = 'username';
my $password = '12345luggage';Set the $request variable to the URL for the desired API call.
# The URL for the SSL::install_ssl UAPI function.
my $request = "https://localhost:2083/execute/SSL/install_ssl";Set the PERL_LWP_SSL_VERIFY_HOSTNAME environment variable to 0 to allow HTTPS connections to unsigned services.
You must include this step in your code. Services on the local host are always unsigned.
# Required to allow HTTPS connections to unsigned services.
# Services on localhost are always unsigned.
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;Use the LWP::UserAgent module's new() method to create a new UserAgent object to use for the API call.
# Create a useragent object.
my $ua = LWP::UserAgent->new();Use the new UserAgent object to set up authentication headers that use the $username and $password values.
# Add authentication headers.
$ua->default_header(
'Authorization' => 'Basic ' . MIME::Base64::encode("$username:$password"),
);Declare variables and set values for the SSL certificate and key files. You must URI-encode the cert and key parameters' values.
# Read in the SSL certificate and key file.
my ( $cert, $key );
{
local $/;
open ( my $fh, '<', '/path/to/certificate.crt' );
$cert = <$fh>;
close $fh;
open ( $fh, '<', '/path/to/key.key' );
$key = <$fh>;
close $key;
};Create a POST request that includes the function's required input parameters. The $response variable will contain the call's output.
# Make the call.
my $response = $ua->post($request,
Content_Type => 'form-data',
Content => [
domain => 'example.com',
cert => $cert,
key => $key,
],
);Create an object to decode the call's JSON-formatted output. You will use this object to sort and pretty-print the JSON.
# Create an object to decode the JSON.
# Sorted by keys and pretty-printed.
my $json_printer = JSON->new->pretty->canonical(1);Use the Encode module to UTF-8 encode the call's output in the $response variable. Then, use the JSON module to decode the output. If you do not UTF-8 encode this output, you may receive wide character warnings.
# UTF-8 encode before decoding to avoid wide character warnings.
my $content = JSON::decode_json(Encode::encode_utf8($response->decoded_content));Use the object that line 65 created to pretty-print and sort the JSON output. Then, use the Encode module to UTF-8 encode the pretty-printed and sorted JSON, and print the final result. If you do not UTF-8 encode this output, you may receive wide character warnings.
# Print output, UTF-8 encoded to avoid wide character warnings.
print Encode::encode_utf8($json_printer->encode($content));Set error reporting to E_ALL in order to log all errors and warnings. You can omit this step in production code, but we strongly recommend its use during development.
// Log everything during development.
// If you run this on the CLI, set 'display_errors = On' in php.ini.
error_reporting(E_ALL);Declare the variables for your cPanel account username and password in order to allow your code to authenticate with cPanel & WHM.
// Declare your username and password for authentication.
$username = 'example';
$password = 'luggage12345';Define the API host, and the URL for the desired API call.
// Define the API call.
$cpanel_host = 'localhost';
$request_uri = "https://$cpanel_host:2083/execute/SSL/install_ssl";Declare variables and set values for the SSL certificate and key files.
This example manually defines the filename and destination. You can also use functions or the $argv array to pass these values.
// Define the SSL certificate and key files.
$cert_file = realpath("/path/to/cert.crt");
$key_file = realpath("/path/to/key.key");Set up the payload to send to the server. This data includes the function's required input parameters. You must URI-encode the cert and key parameters' values.
// Set up the payload to send to the server.
$payload = array(
'domain' => "example.com",
'cert' => file_get_contents($cert_file),
'key' => file_get_contents($key_file)
);Set up a cURL request object that uses the specified $username and $password variables.
- Only use the
CURLOPT_SSL_VERIFYHOSTandCURLOPT_SSL_VERIFYPEERoptions with self-signed or expired certificates. localhostalways uses a self-signed certificate.
// Set up the cURL request object.
$ch = curl_init( $request_uri );
curl_setopt( $ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
curl_setopt( $ch, CURLOPT_USERPWD, $username . ':' . $password );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );Create a POST request that includes the function's required input parameters and uses the $payload variable from line 19.
// Set up a POST request with the payload.
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );Use the curl_exec() method to make the API call. Then, use the curl_close() method to close the cURL object that you created.
// Make the call, and then terminate the cURL caller object.
$curl_response = curl_exec( $ch );
curl_close( $ch );Use the json_decode() method to decode the $curl_response value, which contains the call's output. Then, validate that output.
- Lines 43 through 45 of the example below check to ensure that the call returned output.
- Lines 46 through 48 of the example below ensure that there were no errors.
// Decode and validate output.
$response = json_decode( $curl_response );
if( empty( $response ) ) {
echo "The cURL call did not return valid JSON:\n";
die( $response );
} elseif ( !$response->status ) {
echo "The cURL call returned valid JSON, but reported errors:\n";
die( $response->errors[0] . "\n" );
}Print the validated output and exit.
// Print and exit.
die( print_r( $response ) );When you finish this tutorial, your code will resemble the following examples.
#!/usr/local/cpanel/3rdparty/bin/perl
# Return errors if Perl experiences problems.
use strict;
use warnings;
# Allow my code to perform web requests.
use LWP::UserAgent;
use LWP::Protocol::https;
# Use the correct encoding to prevent wide character warnings.
use Encode;
use utf8;
# Properly decode JSON.
use JSON;
# Function properly with Base64 authentication headers.
use MIME::Base64;
# Authentication information.
my $username = 'username';
my $password = '12345luggage';
# The URL for the SSL::install_ssl UAPI function.
my $request = "https://localhost:2083/execute/SSL/install_ssl";
# Required to allow HTTPS connections to unsigned services.
# Services on localhost are always unsigned.
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
# Create a useragent object.
my $ua = LWP::UserAgent->new();
# Add authentication headers.
$ua->default_header(
'Authorization' => 'Basic ' . MIME::Base64::encode("$username:$password"),
);
# Read in the SSL certificate and key file.
my ( $cert, $key );
{
local $/;
open ( my $fh, '<', '/path/to/certificate.crt' );
$cert = <$fh>;
close $fh;
open ( $fh, '<', '/path/to/key.key' );
$key = <$fh>;
close $key;
};
# Make the call.
my $response = $ua->post($request,
Content_Type => 'form-data',
Content => [
domain => 'example.com',
cert => $cert,
key => $key,
],
);
# Create an object to decode the JSON.
# Sorted by keys and pretty-printed.
my $json_printer = JSON->new->pretty->canonical(1);
# UTF-8 encode before decoding to avoid wide character warnings.
my $content = JSON::decode_json(Encode::encode_utf8($response->decoded_content));
# Print output, UTF-8 encoded to avoid wide character warnings.
print Encode::encode_utf8($json_printer->encode($content));<?php
// Log everything during development.
// If you run this on the CLI, set 'display_errors = On' in php.ini.
error_reporting(E_ALL);
// Declare your username and password for authentication.
$username = 'example';
$password = 'luggage12345';
// Define the API call.
$cpanel_host = 'localhost';
$request_uri = "https://$cpanel_host:2083/execute/SSL/install_ssl";
// Define the SSL certificate and key files.
$cert_file = realpath("/path/to/cert.crt");
$key_file = realpath("/path/to/key.key");
// Set up the payload to send to the server.
$payload = array(
'domain' => "example.com",
'cert' => file_get_contents($cert_file),
'key' => file_get_contents($key_file)
);
// Set up the cURL request object.
$ch = curl_init( $request_uri );
curl_setopt( $ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
curl_setopt( $ch, CURLOPT_USERPWD, $username . ':' . $password );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
// Set up a POST request with the payload.
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
// Make the call, and then terminate the cURL caller object.
$curl_response = curl_exec( $ch );
curl_close( $ch );
// Decode and validate output.
$response = json_decode( $curl_response );
if( empty( $response ) ) {
echo "The cURL call did not return valid JSON:\n";
die( $response );
} elseif ( !$response->status ) {
echo "The cURL call returned valid JSON, but reported errors:\n";
die( $response->errors[0] . "\n" );
}
// Print and exit.
die( print_r( $response ) );
?>