Difference between revisions of "REST"

From securityrouter.org, an OpenBSD-based firewall
Jump to: navigation, search
Line 18: Line 18:
== Proxy code ==
== Proxy code ==
if (!isset($_SERVER['PHP_AUTH_USER'])) {
if (!isset($_SERVER['PHP_AUTH_USER'])) {
         header('HTTP/1.0 401 Unauthorized');
         header('HTTP/1.0 401 Unauthorized');
Line 101: Line 101:
The PHP code above should usually be placed within <tt><?php</tt> tags, and accompanied with a rewrite directives such as (Apache example)
The PHP code above should usually be placed within <tt><?php</tt> tags, and accompanied with a rewrite directives such as (Apache example)
  RewriteEngine On
  RewriteEngine On

Latest revision as of 06:23, 15 June 2018

REST[1] (Representational state transfer) or RESTful APIs have become increasingly popular. Because it's not perfectly fit for all the functionality that our system provides, our primary API is SOAP.

We do however realise that there might be cases when SOAP is not an option, and therefore provide a REST proxy. Input and output is JSON encoded, and the arguments are described on the SOAP page and XLST styled WSDL file accessible as https://system/remote/


List all configuration revisions:

GET /rest/config

Commit and apply a new configuration file:

POST /rest/config
{ "message": "added vlan", "config": "interface em0..." }

View the running configuration:

GET /rest/config/head

View a specific revision:

GET /rest/config/ID

Tag a revision:

PUT /rest/config/ID/tag
{ "message": "before clustering" }

Proxy code

if (!isset($_SERVER['PHP_AUTH_USER'])) {
        header('HTTP/1.0 401 Unauthorized');
        header('WWW-Authenticate: Basic realm="SR REST"');
$url = '';
$soap = new SoapClient($url.'/remote/?wsdl', array(
        'location' => $url.'/remote/',
        'uri' => 'urn:sr',
        'login' => $_SERVER['PHP_AUTH_USER'],
        'password' => $_SERVER['PHP_AUTH_PW']
$data = json_decode(file_get_contents('php://input'));
if ($data === null) $data = (object)$_GET;

if (is_call('GET',    array('config')))                               json($soap->configRevisionLog());
if (is_call('POST',   array('config')))                               json($soap->configCommit($data));
if (is_call('GET',    array('config', 'head')))                       json($soap->configCheckout(-1));
if (is_call('GET',    array('config', 'ID'), 'revision'))             json($soap->configCheckout($data));
if (is_call('PUT',    array('config', 'ID', 'tag'), 'revision'))      json($soap->configTag($data));
if (is_call('POST',   array('commit', 'ID'), 'uuid'))                 json($soap->configConfirm($data));
if (is_call('DELETE', array('commit', 'ID'), 'uuid'))                 json($soap->configCancel($data));
if (is_call('POST',   array('check')))                                json($soap->configCheck($data));
if (is_call('GET',    array('file')))                                 json($soap->fileRead($data));
if (is_call('PUT',    array('file')))                                 json($soap->fileWrite($data));
if (is_call('GET',    array('interfaces')))                           json($soap->getInterfaces());
if (is_call('GET',    array('serial')))                               json($soap->getSerial());
if (is_call('GET',    array('time')))                                 json($soap->getTime());
if (is_call('PUT',    array('time')))                                 json($soap->systemTime($data));
if (is_call('GET',    array('uptime')))                               json($soap->getUptime());
if (is_call('GET',    array('graph')))                                json($soap->graphList());
if (is_call('GET',    array('graph', 'ID'), 'name'))                  binary($soap->graphFile($data));
if (is_call('GET',    array('license')))                              json($soap->licenseExport());
if (is_call('POST',   array('license')))                              json($soap->licenseInstall($data));
if (is_call('DELETE', array('license', 'ID'), 'key'))                 json($soap->licenseRemove($data));
if (is_call('PUT',    array('power', 'off')))                         json($soap->systemPowerOff());
if (is_call('PUT',    array('power', 'reset')))                       json($soap->systemReboot());
if (is_call('GET',    array('software')))                             json($soap->getVersion());
if (is_call('PUT',    array('software')))                             json($soap->systemUpdate($data));
if (is_call('POST',   array('command')))                              json($soap->commandRun($data));
if (is_call('GET',    array('command', 'ID'), 'commandid'))           json($soap->commandPoll($data));
if (is_call('POST',   array('command', 'ID'), 'commandid'))           json($soap->commandPush($data));
if (is_call('PUT',    array('command', 'ID', 'signal'), 'commandid')) json($soap->commandPush($data));
if (is_call('PUT',    array('command', 'ID', 'stop'), 'commandid'))   json($soap->commandStop($data));
if (is_call('PUT',    array('command', 'ID', 'term'), 'commandid'))   json($soap->commandTermsize($data));
die('unknown call');

function is_call($method, $argv, $id = false) {
        global $data;
        $path = explode('/', $_SERVER['PATH_INFO']);
        if ($_SERVER['REQUEST_METHOD'] != $method)
                return false;
        if (count($path) != count($argv) + 1)
                return false;
        foreach($argv as $i => $a) {
                if ($a == 'ID')
                        $data->{$id} = $path[$i+1];
                else if ($path[$i+1] != $a)
                        return false;
        return true;

function json($data) {
        header('Content-type: application/json');
        echo json_encode($data);

function binary($data) {
        header('Content-type: application/octet-stream');
        echo $data->result;

function error($e) {
        header('HTTP/1.0 500 Internal Server Error');
        header('Content-type: application/json');
        echo json_encode(array('error' => $e->getMessage()));

The PHP code above should usually be placed within <?php tags, and accompanied with a rewrite directives such as (Apache example)

RewriteEngine On
RewriteBase /rest/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]