API client class v1.1.72

- added property $request_timeout to control the cURL option CURLOPT_TIMEOUT, contributed by @mreho
- added setter and getter for $request_timeout, contributed by @mreho
- changed default value for the cURL option CURLOPT_HTTP_VERSION to CURL_HTTP_VERSION_1_1:
    - as of cURL version 7.62.0 the default value is CURL_HTTP_VERSION_2TLS which may cause issues
    - https://curl.se/libcurl/c/CURLOPT_HTTP_VERSION.html
- added property for $curl_http_version to hold the value for CURLOPT_HTTP_VERSION
- added setter and getter for $curl_http_version
- switched to using a constant to hold the class version
- updated the README file
This commit is contained in:
malle-pietje 2021-10-19 10:39:17 +02:00
parent 13b6699889
commit 9cca43557c
3 changed files with 223 additions and 155 deletions

115
README.md
View File

@ -1,44 +1,53 @@
## UniFi Controller API client class ## UniFi Controller API client class
A PHP class that provides access to Ubiquiti's [**UniFi Network Controller**](https://unifi-network.ui.com/) API, A PHP class that provides access to Ubiquiti's [**UniFi Network Controller**](https://unifi-network.ui.com/) API.
versions 4.X.X, 5.X.X and 6.X.X of the UniFi Network Controller software are supported (version 6.3.51 has been
confirmed to work) as well as UniFi OS-based controllers (version 5.12.59 has been confirmed to work). This class is UniFi Network Controller software versions 4.X.X, 5.X.X and 6.X.X are supported
used by our API browser tool which can be found [here](https://github.com/Art-of-WiFi/UniFi-API-browser). (version 6.4.54 has been confirmed to work) as well as UniFi OS-based controllers .
This class is used by our API browser tool which can be found [here](https://github.com/Art-of-WiFi/UniFi-API-browser).
The package can be installed manually or by using The package can be installed manually or by using
composer/[packagist](https://packagist.org/packages/art-of-wifi/unifi-api-client) for easy inclusion in your projects. composer/[packagist](https://packagist.org/packages/art-of-wifi/unifi-api-client) for
easy inclusion in your projects.
## Requirements ## Requirements
- a server with PHP, version 5.5.0 or higher, and the PHP cURL module installed (tested on Apache 2.4 with PHP Version - a server with:
5.6.1 and cURL 7.42.1 and with PHP 7.2.24 and cURL 7.58.0) - PHP version 5.5.0 or higher
- direct network connectivity between this server and the host and port (normally TCP port 8443) where the UniFi - PHP json and PHP cURL modules
Controller is running - tested on Apache 2.4 with PHP Version 5.6.1 and cURL 7.42.1 and with PHP 7.2.24 and cURL 7.58.0
- you must use **local accounts**, not UniFi Cloud accounts, to access the UniFi Controller API through this class - direct network connectivity between this server and the host and port (normally TCP
port 8443 or port 443 for
UniFi OS) where the UniFi Controller is running
- you must use **accounts with local access**, not pure UniFi Cloud accounts,
to access the UniFi Controller API through this class
## UniFi OS Support ## UniFi OS Support
Support for UniFi OS-based controllers (UniFi Dream Machine Pro or Cloud Key Gen2/Cloud Key Gen2 Plus with firmware Support for UniFi OS-based controllers (UniFi Dream Machine, UniFi Dream Machine Pro
version 2.0.24 or higher) has been added as of version 1.1.47. The class automatically detects UniFi OS devices and or Cloud Key Gen2/Cloud Key Gen2 Plus with firmware version 2.0.24 or higher) has
adjusts URLs and several functions/methods accordingly. If your own code applies strict validation of the URL that is been added as of version 1.1.47. The class automatically detects UniFi OS devices and
passed to the constructor, please adapt your logic to allow URLs without a port suffix when dealing with a UniFi adjusts URLs and several functions/methods accordingly. If your own code implements strict
OS-based controller. validation of the URL that is passed to the constructor, please adapt your logic to
allow URLs without a port suffix or with port 443 when dealing with a UniFi OS-based
controller.
Please test all methods you plan on using thoroughly before using the API Client with UniFi OS devices in a production Please test all methods you plan on using thoroughly before using the API Client with
environment. UniFi OS devices in a production environment.
## Installation ## Installation
Use [Composer](#composer), [Git](#git) or simply [Download the Release](#download-the-release) to install the API client Use [Composer](#composer), [Git](#git) or simply [Download the Release](#download-the-release) to install the
class. API client class.
### Composer ### Composer
The preferred installation method is through [composer](https://getcomposer.org). Follow The preferred installation method is through [composer](https://getcomposer.org).
these [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer Follow these [installation instructions](https://getcomposer.org/doc/00-intro.md) if you don't have composer
installed. installed already.
Once composer is installed, simply execute this command from the shell in your project directory: Once composer is installed, simply execute this command from the shell in your project
directory:
```sh ```sh
composer require art-of-wifi/unifi-api-client composer require art-of-wifi/unifi-api-client
@ -98,7 +107,7 @@ require_once 'vendor/autoload.php';
* initialize the UniFi API connection class, log in to the controller and request the alarms collection * initialize the UniFi API connection class, log in to the controller and request the alarms collection
* (this example assumes you have already assigned the correct values to the variables used) * (this example assumes you have already assigned the correct values to the variables used)
*/ */
$unifi_connection = new UniFi_API\Client($controller_user, $controller_password, $controller_url, $site_id, $controller_version, true); $unifi_connection = new UniFi_API\Client($controller_user, $controller_password $controller_url, $site_id, $controller_version, true);
$login = $unifi_connection->login(); $login = $unifi_connection->login();
$results = $unifi_connection->list_alarms(); // returns a PHP array containing alarm objects $results = $unifi_connection->list_alarms(); // returns a PHP array containing alarm objects
``` ```
@ -115,16 +124,16 @@ own PHP code.
`jl3z2shm` is the short site "name" and the value to assign to $site_id. `jl3z2shm` is the short site "name" and the value to assign to $site_id.
2. The last optional parameter that is passed to the constructor in the above example (`true`), enables validation of 2. The 6th optional parameter that is passed to the constructor in the above example (`true`), enables validation of
the controller's SSL certificate which is otherwise **disabled** by default. It is **highly recommended** to enable the controller's SSL certificate which is otherwise **disabled** by default. It is **highly recommended** to enable
this feature in production environments where you have a valid SSL cert installed on the UniFi Controller that is this feature in production environments where you have a valid SSL cert installed on the UniFi Controller that is
associated with the FQDN in the `controller_url` parameter. This option was added with API client version 1.1.16. associated with the FQDN in the `controller_url` parameter. This option was added with API client version 1.1.16.
## Functions/methods supported ## Functions/methods supported
The class currently supports the following functions/methods to GET/POST/PUT/DELETE data through the UniFi Controller The class currently supports the following functions/methods to GET/POST/PUT/DELETE data
API. Please refer to the comments in the source code for more details on the functions/methods and their respective through the UniFi Controller API. Please refer to the comments in the source code for
parameters. more details on the functions/methods and their respective parameters.
- login() - login()
- logout() - logout()
@ -134,10 +143,10 @@ parameters.
- authorize_guest() - authorize_guest()
- block_sta() - block_sta()
- cancel_rolling_upgrade() - cancel_rolling_upgrade()
- cmd_stat()
- count_alarms()
- check_controller_update() - check_controller_update()
- check_firmware_update() - check_firmware_update()
- cmd_stat()
- count_alarms()
- create_apgroup() (supported with controller versions 6.0.X and higher) - create_apgroup() (supported with controller versions 6.0.X and higher)
- create_dynamicdns() - create_dynamicdns()
- create_firewallgroup() - create_firewallgroup()
@ -177,8 +186,8 @@ parameters.
- list_country_codes() - list_country_codes()
- list_current_channels() - list_current_channels()
- list_dashboard() - list_dashboard()
- list_devices()
- list_device_name_mappings() - list_device_name_mappings()
- list_devices()
- list_dpi_stats() - list_dpi_stats()
- list_dynamicdns() - list_dynamicdns()
- list_events() - list_events()
@ -259,24 +268,24 @@ parameters.
- stat_daily_gateway() (supported on controller version 5.7.X and higher) - stat_daily_gateway() (supported on controller version 5.7.X and higher)
- stat_daily_site() - stat_daily_site()
- stat_daily_user() (supported on controller version 5.7.X and higher) - stat_daily_user() (supported on controller version 5.7.X and higher)
- stat_full_status()
- stat_hourly_aps() - stat_hourly_aps()
- stat_hourly_gateway() (supported on controller version 5.7.X and higher) - stat_hourly_gateway() (supported on controller version 5.7.X and higher)
- stat_hourly_site() - stat_hourly_site()
- stat_hourly_user() (supported on controller version 5.7.X and higher) - stat_hourly_user() (supported on controller version 5.7.X and higher)
- stat_ips_events() (supported on controller version 5.9.10 and higher) - stat_ips_events() (supported on controller version 5.9.10 and higher)
- stat_monthly_aps()
- stat_monthly_gateway()
- stat_monthly_site()
- stat_monthly_user()
- stat_payment() - stat_payment()
- stat_sessions() - stat_sessions()
- stat_sites() - stat_sites()
- stat_speedtest_results() - stat_speedtest_results()
- stat_sta_sessions_latest() - stat_sta_sessions_latest()
- stat_status() - stat_status()
- stat_full_status()
- stat_sysinfo() - stat_sysinfo()
- stat_voucher() - stat_voucher()
- stat_monthly_aps()
- stat_monthly_gateway()
- stat_monthly_site()
- stat_monthly_user()
- unauthorize_guest() - unauthorize_guest()
- unblock_sta() - unblock_sta()
- unset_locate_ap() (deprecated but still available as alias) - unset_locate_ap() (deprecated but still available as alias)
@ -286,38 +295,44 @@ parameters.
Other functions, getters/setters: Other functions, getters/setters:
- get_class_version() - get_class_version()
- get_connection_timeout()
- get_cookie() (renamed from getcookie(), deprecated but still available, use get_cookies() instead) - get_cookie() (renamed from getcookie(), deprecated but still available, use get_cookies() instead)
- get_cookies() - get_cookies()
- get_curl_connection_timeout()
- get_curl_http_version()
- get_curl_method()
- get_curl_request_timeout()
- get_curl_request_timeout()
- get_curl_ssl_verify_host()
- get_curl_ssl_verify_peer()
- get_debug() - get_debug()
- get_is_unifi_os() - get_is_unifi_os()
- get_last_error_message() - get_last_error_message()
- get_last_results_raw() - get_last_results_raw()
- get_request_method()
- get_site() - get_site()
- get_ssl_verify_host()
- get_ssl_verify_peer()
- set_connection_timeout() - set_connection_timeout()
- set_cookies() - set_cookies()
- set_curl_http_version()
- set_curl_request_timeout()
- set_curl_ssl_verify_host()
- set_curl_ssl_verify_peer()
- set_debug() - set_debug()
- set_is_unifi_os() - set_is_unifi_os()
- set_request_method() - set_request_method()
- set_request_timeout()
- set_site() - set_site()
- set_ssl_verify_host()
- set_ssl_verify_peer()
## Need help or have suggestions? ## Need help or have suggestions?
There is still work to be done to add functionality and further improve the usability of this class, so all There is still work to be done to add functionality and further improve the usability of
suggestions/comments are welcome. Please use the this class, so all suggestions/comments are welcome. Please use the GitHub
GitHub [issue list](https://github.com/Art-of-WiFi/UniFi-API-client/issues) or the Ubiquiti Community [issue list](https://github.com/Art-of-WiFi/UniFi-API-client/issues) or the Ubiquiti
forums (https://community.ubnt.com/t5/UniFi-Wireless/PHP-class-to-access-the-UniFi-controller-API-updates-and/td-p/1512870) Community forums (https://community.ubnt.com/t5/UniFi-Wireless/PHP-class-to-access-the-UniFi-controller-API-updates-and/td-p/1512870)
to share your suggestions and questions. to share your suggestions and questions.
## Contribute ## Contribute
If you would like to contribute code (improvements), please open an issue and include your code there or else create a If you would like to contribute code (improvements), please open an issue and include
pull request. your code there or else create a pull request.
## Credits ## Credits
@ -332,5 +347,5 @@ and the API as published by Ubiquiti:
## Important Disclaimer ## Important Disclaimer
Many of the functions in this API client class are not officially supported by Ubiquiti and as such, may not be Many of the functions in this API client class are not officially supported by Ubiquiti
supported in future versions of the UniFi Controller API. and as such, may not be supported in future versions of the UniFi Controller API.

View File

@ -1,6 +1,6 @@
{ {
"name": "art-of-wifi/unifi-api-client", "name": "art-of-wifi/unifi-api-client",
"type": "library", "type": "library",
"description": "API client class for use with Ubiquiti's UniFi controller", "description": "API client class for use with Ubiquiti's UniFi controller",
"keywords": [ "keywords": [
"ubnt", "ubnt",
@ -10,13 +10,13 @@
"api", "api",
"client" "client"
], ],
"homepage": "https://github.com/Art-of-WiFi/UniFi-API-client", "homepage": "https://github.com/Art-of-WiFi/UniFi-API-client",
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {
"name": "Art of WiFi", "name": "Art of WiFi",
"email": "info@artofowifi.net", "email": "info@artofowifi.net",
"homepage": "http://artofwifi.net" "homepage": "https://artofwifi.net"
} }
], ],
"require": { "require": {
@ -29,4 +29,4 @@
"UniFi_API\\": "src/" "UniFi_API\\": "src/"
} }
} }
} }

View File

@ -22,26 +22,31 @@ class Client
{ {
/** /**
* private and protected properties * private and protected properties
*
* NOTE:
* do not modify the values here, instead user the constructor or the getter and setter functions/methods
*/ */
private $class_version = '1.1.71'; const CLASS_VERSION = '1.1.72';
protected $baseurl = 'https://127.0.0.1:8443'; protected $baseurl = 'https://127.0.0.1:8443';
protected $user = ''; protected $user = '';
protected $password = ''; protected $password = '';
protected $site = 'default'; protected $site = 'default';
protected $version = '6.0.43'; protected $version = '6.2.26';
protected $debug = false; protected $debug = false;
protected $ssl_verify_peer = false; protected $is_loggedin = false;
protected $ssl_verify_host = false; protected $is_unifi_os = false;
protected $is_loggedin = false; protected $exec_retries = 0;
protected $is_unifi_os = false; protected $cookies = '';
protected $exec_retries = 0; protected $last_results_raw = null;
protected $cookies = ''; protected $last_error_message = null;
protected $headers = []; protected $curl_ssl_verify_peer = false;
protected $method = 'GET'; protected $curl_ssl_verify_host = false;
protected $methods_allowed = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']; protected $curl_http_version = CURL_HTTP_VERSION_1_1;
protected $connect_timeout = 10; protected $curl_headers = [];
protected $last_results_raw = null; protected $curl_method = 'GET';
protected $last_error_message = null; protected $curl_methods_allowed = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'];
protected $curl_request_timeout = 30;
protected $curl_connect_timeout = 10;
/** /**
* Construct an instance of the UniFi API client class * Construct an instance of the UniFi API client class
@ -81,8 +86,8 @@ class Client
} }
if ((boolean)$ssl_verify === true) { if ((boolean)$ssl_verify === true) {
$this->ssl_verify_peer = true; $this->curl_ssl_verify_peer = true;
$this->ssl_verify_host = 2; $this->curl_ssl_verify_host = 2;
} }
} }
@ -112,7 +117,7 @@ class Client
/** /**
* Login to the UniFi controller * Login to the UniFi controller
* *
* @return bool returns true upon success * @return bool|int returns true upon success, false or HTTP status upon error
*/ */
public function login() public function login()
{ {
@ -129,8 +134,7 @@ class Client
} }
/** /**
* check whether this is a "regular" controller or one based on UniFi OS, * prepare cURL and options to check whether this is a "regular" controller or one based on UniFi OS
* prepare cURL and options
*/ */
if (!($ch = $this->get_curl_handle())) { if (!($ch = $this->get_curl_handle())) {
return false; return false;
@ -241,9 +245,9 @@ class Client
]; ];
/** /**
* constuct HTTP request headers as required * construct the HTTP request headers as required
*/ */
$this->headers = [ $this->curl_headers = [
'content-length: 0', 'content-length: 0',
'Expect:', 'Expect:',
]; ];
@ -256,7 +260,7 @@ class Client
$this->create_x_csrf_token_header(); $this->create_x_csrf_token_header();
} }
$curl_options[CURLOPT_HTTPHEADER] = $this->headers; $curl_options[CURLOPT_HTTPHEADER] = $this->curl_headers;
$curl_options[CURLOPT_URL] = $this->baseurl . $logout_path; $curl_options[CURLOPT_URL] = $this->baseurl . $logout_path;
curl_setopt_array($ch, $curl_options); curl_setopt_array($ch, $curl_options);
@ -1078,8 +1082,8 @@ class Client
return false; return false;
} }
$this->method = 'PUT'; $this->curl_method = 'PUT';
$payload = [ $payload = [
'_id' => $client_id, '_id' => $client_id,
'use_fixedip' => $use_fixedip, 'use_fixedip' => $use_fixedip,
]; ];
@ -1138,8 +1142,8 @@ class Client
*/ */
public function edit_usergroup($group_id, $site_id, $group_name, $group_dn = -1, $group_up = -1) public function edit_usergroup($group_id, $site_id, $group_name, $group_dn = -1, $group_up = -1)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
$payload = [ $payload = [
'_id' => $group_id, '_id' => $group_id,
'name' => $group_name, 'name' => $group_name,
'qos_rate_max_down' => intval($group_dn), 'qos_rate_max_down' => intval($group_dn),
@ -1157,7 +1161,7 @@ class Client
*/ */
public function delete_usergroup($group_id) public function delete_usergroup($group_id)
{ {
$this->method = 'DELETE'; $this->curl_method = 'DELETE';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/usergroup/' . trim($group_id)); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/usergroup/' . trim($group_id));
} }
@ -1196,8 +1200,8 @@ class Client
*/ */
public function edit_apgroup($group_id, $group_name, $device_macs) public function edit_apgroup($group_id, $group_name, $device_macs)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
$payload = [ $payload = [
'_id' => $group_id, '_id' => $group_id,
'attr_no_delete' => false, 'attr_no_delete' => false,
'name' => $group_name, 'name' => $group_name,
@ -1214,7 +1218,7 @@ class Client
*/ */
public function delete_apgroup($group_id) public function delete_apgroup($group_id)
{ {
$this->method = 'DELETE'; $this->curl_method = 'DELETE';
return $this->fetch_results_boolean('/v2/api/site/' . $this->site . '/apgroups/' . trim($group_id)); return $this->fetch_results_boolean('/v2/api/site/' . $this->site . '/apgroups/' . trim($group_id));
} }
@ -1268,8 +1272,8 @@ class Client
return false; return false;
} }
$this->method = 'PUT'; $this->curl_method = 'PUT';
$payload = [ $payload = [
'_id' => $group_id, '_id' => $group_id,
'name' => $group_name, 'name' => $group_name,
'group_type' => $group_type, 'group_type' => $group_type,
@ -1287,7 +1291,7 @@ class Client
*/ */
public function delete_firewallgroup($group_id) public function delete_firewallgroup($group_id)
{ {
$this->method = 'DELETE'; $this->curl_method = 'DELETE';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/firewallgroup/' . trim($group_id)); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/firewallgroup/' . trim($group_id));
} }
@ -1489,7 +1493,7 @@ class Client
*/ */
public function set_site_country($country_id, $payload) public function set_site_country($country_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/country/' . trim($country_id), return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/country/' . trim($country_id),
$payload); $payload);
} }
@ -1509,7 +1513,7 @@ class Client
*/ */
public function set_site_locale($locale_id, $payload) public function set_site_locale($locale_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/locale/' . trim($locale_id), return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/locale/' . trim($locale_id),
$payload); $payload);
} }
@ -1526,7 +1530,7 @@ class Client
*/ */
public function set_site_snmp($snmp_id, $payload) public function set_site_snmp($snmp_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/snmp/' . trim($snmp_id), $payload); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/snmp/' . trim($snmp_id), $payload);
} }
@ -1542,7 +1546,7 @@ class Client
*/ */
public function set_site_mgmt($mgmt_id, $payload) public function set_site_mgmt($mgmt_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/mgmt/' . trim($mgmt_id), $payload); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/mgmt/' . trim($mgmt_id), $payload);
} }
@ -1559,7 +1563,7 @@ class Client
*/ */
public function set_site_guest_access($guest_access_id, $payload) public function set_site_guest_access($guest_access_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/guest_access/' . trim($guest_access_id), return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/guest_access/' . trim($guest_access_id),
$payload); $payload);
} }
@ -1576,7 +1580,7 @@ class Client
*/ */
public function set_site_ntp($ntp_id, $payload) public function set_site_ntp($ntp_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/ntp/' . trim($ntp_id), $payload); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/ntp/' . trim($ntp_id), $payload);
} }
@ -1593,7 +1597,7 @@ class Client
*/ */
public function set_site_connectivity($connectivity_id, $payload) public function set_site_connectivity($connectivity_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/connectivity/' . trim($connectivity_id), return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/connectivity/' . trim($connectivity_id),
$payload); $payload);
} }
@ -2144,8 +2148,8 @@ class Client
return false; return false;
} }
$this->method = 'PUT'; $this->curl_method = 'PUT';
$payload = ['disabled' => $disable]; $payload = ['disabled' => $disable];
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($ap_id), $payload); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($ap_id), $payload);
} }
@ -2167,8 +2171,8 @@ class Client
return false; return false;
} }
$this->method = 'PUT'; $this->curl_method = 'PUT';
$payload = ['led_override' => $override_mode]; $payload = ['led_override' => $override_mode];
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($device_id), $payload); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($device_id), $payload);
} }
@ -2453,7 +2457,7 @@ class Client
*/ */
public function set_dynamicdns($dynamicdns_id, $payload) public function set_dynamicdns($dynamicdns_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/dynamicdns/' . trim($dynamicdns_id), return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/dynamicdns/' . trim($dynamicdns_id),
$payload); $payload);
} }
@ -2494,7 +2498,7 @@ class Client
*/ */
public function set_networksettings_base($network_id, $payload) public function set_networksettings_base($network_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id), return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id),
$payload); $payload);
} }
@ -2507,7 +2511,7 @@ class Client
*/ */
public function delete_network($network_id) public function delete_network($network_id)
{ {
$this->method = 'DELETE'; $this->curl_method = 'DELETE';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id)); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id));
} }
@ -2607,7 +2611,7 @@ class Client
*/ */
public function set_wlansettings_base($wlan_id, $payload) public function set_wlansettings_base($wlan_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id), $payload); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id), $payload);
} }
@ -2658,7 +2662,7 @@ class Client
*/ */
public function delete_wlan($wlan_id) public function delete_wlan($wlan_id)
{ {
$this->method = 'DELETE'; $this->curl_method = 'DELETE';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id)); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id));
} }
@ -2914,7 +2918,7 @@ class Client
*/ */
public function set_device_settings_base($device_id, $payload) public function set_device_settings_base($device_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($device_id), $payload); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($device_id), $payload);
} }
@ -3027,7 +3031,7 @@ class Client
*/ */
public function set_radius_account_base($account_id, $payload) public function set_radius_account_base($account_id, $payload)
{ {
$this->method = 'PUT'; $this->curl_method = 'PUT';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/account/' . trim($account_id), $payload); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/account/' . trim($account_id), $payload);
} }
@ -3042,7 +3046,7 @@ class Client
*/ */
public function delete_radius_account($account_id) public function delete_radius_account($account_id)
{ {
$this->method = 'DELETE'; $this->curl_method = 'DELETE';
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/account/' . trim($account_id)); return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/account/' . trim($account_id));
} }
@ -3123,7 +3127,7 @@ class Client
*/ */
public function custom_api_request($path, $method = 'GET', $payload = null, $return = 'array') public function custom_api_request($path, $method = 'GET', $payload = null, $return = 'array')
{ {
if (!in_array($method, $this->methods_allowed)) { if (!in_array($method, $this->curl_methods_allowed)) {
return false; return false;
} }
@ -3131,7 +3135,7 @@ class Client
return false; return false;
} }
$this->method = $method; $this->curl_method = $method;
if ($return === 'array') { if ($return === 'array') {
return $this->fetch_results($path, $payload); return $this->fetch_results($path, $payload);
@ -3369,7 +3373,7 @@ class Client
*/ */
public function get_class_version() public function get_class_version()
{ {
return $this->class_version; return self::CLASS_VERSION;
} }
/** /**
@ -3387,25 +3391,25 @@ class Client
* *
* @return string request type * @return string request type
*/ */
public function get_method() public function get_curl_method()
{ {
return $this->method; return $this->curl_method;
} }
/** /**
* Set request method * Set request method
* *
* @param string $method a valid HTTP request method * @param string $curl_method a valid HTTP request method
* @return bool whether request was successful or not * @return bool whether request was successful or not
*/ */
public function set_method($method) public function set_curl_method($curl_method)
{ {
if (!in_array($method, $this->methods_allowed)) { if (!in_array($curl_method, $this->curl_methods_allowed)) {
return false; return false;
} }
$this->method = $method; $this->curl_method = $curl_method;
return true; return true;
} }
@ -3417,9 +3421,9 @@ class Client
* *
* @return bool value of private property $ssl_verify_peer (cURL option CURLOPT_SSL_VERIFYPEER) * @return bool value of private property $ssl_verify_peer (cURL option CURLOPT_SSL_VERIFYPEER)
*/ */
public function get_ssl_verify_peer() public function get_curl_ssl_verify_peer()
{ {
return $this->ssl_verify_peer; return $this->curl_ssl_verify_peer;
} }
/** /**
@ -3427,15 +3431,15 @@ class Client
* *
* https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html * https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html
* *
* @param int|bool $ssl_verify_peer should be 0/false or 1/true * @param int|bool $curl_ssl_verify_peer should be 0/false or 1/true
*/ */
public function set_ssl_verify_peer($ssl_verify_peer) public function set_curl_ssl_verify_peer($curl_ssl_verify_peer)
{ {
if (!in_array($ssl_verify_peer, [0, false, 1, true])) { if (!in_array($curl_ssl_verify_peer, [0, false, 1, true])) {
return false; return false;
} }
$this->ssl_verify_peer = $ssl_verify_peer; $this->curl_ssl_verify_peer = $curl_ssl_verify_peer;
return true; return true;
} }
@ -3447,9 +3451,9 @@ class Client
* *
* @return bool value of private property $ssl_verify_peer (cURL option CURLOPT_SSL_VERIFYHOST) * @return bool value of private property $ssl_verify_peer (cURL option CURLOPT_SSL_VERIFYHOST)
*/ */
public function get_ssl_verify_host() public function get_curl_ssl_verify_host()
{ {
return $this->ssl_verify_host; return $this->curl_ssl_verify_host;
} }
/** /**
@ -3457,15 +3461,15 @@ class Client
* *
* https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html * https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html
* *
* @param int|bool $ssl_verify_host should be 0/false or 2 * @param int|bool $curl_ssl_verify_host should be 0/false or 2
*/ */
public function set_ssl_verify_host($ssl_verify_host) public function set_curl_ssl_verify_host($curl_ssl_verify_host)
{ {
if (!in_array($ssl_verify_host, [0, false, 2])) { if (!in_array($curl_ssl_verify_host, [0, false, 2])) {
return false; return false;
} }
$this->ssl_verify_host = $ssl_verify_host; $this->curl_ssl_verify_host = $curl_ssl_verify_host;
return true; return true;
} }
@ -3504,17 +3508,64 @@ class Client
*/ */
public function set_connection_timeout($timeout) public function set_connection_timeout($timeout)
{ {
$this->connect_timeout = $timeout; $this->curl_connect_timeout = $timeout;
} }
/** /**
* Get current value of the private property $connect_timeout * Get current value of the private property $connect_timeout
* *
* @return int current value if $connect_timeout * @return int current value of $connect_timeout
*/ */
public function get_connection_timeout() public function get_connection_timeout()
{ {
return $this->connect_timeout; return $this->curl_connect_timeout;
}
/**
* Set value for the private property $request_timeout
*
* @param int $timeout new value for $request_timeout in seconds
*/
public function set_curl_request_timeout($timeout)
{
$this->curl_request_timeout = $timeout;
}
/**
* Get current value of the private property $request_timeout
*
* @return int current value of $request_timeout
*/
public function get_curl_request_timeout()
{
return $this->curl_request_timeout;
}
/**
* Set value for the private property $curl_http_version
*
* NOTES:
* - as of cURL version 7.62.0 the default value is CURL_HTTP_VERSION_2TLS which may cause issues
* - the default value used in this class is CURL_HTTP_VERSION_1_1
* - https://curl.se/libcurl/c/CURLOPT_HTTP_VERSION.html
*
* @param int $http_version new value for $curl_http_version, can be CURL_HTTP_VERSION_1_1 int(2)
* or CURL_HTTP_VERSION_2TLS int(4)
*/
public function set_curl_http_version($http_version)
{
$this->curl_http_version = $http_version;
}
/**
* Get current value of the private property $curl_http_version
*
* @return int current value of $request_timeout, can be CURL_HTTP_VERSION_1_1 int(2) or
* CURL_HTTP_VERSION_2TLS int(4)
*/
public function get_curl_http_version()
{
return $this->curl_http_version;
} }
/**************************************************************** /****************************************************************
@ -3746,7 +3797,7 @@ class Client
return; return;
} }
$this->headers[] = 'x-csrf-token: ' . json_decode(base64_decode($jwt_components[1]))->csrfToken; $this->curl_headers[] = 'x-csrf-token: ' . json_decode(base64_decode($jwt_components[1]))->csrfToken;
} }
} }
@ -3796,8 +3847,8 @@ class Client
*/ */
protected function exec_curl($path, $payload = null) protected function exec_curl($path, $payload = null)
{ {
if (!in_array($this->method, $this->methods_allowed)) { if (!in_array($this->curl_method, $this->curl_methods_allowed)) {
trigger_error('an invalid HTTP request type was used: ' . $this->method); trigger_error('an invalid HTTP request type was used: ' . $this->curl_method);
return false; return false;
} }
@ -3806,8 +3857,8 @@ class Client
return false; return false;
} }
$this->headers = []; $this->curl_headers = [];
$url = $this->baseurl . $path; $url = $this->baseurl . $path;
if ($this->is_unifi_os) { if ($this->is_unifi_os) {
$url = $this->baseurl . '/proxy/network' . $path; $url = $this->baseurl . '/proxy/network' . $path;
@ -3828,7 +3879,7 @@ class Client
/** /**
* add empty Expect header to prevent cURL from injecting an "Expect: 100-continue" header * add empty Expect header to prevent cURL from injecting an "Expect: 100-continue" header
*/ */
$this->headers = [ $this->curl_headers = [
'content-type: application/json', 'content-type: application/json',
'Expect:', 'Expect:',
]; ];
@ -3837,12 +3888,12 @@ class Client
* should not use GET (the default request type) or DELETE when passing a payload, * should not use GET (the default request type) or DELETE when passing a payload,
* switch to POST instead * switch to POST instead
*/ */
if ($this->method === 'GET' || $this->method === 'DELETE') { if ($this->curl_method === 'GET' || $this->curl_method === 'DELETE') {
$this->method = 'POST'; $this->curl_method = 'POST';
} }
} }
switch ($this->method) { switch ($this->curl_method) {
case 'POST': case 'POST':
$curl_options[CURLOPT_POST] = true; $curl_options[CURLOPT_POST] = true;
break; break;
@ -3857,12 +3908,12 @@ class Client
break; break;
} }
if ($this->is_unifi_os && $this->method !== 'GET') { if ($this->is_unifi_os && $this->curl_method !== 'GET') {
$this->create_x_csrf_token_header(); $this->create_x_csrf_token_header();
} }
if (count($this->headers) > 0) { if (count($this->curl_headers) > 0) {
$curl_options[CURLOPT_HTTPHEADER] = $this->headers; $curl_options[CURLOPT_HTTPHEADER] = $this->curl_headers;
} }
curl_setopt_array($ch, $curl_options); curl_setopt_array($ch, $curl_options);
@ -3948,7 +3999,7 @@ class Client
/** /**
* set method back to default value, just in case * set method back to default value, just in case
*/ */
$this->method = 'GET'; $this->curl_method = 'GET';
return $response; return $response;
} }
@ -3963,9 +4014,11 @@ class Client
if (is_object($ch) || is_resource($ch)) { if (is_object($ch) || is_resource($ch)) {
$curl_options = [ $curl_options = [
CURLOPT_PROTOCOLS => CURLPROTO_HTTPS, CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
CURLOPT_SSL_VERIFYPEER => $this->ssl_verify_peer, CURLOPT_HTTP_VERSION => $this->curl_http_version,
CURLOPT_SSL_VERIFYHOST => $this->ssl_verify_host, CURLOPT_SSL_VERIFYPEER => $this->curl_ssl_verify_peer,
CURLOPT_CONNECTTIMEOUT => $this->connect_timeout, CURLOPT_SSL_VERIFYHOST => $this->curl_ssl_verify_host,
CURLOPT_CONNECTTIMEOUT => $this->curl_connect_timeout,
CURLOPT_TIMEOUT => $this->curl_request_timeout,
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '', CURLOPT_ENCODING => '',
CURLOPT_HEADERFUNCTION => [$this, 'response_header_callback'], CURLOPT_HEADERFUNCTION => [$this, 'response_header_callback'],