Update JsonRPC library
This commit is contained in:
parent
ded8552b8d
commit
d964c97f90
@ -13,7 +13,7 @@
|
|||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"fguillot/simple-validator": "v1.0.0",
|
"fguillot/simple-validator": "v1.0.0",
|
||||||
"fguillot/json-rpc": "v1.0.2",
|
"fguillot/json-rpc": "v1.1.0",
|
||||||
"fguillot/picodb": "v1.0.2",
|
"fguillot/picodb": "v1.0.2",
|
||||||
"fguillot/picofeed": "v0.1.23",
|
"fguillot/picofeed": "v0.1.23",
|
||||||
"pda/pheanstalk": "v3.1.0"
|
"pda/pheanstalk": "v3.1.0"
|
||||||
|
46
jsonrpc.php
46
jsonrpc.php
@ -3,27 +3,26 @@
|
|||||||
require __DIR__.'/common.php';
|
require __DIR__.'/common.php';
|
||||||
|
|
||||||
use JsonRPC\Server;
|
use JsonRPC\Server;
|
||||||
use PicoFeed\PicoFeedException;
|
|
||||||
use Model\Config;
|
use Model\Config;
|
||||||
|
|
||||||
$server = new Server;
|
$server = new Server();
|
||||||
|
|
||||||
$server->authentication(array(
|
$server->authentication(array(
|
||||||
Config\get('username') => Config\get('api_token')
|
Config\get('username') => Config\get('api_token')
|
||||||
));
|
));
|
||||||
|
|
||||||
// Get version
|
// Get version
|
||||||
$server->register('app.version', function () {
|
$server->register('app.version', function () {
|
||||||
|
|
||||||
return array('version' => APP_VERSION);
|
return array('version' => APP_VERSION);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get all feeds
|
// Get all feeds
|
||||||
$server->register('feed.list', function () {
|
$server->register('feed.list', function () {
|
||||||
|
|
||||||
$feeds = Model\Feed\get_all();
|
$feeds = Model\Feed\get_all();
|
||||||
if (!$feeds) {
|
if (empty($feeds)) {
|
||||||
return $feeds;
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$groups = Model\Group\get_feeds_map();
|
$groups = Model\Group\get_feeds_map();
|
||||||
foreach ($feeds as &$feed) {
|
foreach ($feeds as &$feed) {
|
||||||
$feed_id = $feed['id'];
|
$feed_id = $feed['id'];
|
||||||
@ -38,23 +37,16 @@ $server->register('feed.list', function () {
|
|||||||
|
|
||||||
// Get one feed
|
// Get one feed
|
||||||
$server->register('feed.info', function ($feed_id) {
|
$server->register('feed.info', function ($feed_id) {
|
||||||
|
|
||||||
$result = Model\Feed\get($feed_id);
|
$result = Model\Feed\get($feed_id);
|
||||||
$result['feed_group_ids'] = Model\Group\get_feed_group_ids($feed_id);
|
$result['feed_group_ids'] = Model\Group\get_feed_group_ids($feed_id);
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add a new feed
|
// Add a new feed
|
||||||
$server->register('feed.create', function($url) {
|
$server->register('feed.create', function($url) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$result = Model\Feed\create($url);
|
$result = Model\Feed\create($url);
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch (PicoFeedException $e) {
|
|
||||||
$result = false;
|
|
||||||
}
|
|
||||||
catch (UnexpectedValueException $e) {
|
|
||||||
$result = false;
|
$result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,157 +57,131 @@ $server->register('feed.create', function($url) {
|
|||||||
|
|
||||||
// Delete a feed
|
// Delete a feed
|
||||||
$server->register('feed.delete', function($feed_id) {
|
$server->register('feed.delete', function($feed_id) {
|
||||||
|
|
||||||
return Model\Feed\remove($feed_id);
|
return Model\Feed\remove($feed_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delete all feeds
|
// Delete all feeds
|
||||||
$server->register('feed.delete_all', function() {
|
$server->register('feed.delete_all', function() {
|
||||||
|
|
||||||
return Model\Feed\remove_all();
|
return Model\Feed\remove_all();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Enable a feed
|
// Enable a feed
|
||||||
$server->register('feed.enable', function($feed_id) {
|
$server->register('feed.enable', function($feed_id) {
|
||||||
|
|
||||||
return Model\Feed\enable($feed_id);
|
return Model\Feed\enable($feed_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Disable a feed
|
// Disable a feed
|
||||||
$server->register('feed.disable', function($feed_id) {
|
$server->register('feed.disable', function($feed_id) {
|
||||||
|
|
||||||
return Model\Feed\disable($feed_id);
|
return Model\Feed\disable($feed_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update a feed
|
// Update a feed
|
||||||
$server->register('feed.update', function($feed_id) {
|
$server->register('feed.update', function($feed_id) {
|
||||||
|
|
||||||
return Model\Feed\refresh($feed_id);
|
return Model\Feed\refresh($feed_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get all groups
|
// Get all groups
|
||||||
$server->register('group.list', function () {
|
$server->register('group.list', function () {
|
||||||
|
|
||||||
return Model\Group\get_all();
|
return Model\Group\get_all();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get all items for a specific feed
|
// Get all items for a specific feed
|
||||||
$server->register('item.feed.list', function ($feed_id, $offset = null, $limit = null) {
|
$server->register('item.feed.list', function ($feed_id, $offset = null, $limit = null) {
|
||||||
|
|
||||||
return Model\Item\get_all_by_feed($feed_id, $offset, $limit);
|
return Model\Item\get_all_by_feed($feed_id, $offset, $limit);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Count all feed items
|
// Count all feed items
|
||||||
$server->register('item.feed.count', function ($feed_id) {
|
$server->register('item.feed.count', function ($feed_id) {
|
||||||
|
|
||||||
return Model\Item\count_by_feed($feed_id);
|
return Model\Item\count_by_feed($feed_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get all bookmark items
|
// Get all bookmark items
|
||||||
$server->register('item.bookmark.list', function ($offset = null, $limit = null) {
|
$server->register('item.bookmark.list', function ($offset = null, $limit = null) {
|
||||||
|
|
||||||
return Model\Item\get_bookmarks($offset, $limit);
|
return Model\Item\get_bookmarks($offset, $limit);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Count bookmarks
|
// Count bookmarks
|
||||||
$server->register('item.bookmark.count', function () {
|
$server->register('item.bookmark.count', function () {
|
||||||
|
|
||||||
return Model\Item\count_bookmarks();
|
return Model\Item\count_bookmarks();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add a bookmark
|
// Add a bookmark
|
||||||
$server->register('item.bookmark.create', function ($item_id) {
|
$server->register('item.bookmark.create', function ($item_id) {
|
||||||
|
|
||||||
return Model\Item\set_bookmark_value($item_id, 1);
|
return Model\Item\set_bookmark_value($item_id, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove a bookmark
|
// Remove a bookmark
|
||||||
$server->register('item.bookmark.delete', function ($item_id) {
|
$server->register('item.bookmark.delete', function ($item_id) {
|
||||||
|
|
||||||
return Model\Item\set_bookmark_value($item_id, 0);
|
return Model\Item\set_bookmark_value($item_id, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get all unread items
|
// Get all unread items
|
||||||
$server->register('item.list_unread', function ($offset = null, $limit = null) {
|
$server->register('item.list_unread', function ($offset = null, $limit = null) {
|
||||||
|
|
||||||
return Model\Item\get_all_by_status('unread', array(), $offset, $limit);
|
return Model\Item\get_all_by_status('unread', array(), $offset, $limit);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Count all unread items
|
// Count all unread items
|
||||||
$server->register('item.count_unread', function () {
|
$server->register('item.count_unread', function () {
|
||||||
|
|
||||||
return Model\Item\count_by_status('unread');
|
return Model\Item\count_by_status('unread');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get all read items
|
// Get all read items
|
||||||
$server->register('item.list_read', function ($offset = null, $limit = null) {
|
$server->register('item.list_read', function ($offset = null, $limit = null) {
|
||||||
|
|
||||||
return Model\Item\get_all_by_status('read', array(), $offset, $limit);
|
return Model\Item\get_all_by_status('read', array(), $offset, $limit);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Count all read items
|
// Count all read items
|
||||||
$server->register('item.count_read', function () {
|
$server->register('item.count_read', function () {
|
||||||
|
|
||||||
return Model\Item\count_by_status('read');
|
return Model\Item\count_by_status('read');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get one item
|
// Get one item
|
||||||
$server->register('item.info', function ($item_id) {
|
$server->register('item.info', function ($item_id) {
|
||||||
|
|
||||||
return Model\Item\get($item_id);
|
return Model\Item\get($item_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delete an item
|
// Delete an item
|
||||||
$server->register('item.delete', function($item_id) {
|
$server->register('item.delete', function($item_id) {
|
||||||
|
|
||||||
return Model\Item\set_removed($item_id);
|
return Model\Item\set_removed($item_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mark item as read
|
// Mark item as read
|
||||||
$server->register('item.mark_as_read', function($item_id) {
|
$server->register('item.mark_as_read', function($item_id) {
|
||||||
|
|
||||||
return Model\Item\set_read($item_id);
|
return Model\Item\set_read($item_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mark item as unread
|
// Mark item as unread
|
||||||
$server->register('item.mark_as_unread', function($item_id) {
|
$server->register('item.mark_as_unread', function($item_id) {
|
||||||
|
|
||||||
return Model\Item\set_unread($item_id);
|
return Model\Item\set_unread($item_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Change the status of list of items
|
// Change the status of list of items
|
||||||
$server->register('item.set_list_status', function($status, array $items) {
|
$server->register('item.set_list_status', function($status, array $items) {
|
||||||
|
|
||||||
return Model\Item\set_status($status, $items);
|
return Model\Item\set_status($status, $items);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Flush all read items
|
// Flush all read items
|
||||||
$server->register('item.flush', function() {
|
$server->register('item.flush', function() {
|
||||||
|
|
||||||
return Model\Item\mark_all_as_removed();
|
return Model\Item\mark_all_as_removed();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mark all unread items as read
|
// Mark all unread items as read
|
||||||
$server->register('item.mark_all_as_read', function() {
|
$server->register('item.mark_all_as_read', function() {
|
||||||
|
|
||||||
return Model\Item\mark_all_as_read();
|
return Model\Item\mark_all_as_read();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get all items with the content
|
// Get all items with the content
|
||||||
$server->register('item.get_all', function() {
|
$server->register('item.get_all', function() {
|
||||||
|
|
||||||
return Model\Item\get_all();
|
return Model\Item\get_all();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get all items since a date
|
// Get all items since a date
|
||||||
$server->register('item.get_all_since', function($timestamp) {
|
$server->register('item.get_all_since', function($timestamp) {
|
||||||
|
|
||||||
return Model\Item\get_all_since($timestamp);
|
return Model\Item\get_all_since($timestamp);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get all items id and status
|
// Get all items id and status
|
||||||
$server->register('item.get_all_status', function() {
|
$server->register('item.get_all_status', function() {
|
||||||
|
|
||||||
return Model\Item\get_all_status();
|
return Model\Item\get_all_status();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
27
vendor/composer/autoload_classmap.php
vendored
27
vendor/composer/autoload_classmap.php
vendored
@ -6,15 +6,28 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'JsonRPC\\AccessDeniedException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/AccessDeniedException.php',
|
|
||||||
'JsonRPC\\AuthenticationFailure' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Server.php',
|
|
||||||
'JsonRPC\\Client' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Client.php',
|
'JsonRPC\\Client' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Client.php',
|
||||||
'JsonRPC\\ConnectionFailureException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Client.php',
|
'JsonRPC\\Exception\\AccessDeniedException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/AccessDeniedException.php',
|
||||||
'JsonRPC\\InvalidJsonFormat' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Server.php',
|
'JsonRPC\\Exception\\AuthenticationFailureException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/AuthenticationFailureException.php',
|
||||||
'JsonRPC\\InvalidJsonRpcFormat' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Server.php',
|
'JsonRPC\\Exception\\ConnectionFailureException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/ConnectionFailureException.php',
|
||||||
'JsonRPC\\ResponseException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/ResponseException.php',
|
'JsonRPC\\Exception\\InvalidJsonFormatException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonFormatException.php',
|
||||||
|
'JsonRPC\\Exception\\InvalidJsonRpcFormatException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonRpcFormatException.php',
|
||||||
|
'JsonRPC\\Exception\\ResponseEncodingFailureException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/ResponseEncodingFailureException.php',
|
||||||
|
'JsonRPC\\Exception\\ResponseException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/ResponseException.php',
|
||||||
|
'JsonRPC\\Exception\\ServerErrorException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/ServerErrorException.php',
|
||||||
|
'JsonRPC\\HttpClient' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/HttpClient.php',
|
||||||
|
'JsonRPC\\ProcedureHandler' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/ProcedureHandler.php',
|
||||||
|
'JsonRPC\\Request\\BatchRequestParser' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Request/BatchRequestParser.php',
|
||||||
|
'JsonRPC\\Request\\RequestBuilder' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Request/RequestBuilder.php',
|
||||||
|
'JsonRPC\\Request\\RequestParser' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Request/RequestParser.php',
|
||||||
|
'JsonRPC\\Response\\ResponseBuilder' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Response/ResponseBuilder.php',
|
||||||
|
'JsonRPC\\Response\\ResponseParser' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Response/ResponseParser.php',
|
||||||
'JsonRPC\\Server' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Server.php',
|
'JsonRPC\\Server' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Server.php',
|
||||||
'JsonRPC\\ServerErrorException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Client.php',
|
'JsonRPC\\Validator\\HostValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/HostValidator.php',
|
||||||
|
'JsonRPC\\Validator\\JsonEncodingValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/JsonEncodingValidator.php',
|
||||||
|
'JsonRPC\\Validator\\JsonFormatValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/JsonFormatValidator.php',
|
||||||
|
'JsonRPC\\Validator\\RpcFormatValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/RpcFormatValidator.php',
|
||||||
|
'JsonRPC\\Validator\\UserValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/UserValidator.php',
|
||||||
'Pheanstalk\\Command' => $vendorDir . '/pda/pheanstalk/src/Command.php',
|
'Pheanstalk\\Command' => $vendorDir . '/pda/pheanstalk/src/Command.php',
|
||||||
'Pheanstalk\\Command\\AbstractCommand' => $vendorDir . '/pda/pheanstalk/src/Command/AbstractCommand.php',
|
'Pheanstalk\\Command\\AbstractCommand' => $vendorDir . '/pda/pheanstalk/src/Command/AbstractCommand.php',
|
||||||
'Pheanstalk\\Command\\BuryCommand' => $vendorDir . '/pda/pheanstalk/src/Command/BuryCommand.php',
|
'Pheanstalk\\Command\\BuryCommand' => $vendorDir . '/pda/pheanstalk/src/Command/BuryCommand.php',
|
||||||
|
76
vendor/composer/installed.json
vendored
76
vendor/composer/installed.json
vendored
@ -37,44 +37,6 @@
|
|||||||
"description": "Simple validator library",
|
"description": "Simple validator library",
|
||||||
"homepage": "https://github.com/fguillot/simpleValidator"
|
"homepage": "https://github.com/fguillot/simpleValidator"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "fguillot/json-rpc",
|
|
||||||
"version": "v1.0.2",
|
|
||||||
"version_normalized": "1.0.2.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/fguillot/JsonRPC.git",
|
|
||||||
"reference": "265cf039c2823f684349de78c0c03a597992bea9"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/fguillot/JsonRPC/zipball/265cf039c2823f684349de78c0c03a597992bea9",
|
|
||||||
"reference": "265cf039c2823f684349de78c0c03a597992bea9",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.4"
|
|
||||||
},
|
|
||||||
"time": "2015-09-12 16:27:13",
|
|
||||||
"type": "library",
|
|
||||||
"installation-source": "dist",
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"JsonRPC": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Frédéric Guillot"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Simple Json-RPC client/server library that just works",
|
|
||||||
"homepage": "https://github.com/fguillot/JsonRPC"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "fguillot/picodb",
|
"name": "fguillot/picodb",
|
||||||
"version": "v1.0.2",
|
"version": "v1.0.2",
|
||||||
@ -262,5 +224,43 @@
|
|||||||
"keywords": [
|
"keywords": [
|
||||||
"beanstalkd"
|
"beanstalkd"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fguillot/json-rpc",
|
||||||
|
"version": "v1.1.0",
|
||||||
|
"version_normalized": "1.1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/fguillot/JsonRPC.git",
|
||||||
|
"reference": "e915dab71940e7ac251955c785570048f460d332"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/fguillot/JsonRPC/zipball/e915dab71940e7ac251955c785570048f460d332",
|
||||||
|
"reference": "e915dab71940e7ac251955c785570048f460d332",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.4"
|
||||||
|
},
|
||||||
|
"time": "2016-04-27 02:48:10",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"JsonRPC": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Frédéric Guillot"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Simple Json-RPC client/server library that just works",
|
||||||
|
"homepage": "https://github.com/fguillot/JsonRPC"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace JsonRPC;
|
|
||||||
|
|
||||||
class AccessDeniedException extends \Exception
|
|
||||||
{
|
|
||||||
}
|
|
366
vendor/fguillot/json-rpc/src/JsonRPC/Client.php
vendored
366
vendor/fguillot/json-rpc/src/JsonRPC/Client.php
vendored
@ -3,12 +3,8 @@
|
|||||||
namespace JsonRPC;
|
namespace JsonRPC;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use RuntimeException;
|
use JsonRPC\Request\RequestBuilder;
|
||||||
use BadFunctionCallException;
|
use JsonRPC\Response\ResponseParser;
|
||||||
use InvalidArgumentException;
|
|
||||||
|
|
||||||
class ConnectionFailureException extends Exception {};
|
|
||||||
class ServerErrorException extends Exception {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JsonRPC client class
|
* JsonRPC client class
|
||||||
@ -18,105 +14,99 @@ class ServerErrorException extends Exception {};
|
|||||||
*/
|
*/
|
||||||
class Client
|
class Client
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* URL of the server
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $url;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the only argument passed to a function is an array
|
* If the only argument passed to a function is an array
|
||||||
* assume it contains named arguments
|
* assume it contains named arguments
|
||||||
*
|
*
|
||||||
|
* @access private
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
private $isNamedArguments = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not immediately throw an exception on error. Return it instead.
|
||||||
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
public $named_arguments = true;
|
private $returnException = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* HTTP client timeout
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @var integer
|
|
||||||
*/
|
|
||||||
private $timeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Username for authentication
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $username;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Password for authentication
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $password;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True for a batch request
|
* True for a batch request
|
||||||
*
|
*
|
||||||
* @access public
|
* @access private
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*/
|
*/
|
||||||
public $is_batch = false;
|
private $isBatch = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Batch payload
|
* Batch payload
|
||||||
*
|
*
|
||||||
* @access public
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $batch = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable debug output to the php error log
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @var boolean
|
|
||||||
*/
|
|
||||||
public $debug = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default HTTP headers to send to the server
|
|
||||||
*
|
|
||||||
* @access private
|
* @access private
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $headers = array(
|
private $batch = array();
|
||||||
'User-Agent: JSON-RPC PHP Client <https://github.com/fguillot/JsonRPC>',
|
|
||||||
'Content-Type: application/json',
|
|
||||||
'Accept: application/json',
|
|
||||||
'Connection: close',
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SSL certificates verification
|
* Http Client
|
||||||
*
|
*
|
||||||
* @access public
|
* @access private
|
||||||
* @var boolean
|
* @var HttpClient
|
||||||
*/
|
*/
|
||||||
public $ssl_verify_peer = true;
|
private $httpClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $url Server URL
|
* @param string $url Server URL
|
||||||
* @param integer $timeout HTTP timeout
|
* @param bool $returnException Return exceptions
|
||||||
* @param array $headers Custom HTTP headers
|
* @param HttpClient $httpClient HTTP client object
|
||||||
*/
|
*/
|
||||||
public function __construct($url, $timeout = 3, $headers = array())
|
public function __construct($url = '', $returnException = false, HttpClient $httpClient = null)
|
||||||
{
|
{
|
||||||
$this->url = $url;
|
$this->httpClient = $httpClient ?: new HttpClient($url);
|
||||||
$this->timeout = $timeout;
|
$this->returnException = $returnException;
|
||||||
$this->headers = array_merge($this->headers, $headers);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arguments passed are always positional
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withPositionalArguments()
|
||||||
|
{
|
||||||
|
$this->isNamedArguments = false;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get HTTP Client
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return HttpClient
|
||||||
|
*/
|
||||||
|
public function getHttpClient()
|
||||||
|
{
|
||||||
|
return $this->httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set username and password
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function authentication($username, $password)
|
||||||
|
{
|
||||||
|
$this->httpClient
|
||||||
|
->withUsername($username)
|
||||||
|
->withPassword($password);
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,30 +119,13 @@ class Client
|
|||||||
*/
|
*/
|
||||||
public function __call($method, array $params)
|
public function __call($method, array $params)
|
||||||
{
|
{
|
||||||
// Allow to pass an array and use named arguments
|
if ($this->isNamedArguments && count($params) === 1 && is_array($params[0])) {
|
||||||
if ($this->named_arguments && count($params) === 1 && is_array($params[0])) {
|
|
||||||
$params = $params[0];
|
$params = $params[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->execute($method, $params);
|
return $this->execute($method, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set authentication parameters
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param string $username Username
|
|
||||||
* @param string $password Password
|
|
||||||
* @return Client
|
|
||||||
*/
|
|
||||||
public function authentication($username, $password)
|
|
||||||
{
|
|
||||||
$this->username = $username;
|
|
||||||
$this->password = $password;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a batch request
|
* Start a batch request
|
||||||
*
|
*
|
||||||
@ -161,9 +134,8 @@ class Client
|
|||||||
*/
|
*/
|
||||||
public function batch()
|
public function batch()
|
||||||
{
|
{
|
||||||
$this->is_batch = true;
|
$this->isBatch = true;
|
||||||
$this->batch = array();
|
$this->batch = array();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,11 +147,8 @@ class Client
|
|||||||
*/
|
*/
|
||||||
public function send()
|
public function send()
|
||||||
{
|
{
|
||||||
$this->is_batch = false;
|
$this->isBatch = false;
|
||||||
|
return $this->sendPayload('['.implode(', ', $this->batch).']');
|
||||||
return $this->parseResponse(
|
|
||||||
$this->doRequest($this->batch)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,198 +161,41 @@ class Client
|
|||||||
*/
|
*/
|
||||||
public function execute($procedure, array $params = array())
|
public function execute($procedure, array $params = array())
|
||||||
{
|
{
|
||||||
if ($this->is_batch) {
|
$payload = RequestBuilder::create()
|
||||||
$this->batch[] = $this->prepareRequest($procedure, $params);
|
->withProcedure($procedure)
|
||||||
|
->withParams($params)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
if ($this->isBatch) {
|
||||||
|
$this->batch[] = $payload;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->parseResponse(
|
return $this->sendPayload($payload);
|
||||||
$this->doRequest($this->prepareRequest($procedure, $params))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the payload
|
* Send payload
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param string $procedure Procedure name
|
|
||||||
* @param array $params Procedure arguments
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function prepareRequest($procedure, array $params = array())
|
|
||||||
{
|
|
||||||
$payload = array(
|
|
||||||
'jsonrpc' => '2.0',
|
|
||||||
'method' => $procedure,
|
|
||||||
'id' => mt_rand()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (! empty($params)) {
|
|
||||||
$payload['params'] = $params;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the response and return the procedure result
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $payload
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function parseResponse(array $payload)
|
|
||||||
{
|
|
||||||
if ($this->isBatchResponse($payload)) {
|
|
||||||
$results = array();
|
|
||||||
|
|
||||||
foreach ($payload as $response) {
|
|
||||||
$results[] = $this->getResult($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getResult($payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Throw an exception according the RPC error
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $error
|
|
||||||
* @throws BadFunctionCallException
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws RuntimeException
|
|
||||||
*/
|
|
||||||
public function handleRpcErrors(array $error)
|
|
||||||
{
|
|
||||||
switch ($error['code']) {
|
|
||||||
case -32601:
|
|
||||||
throw new BadFunctionCallException('Procedure not found: '. $error['message']);
|
|
||||||
case -32602:
|
|
||||||
throw new ResponseException(
|
|
||||||
'Invalid arguments: '. $error['message'],
|
|
||||||
$error['code'],
|
|
||||||
null,
|
|
||||||
isset($error['data']) ? $error['data'] : null
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
throw new RuntimeException('Invalid request/response: '. $error['message'], $error['code']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Throw an exception according the HTTP response
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $headers
|
|
||||||
* @throws AccessDeniedException
|
|
||||||
* @throws ServerErrorException
|
|
||||||
*/
|
|
||||||
public function handleHttpErrors(array $headers)
|
|
||||||
{
|
|
||||||
$exceptions = array(
|
|
||||||
'401' => 'JsonRPC\AccessDeniedException',
|
|
||||||
'403' => 'JsonRPC\AccessDeniedException',
|
|
||||||
'404' => 'JsonRPC\ConnectionFailureException',
|
|
||||||
'500' => 'JsonRPC\ServerErrorException',
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($headers as $header) {
|
|
||||||
foreach ($exceptions as $code => $exception) {
|
|
||||||
if (strpos($header, 'HTTP/1.0 '.$code) !== false || strpos($header, 'HTTP/1.1 '.$code) !== false) {
|
|
||||||
throw new $exception('Response: '.$header);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do the HTTP request
|
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param array $payload
|
* @throws Exception
|
||||||
* @return array
|
* @param string $payload
|
||||||
|
* @return Exception|Client
|
||||||
*/
|
*/
|
||||||
private function doRequest(array $payload)
|
private function sendPayload($payload)
|
||||||
{
|
{
|
||||||
$stream = @fopen(trim($this->url), 'r', false, $this->getContext($payload));
|
try {
|
||||||
|
|
||||||
if (! is_resource($stream)) {
|
return ResponseParser::create()
|
||||||
throw new ConnectionFailureException('Unable to establish a connection');
|
->withPayload($this->httpClient->execute($payload))
|
||||||
|
->parse();
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
if ($this->returnException) {
|
||||||
|
return $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadata = stream_get_meta_data($stream);
|
throw $e;
|
||||||
$this->handleHttpErrors($metadata['wrapper_data']);
|
|
||||||
|
|
||||||
$response = json_decode(stream_get_contents($stream), true);
|
|
||||||
|
|
||||||
if ($this->debug) {
|
|
||||||
error_log('==> Request: '.PHP_EOL.json_encode($payload, JSON_PRETTY_PRINT));
|
|
||||||
error_log('==> Response: '.PHP_EOL.json_encode($response, JSON_PRETTY_PRINT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return is_array($response) ? $response : array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare stream context
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @param array $payload
|
|
||||||
* @return resource
|
|
||||||
*/
|
|
||||||
private function getContext(array $payload)
|
|
||||||
{
|
|
||||||
$headers = $this->headers;
|
|
||||||
|
|
||||||
if (! empty($this->username) && ! empty($this->password)) {
|
|
||||||
$headers[] = 'Authorization: Basic '.base64_encode($this->username.':'.$this->password);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stream_context_create(array(
|
|
||||||
'http' => array(
|
|
||||||
'method' => 'POST',
|
|
||||||
'protocol_version' => 1.1,
|
|
||||||
'timeout' => $this->timeout,
|
|
||||||
'max_redirects' => 2,
|
|
||||||
'header' => implode("\r\n", $headers),
|
|
||||||
'content' => json_encode($payload),
|
|
||||||
'ignore_errors' => true,
|
|
||||||
),
|
|
||||||
"ssl" => array(
|
|
||||||
"verify_peer" => $this->ssl_verify_peer,
|
|
||||||
"verify_peer_name" => $this->ssl_verify_peer,
|
|
||||||
)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if we have a batch response
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $payload
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
private function isBatchResponse(array $payload)
|
|
||||||
{
|
|
||||||
return array_keys($payload) === range(0, count($payload) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a RPC call result
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @param array $payload
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
private function getResult(array $payload)
|
|
||||||
{
|
|
||||||
if (isset($payload['error']['code'])) {
|
|
||||||
$this->handleRpcErrors($payload['error']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return isset($payload['result']) ? $payload['result'] : null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/AccessDeniedException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/AccessDeniedException.php
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AccessDeniedException
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Exception
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class AccessDeniedException extends Exception
|
||||||
|
{
|
||||||
|
}
|
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/AuthenticationFailureException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/AuthenticationFailureException.php
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AuthenticationFailureException
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Exception
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class AuthenticationFailureException extends Exception
|
||||||
|
{
|
||||||
|
}
|
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ConnectionFailureException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ConnectionFailureException.php
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ConnectionFailureException
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Exception
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ConnectionFailureException extends Exception
|
||||||
|
{
|
||||||
|
}
|
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonFormatException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonFormatException.php
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class InvalidJsonFormatException
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Exception
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class InvalidJsonFormatException extends Exception
|
||||||
|
{
|
||||||
|
}
|
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonRpcFormatException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonRpcFormatException.php
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class InvalidJsonRpcFormatException
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Exception
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class InvalidJsonRpcFormatException extends Exception
|
||||||
|
{
|
||||||
|
}
|
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ResponseEncodingFailureException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ResponseEncodingFailureException.php
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ResponseEncodingFailureException
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Exception
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ResponseEncodingFailureException extends Exception
|
||||||
|
{
|
||||||
|
}
|
@ -1,13 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace JsonRPC;
|
namespace JsonRPC\Exception;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ResponseException
|
* Class ResponseException
|
||||||
*
|
*
|
||||||
* @package JsonRPC
|
* @package JsonRPC\Exception
|
||||||
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class ResponseException extends Exception
|
class ResponseException extends Exception
|
||||||
{
|
{
|
||||||
@ -40,7 +41,7 @@ class ResponseException extends Exception
|
|||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param mixed $data [optional] A value that contains additional information about the error.
|
* @param mixed $data [optional] A value that contains additional information about the error.
|
||||||
* @return \JsonRPC\ResponseException
|
* @return \JsonRPC\Exception\ResponseException
|
||||||
*/
|
*/
|
||||||
public function setData($data = null)
|
public function setData($data = null)
|
||||||
{
|
{
|
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ServerErrorException.php
vendored
Normal file
15
vendor/fguillot/json-rpc/src/JsonRPC/Exception/ServerErrorException.php
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ServerErrorException
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Exception
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ServerErrorException extends Exception
|
||||||
|
{
|
||||||
|
}
|
365
vendor/fguillot/json-rpc/src/JsonRPC/HttpClient.php
vendored
Normal file
365
vendor/fguillot/json-rpc/src/JsonRPC/HttpClient.php
vendored
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use JsonRPC\Exception\AccessDeniedException;
|
||||||
|
use JsonRPC\Exception\ConnectionFailureException;
|
||||||
|
use JsonRPC\Exception\ServerErrorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class HttpClient
|
||||||
|
*
|
||||||
|
* @package JsonRPC
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class HttpClient
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* URL of the server
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP client timeout
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $timeout = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default HTTP headers to send to the server
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $headers = array(
|
||||||
|
'User-Agent: JSON-RPC PHP Client <https://github.com/fguillot/JsonRPC>',
|
||||||
|
'Content-Type: application/json',
|
||||||
|
'Accept: application/json',
|
||||||
|
'Connection: close',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username for authentication
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $username;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password for authentication
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable debug output to the php error log
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
private $debug = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cookies
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $cookies = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSL certificates verification
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
private $verifySslCertificate = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback called before the doing the request
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var Closure
|
||||||
|
*/
|
||||||
|
private $beforeRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HttpClient constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $url
|
||||||
|
*/
|
||||||
|
public function __construct($url = '')
|
||||||
|
{
|
||||||
|
$this->url = $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set URL
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $url
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withUrl($url)
|
||||||
|
{
|
||||||
|
$this->url = $url;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set username
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $username
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withUsername($username)
|
||||||
|
{
|
||||||
|
$this->username = $username;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set password
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $password
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withPassword($password)
|
||||||
|
{
|
||||||
|
$this->password = $password;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set timeout
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $timeout
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withTimeout($timeout)
|
||||||
|
{
|
||||||
|
$this->timeout = $timeout;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set timeout
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $headers
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withHeaders(array $headers)
|
||||||
|
{
|
||||||
|
$this->headers = array_merge($this->headers, $headers);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set cookies
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $cookies
|
||||||
|
* @param boolean $replace
|
||||||
|
*/
|
||||||
|
public function withCookies(array $cookies, $replace = false)
|
||||||
|
{
|
||||||
|
if ($replace) {
|
||||||
|
$this->cookies = $cookies;
|
||||||
|
} else {
|
||||||
|
$this->cookies = array_merge($this->cookies, $cookies);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable debug mode
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withDebug()
|
||||||
|
{
|
||||||
|
$this->debug = true;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable SSL verification
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withoutSslVerification()
|
||||||
|
{
|
||||||
|
$this->verifySslCertificate = false;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a callback before the request
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param Closure $closure
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withBeforeRequestCallback(Closure $closure)
|
||||||
|
{
|
||||||
|
$this->beforeRequest = $closure;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cookies
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getCookies()
|
||||||
|
{
|
||||||
|
return $this->cookies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do the HTTP request
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @throws ConnectionFailureException
|
||||||
|
* @param string $payload
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function execute($payload)
|
||||||
|
{
|
||||||
|
if (is_callable($this->beforeRequest)) {
|
||||||
|
call_user_func_array($this->beforeRequest, array($this, $payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream = fopen(trim($this->url), 'r', false, $this->buildContext($payload));
|
||||||
|
|
||||||
|
if (! is_resource($stream)) {
|
||||||
|
throw new ConnectionFailureException('Unable to establish a connection');
|
||||||
|
}
|
||||||
|
|
||||||
|
$metadata = stream_get_meta_data($stream);
|
||||||
|
$headers = $metadata['wrapper_data'];
|
||||||
|
$response = json_decode(stream_get_contents($stream), true);
|
||||||
|
|
||||||
|
if ($this->debug) {
|
||||||
|
error_log('==> Request: '.PHP_EOL.json_encode($payload, JSON_PRETTY_PRINT));
|
||||||
|
error_log('==> Headers: '.PHP_EOL.var_export($headers, true));
|
||||||
|
error_log('==> Response: '.PHP_EOL.json_encode($response, JSON_PRETTY_PRINT));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->handleExceptions($headers);
|
||||||
|
$this->parseCookies($headers);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare stream context
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $payload
|
||||||
|
* @return resource
|
||||||
|
*/
|
||||||
|
private function buildContext($payload)
|
||||||
|
{
|
||||||
|
$headers = $this->headers;
|
||||||
|
|
||||||
|
if (! empty($this->username) && ! empty($this->password)) {
|
||||||
|
$headers[] = 'Authorization: Basic '.base64_encode($this->username.':'.$this->password);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! empty($this->cookies)){
|
||||||
|
$cookies = array();
|
||||||
|
|
||||||
|
foreach ($this->cookies as $key => $value) {
|
||||||
|
$cookies[] = $key.'='.$value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers[] = 'Cookie: '.implode('; ', $cookies);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream_context_create(array(
|
||||||
|
'http' => array(
|
||||||
|
'method' => 'POST',
|
||||||
|
'protocol_version' => 1.1,
|
||||||
|
'timeout' => $this->timeout,
|
||||||
|
'max_redirects' => 2,
|
||||||
|
'header' => implode("\r\n", $headers),
|
||||||
|
'content' => $payload,
|
||||||
|
'ignore_errors' => true,
|
||||||
|
),
|
||||||
|
'ssl' => array(
|
||||||
|
'verify_peer' => $this->verifySslCertificate,
|
||||||
|
'verify_peer_name' => $this->verifySslCertificate,
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse cookies from response
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param array $headers
|
||||||
|
*/
|
||||||
|
private function parseCookies(array $headers)
|
||||||
|
{
|
||||||
|
foreach ($headers as $header) {
|
||||||
|
$pos = stripos($header, 'Set-Cookie:');
|
||||||
|
|
||||||
|
if ($pos !== false) {
|
||||||
|
$cookies = explode(';', substr($header, $pos + 11));
|
||||||
|
|
||||||
|
foreach ($cookies as $cookie) {
|
||||||
|
$item = explode('=', $cookie);
|
||||||
|
|
||||||
|
if (count($item) === 2) {
|
||||||
|
$name = trim($item[0]);
|
||||||
|
$value = $item[1];
|
||||||
|
$this->cookies[$name] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throw an exception according the HTTP response
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $headers
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* @throws ServerErrorException
|
||||||
|
*/
|
||||||
|
public function handleExceptions(array $headers)
|
||||||
|
{
|
||||||
|
$exceptions = array(
|
||||||
|
'401' => '\JsonRPC\Exception\AccessDeniedException',
|
||||||
|
'403' => '\JsonRPC\Exception\AccessDeniedException',
|
||||||
|
'404' => '\JsonRPC\Exception\ConnectionFailureException',
|
||||||
|
'500' => '\JsonRPC\Exception\ServerErrorException',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($headers as $header) {
|
||||||
|
foreach ($exceptions as $code => $exception) {
|
||||||
|
if (strpos($header, 'HTTP/1.0 '.$code) !== false || strpos($header, 'HTTP/1.1 '.$code) !== false) {
|
||||||
|
throw new $exception('Response: '.$header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
304
vendor/fguillot/json-rpc/src/JsonRPC/ProcedureHandler.php
vendored
Normal file
304
vendor/fguillot/json-rpc/src/JsonRPC/ProcedureHandler.php
vendored
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC;
|
||||||
|
|
||||||
|
use BadFunctionCallException;
|
||||||
|
use Closure;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use ReflectionFunction;
|
||||||
|
use ReflectionMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ProcedureHandler
|
||||||
|
*
|
||||||
|
* @package JsonRPC
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ProcedureHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* List of procedures
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $callbacks = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of classes
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $classes = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of instances
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $instances = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method name to execute before the procedure
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $before = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $username;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set username
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $username
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withUsername($username)
|
||||||
|
{
|
||||||
|
$this->username = $username;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set password
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $password
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withPassword($password)
|
||||||
|
{
|
||||||
|
$this->password = $password;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new procedure
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $procedure Procedure name
|
||||||
|
* @param closure $callback Callback
|
||||||
|
* @return Server
|
||||||
|
*/
|
||||||
|
public function withCallback($procedure, Closure $callback)
|
||||||
|
{
|
||||||
|
$this->callbacks[$procedure] = $callback;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind a procedure to a class
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $procedure Procedure name
|
||||||
|
* @param mixed $class Class name or instance
|
||||||
|
* @param string $method Procedure name
|
||||||
|
* @return Server
|
||||||
|
*/
|
||||||
|
public function withClassAndMethod($procedure, $class, $method = '')
|
||||||
|
{
|
||||||
|
if ($method === '') {
|
||||||
|
$method = $procedure;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->classes[$procedure] = array($class, $method);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind a class instance
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $instance
|
||||||
|
* @return Server
|
||||||
|
*/
|
||||||
|
public function withObject($instance)
|
||||||
|
{
|
||||||
|
$this->instances[] = $instance;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach a method that will be called before the procedure
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $before
|
||||||
|
* @return Server
|
||||||
|
*/
|
||||||
|
public function withBeforeMethod($before)
|
||||||
|
{
|
||||||
|
$this->before = $before;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the procedure
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $procedure Procedure name
|
||||||
|
* @param array $params Procedure params
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function executeProcedure($procedure, array $params = array())
|
||||||
|
{
|
||||||
|
if (isset($this->callbacks[$procedure])) {
|
||||||
|
return $this->executeCallback($this->callbacks[$procedure], $params);
|
||||||
|
}
|
||||||
|
else if (isset($this->classes[$procedure]) && method_exists($this->classes[$procedure][0], $this->classes[$procedure][1])) {
|
||||||
|
return $this->executeMethod($this->classes[$procedure][0], $this->classes[$procedure][1], $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->instances as $instance) {
|
||||||
|
if (method_exists($instance, $procedure)) {
|
||||||
|
return $this->executeMethod($instance, $procedure, $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new BadFunctionCallException('Unable to find the procedure');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a callback
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param Closure $callback Callback
|
||||||
|
* @param array $params Procedure params
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function executeCallback(Closure $callback, $params)
|
||||||
|
{
|
||||||
|
$reflection = new ReflectionFunction($callback);
|
||||||
|
|
||||||
|
$arguments = $this->getArguments(
|
||||||
|
$params,
|
||||||
|
$reflection->getParameters(),
|
||||||
|
$reflection->getNumberOfRequiredParameters(),
|
||||||
|
$reflection->getNumberOfParameters()
|
||||||
|
);
|
||||||
|
|
||||||
|
return $reflection->invokeArgs($arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a method
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $class Class name or instance
|
||||||
|
* @param string $method Method name
|
||||||
|
* @param array $params Procedure params
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function executeMethod($class, $method, $params)
|
||||||
|
{
|
||||||
|
$instance = is_string($class) ? new $class : $class;
|
||||||
|
|
||||||
|
// Execute before action
|
||||||
|
if (! empty($this->before)) {
|
||||||
|
if (is_callable($this->before)) {
|
||||||
|
call_user_func_array($this->before, array($this->username, $this->password, get_class($class), $method));
|
||||||
|
}
|
||||||
|
else if (method_exists($instance, $this->before)) {
|
||||||
|
$instance->{$this->before}($this->username, $this->password, get_class($class), $method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$reflection = new ReflectionMethod($class, $method);
|
||||||
|
|
||||||
|
$arguments = $this->getArguments(
|
||||||
|
$params,
|
||||||
|
$reflection->getParameters(),
|
||||||
|
$reflection->getNumberOfRequiredParameters(),
|
||||||
|
$reflection->getNumberOfParameters()
|
||||||
|
);
|
||||||
|
|
||||||
|
return $reflection->invokeArgs($instance, $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get procedure arguments
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $request_params Incoming arguments
|
||||||
|
* @param array $method_params Procedure arguments
|
||||||
|
* @param integer $nb_required_params Number of required parameters
|
||||||
|
* @param integer $nb_max_params Maximum number of parameters
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getArguments(array $request_params, array $method_params, $nb_required_params, $nb_max_params)
|
||||||
|
{
|
||||||
|
$nb_params = count($request_params);
|
||||||
|
|
||||||
|
if ($nb_params < $nb_required_params) {
|
||||||
|
throw new InvalidArgumentException('Wrong number of arguments');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($nb_params > $nb_max_params) {
|
||||||
|
throw new InvalidArgumentException('Too many arguments');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isPositionalArguments($request_params)) {
|
||||||
|
return $request_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getNamedArguments($request_params, $method_params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if we have positional parameters
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $request_params Incoming arguments
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isPositionalArguments(array $request_params)
|
||||||
|
{
|
||||||
|
return array_keys($request_params) === range(0, count($request_params) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get named arguments
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $request_params Incoming arguments
|
||||||
|
* @param array $method_params Procedure arguments
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getNamedArguments(array $request_params, array $method_params)
|
||||||
|
{
|
||||||
|
$params = array();
|
||||||
|
|
||||||
|
foreach ($method_params as $p) {
|
||||||
|
$name = $p->getName();
|
||||||
|
|
||||||
|
if (isset($request_params[$name])) {
|
||||||
|
$params[$name] = $request_params[$name];
|
||||||
|
}
|
||||||
|
else if ($p->isDefaultValueAvailable()) {
|
||||||
|
$params[$name] = $p->getDefaultValue();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new InvalidArgumentException('Missing argument: '.$name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
}
|
46
vendor/fguillot/json-rpc/src/JsonRPC/Request/BatchRequestParser.php
vendored
Normal file
46
vendor/fguillot/json-rpc/src/JsonRPC/Request/BatchRequestParser.php
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class BatchRequestParser
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Request
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class BatchRequestParser extends RequestParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Parse incoming request
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function parse()
|
||||||
|
{
|
||||||
|
$responses = array();
|
||||||
|
|
||||||
|
foreach ($this->payload as $payload) {
|
||||||
|
$responses[] = RequestParser::create()
|
||||||
|
->withPayload($payload)
|
||||||
|
->withProcedureHandler($this->procedureHandler)
|
||||||
|
->parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
$responses = array_filter($responses);
|
||||||
|
return empty($responses) ? '' : '['.implode(',', $responses).']';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if we have a batch request
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param array $payload
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isBatchRequest(array $payload)
|
||||||
|
{
|
||||||
|
return is_array($payload) && array_keys($payload) === range(0, count($payload) - 1);
|
||||||
|
}
|
||||||
|
}
|
108
vendor/fguillot/json-rpc/src/JsonRPC/Request/RequestBuilder.php
vendored
Normal file
108
vendor/fguillot/json-rpc/src/JsonRPC/Request/RequestBuilder.php
vendored
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RequestBuilder
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Request
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class RequestBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Request ID
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
private $id = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method name
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $procedure = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method arguments
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $params = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get new object instance
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @return RequestBuilder
|
||||||
|
*/
|
||||||
|
public static function create()
|
||||||
|
{
|
||||||
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set id
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param null $id
|
||||||
|
* @return RequestBuilder
|
||||||
|
*/
|
||||||
|
public function withId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set method
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $procedure
|
||||||
|
* @return RequestBuilder
|
||||||
|
*/
|
||||||
|
public function withProcedure($procedure)
|
||||||
|
{
|
||||||
|
$this->procedure = $procedure;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set parameters
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $params
|
||||||
|
* @return RequestBuilder
|
||||||
|
*/
|
||||||
|
public function withParams(array $params)
|
||||||
|
{
|
||||||
|
$this->params = $params;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the payload
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
$payload = array(
|
||||||
|
'jsonrpc' => '2.0',
|
||||||
|
'method' => $this->procedure,
|
||||||
|
'id' => $this->id ?: mt_rand(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! empty($this->params)) {
|
||||||
|
$payload['params'] = $this->params;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_encode($payload);
|
||||||
|
}
|
||||||
|
}
|
129
vendor/fguillot/json-rpc/src/JsonRPC/Request/RequestParser.php
vendored
Normal file
129
vendor/fguillot/json-rpc/src/JsonRPC/Request/RequestParser.php
vendored
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Request;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use JsonRPC\Exception\AccessDeniedException;
|
||||||
|
use JsonRPC\Exception\AuthenticationFailureException;
|
||||||
|
use JsonRPC\Exception\InvalidJsonRpcFormatException;
|
||||||
|
use JsonRPC\ProcedureHandler;
|
||||||
|
use JsonRPC\Response\ResponseBuilder;
|
||||||
|
use JsonRPC\Validator\JsonFormatValidator;
|
||||||
|
use JsonRPC\Validator\RpcFormatValidator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RequestParser
|
||||||
|
*
|
||||||
|
* @package JsonRPC
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class RequestParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Request payload
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $payload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProcedureHandler
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @var ProcedureHandler
|
||||||
|
*/
|
||||||
|
protected $procedureHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get new object instance
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @return RequestParser
|
||||||
|
*/
|
||||||
|
public static function create()
|
||||||
|
{
|
||||||
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set payload
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $payload
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withPayload($payload)
|
||||||
|
{
|
||||||
|
$this->payload = $payload;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set procedure handler
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param ProcedureHandler $procedureHandler
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withProcedureHandler(ProcedureHandler $procedureHandler)
|
||||||
|
{
|
||||||
|
$this->procedureHandler = $procedureHandler;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse incoming request
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* @throws AuthenticationFailureException
|
||||||
|
*/
|
||||||
|
public function parse()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
JsonFormatValidator::validate($this->payload);
|
||||||
|
RpcFormatValidator::validate($this->payload);
|
||||||
|
|
||||||
|
$result = $this->procedureHandler->executeProcedure(
|
||||||
|
$this->payload['method'],
|
||||||
|
empty($this->payload['params']) ? array() : $this->payload['params']
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! $this->isNotification()) {
|
||||||
|
return ResponseBuilder::create()
|
||||||
|
->withId($this->payload['id'])
|
||||||
|
->withResult($result)
|
||||||
|
->build();
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
|
||||||
|
if ($e instanceof AccessDeniedException || $e instanceof AuthenticationFailureException) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($e instanceof InvalidJsonRpcFormatException || ! $this->isNotification()) {
|
||||||
|
return ResponseBuilder::create()
|
||||||
|
->withId(isset($this->payload['id']) ? $this->payload['id'] : null)
|
||||||
|
->withException($e)
|
||||||
|
->build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the message is a notification
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isNotification()
|
||||||
|
{
|
||||||
|
return is_array($this->payload) && !isset($this->payload['id']);
|
||||||
|
}
|
||||||
|
}
|
324
vendor/fguillot/json-rpc/src/JsonRPC/Response/ResponseBuilder.php
vendored
Normal file
324
vendor/fguillot/json-rpc/src/JsonRPC/Response/ResponseBuilder.php
vendored
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Response;
|
||||||
|
|
||||||
|
use BadFunctionCallException;
|
||||||
|
use Exception;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use JsonRPC\Exception\AccessDeniedException;
|
||||||
|
use JsonRPC\Exception\AuthenticationFailureException;
|
||||||
|
use JsonRPC\Exception\InvalidJsonFormatException;
|
||||||
|
use JsonRPC\Exception\InvalidJsonRpcFormatException;
|
||||||
|
use JsonRPC\Exception\ResponseEncodingFailureException;
|
||||||
|
use JsonRPC\Exception\ResponseException;
|
||||||
|
use JsonRPC\Validator\JsonEncodingValidator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ResponseBuilder
|
||||||
|
*
|
||||||
|
* @package JsonRPC
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ResponseBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Payload ID
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payload ID
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
private $result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payload error code
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $errorCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payload error message
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $errorMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payload error data
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
private $errorData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP Headers
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $headers = array(
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP status
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var ResponseException
|
||||||
|
*/
|
||||||
|
private $exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get new object instance
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @return ResponseBuilder
|
||||||
|
*/
|
||||||
|
public static function create()
|
||||||
|
{
|
||||||
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set id
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $id
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set result
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $result
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withResult($result)
|
||||||
|
{
|
||||||
|
$this->result = $result;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set error
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $code
|
||||||
|
* @param string $message
|
||||||
|
* @param string $data
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withError($code, $message, $data = '')
|
||||||
|
{
|
||||||
|
$this->errorCode = $code;
|
||||||
|
$this->errorMessage = $message;
|
||||||
|
$this->errorData = $data;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set exception
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param Exception $exception
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withException(Exception $exception)
|
||||||
|
{
|
||||||
|
$this->exception = $exception;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add HTTP header
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $name
|
||||||
|
* @param string $value
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withHeader($name, $value)
|
||||||
|
{
|
||||||
|
$this->headers[$name] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add HTTP Status
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $status
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withStatus($status)
|
||||||
|
{
|
||||||
|
$this->status = $status;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get status
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getStatus()
|
||||||
|
{
|
||||||
|
return $this->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get headers
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getHeaders()
|
||||||
|
{
|
||||||
|
return $this->headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build response
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
$encodedResponse = json_encode($this->buildResponse());
|
||||||
|
JsonEncodingValidator::validate();
|
||||||
|
|
||||||
|
return $encodedResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send HTTP headers
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function sendHeaders()
|
||||||
|
{
|
||||||
|
if (! empty($this->status)) {
|
||||||
|
header($this->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->headers as $name => $value) {
|
||||||
|
header($name.': '.$value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build response payload
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function buildResponse()
|
||||||
|
{
|
||||||
|
$response = array('jsonrpc' => '2.0');
|
||||||
|
$this->handleExceptions();
|
||||||
|
|
||||||
|
if (! empty($this->errorMessage)) {
|
||||||
|
$response['error'] = $this->buildErrorResponse();
|
||||||
|
} else {
|
||||||
|
$response['result'] = $this->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response['id'] = $this->id;
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build response error payload
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function buildErrorResponse()
|
||||||
|
{
|
||||||
|
$response = array(
|
||||||
|
'code' => $this->errorCode,
|
||||||
|
'message' => $this->errorMessage,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! empty($this->errorData)) {
|
||||||
|
$response['data'] = $this->errorData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform exceptions to JSON-RPC errors
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
private function handleExceptions()
|
||||||
|
{
|
||||||
|
if ($this->exception instanceof InvalidJsonFormatException) {
|
||||||
|
$this->errorCode = -32700;
|
||||||
|
$this->errorMessage = 'Parse error';
|
||||||
|
$this->id = null;
|
||||||
|
} elseif ($this->exception instanceof InvalidJsonRpcFormatException) {
|
||||||
|
$this->errorCode = -32600;
|
||||||
|
$this->errorMessage = 'Invalid Request';
|
||||||
|
$this->id = null;
|
||||||
|
} elseif ($this->exception instanceof BadFunctionCallException) {
|
||||||
|
$this->errorCode = -32601;
|
||||||
|
$this->errorMessage = 'Method not found';
|
||||||
|
} elseif ($this->exception instanceof InvalidArgumentException) {
|
||||||
|
$this->errorCode = -32602;
|
||||||
|
$this->errorMessage = 'Invalid params';
|
||||||
|
} elseif ($this->exception instanceof ResponseEncodingFailureException) {
|
||||||
|
$this->errorCode = -32603;
|
||||||
|
$this->errorMessage = 'Internal error';
|
||||||
|
$this->errorData = $this->exception->getMessage();
|
||||||
|
} elseif ($this->exception instanceof AuthenticationFailureException) {
|
||||||
|
$this->errorCode = 401;
|
||||||
|
$this->errorMessage = 'Unauthorized';
|
||||||
|
$this->status = 'HTTP/1.0 401 Unauthorized';
|
||||||
|
$this->withHeader('WWW-Authenticate', 'Basic realm="JsonRPC"');
|
||||||
|
} elseif ($this->exception instanceof AccessDeniedException) {
|
||||||
|
$this->errorCode = 403;
|
||||||
|
$this->errorMessage = 'Forbidden';
|
||||||
|
$this->status = 'HTTP/1.0 403 Forbidden';
|
||||||
|
} elseif ($this->exception instanceof ResponseException) {
|
||||||
|
$this->errorCode = $this->exception->getCode();
|
||||||
|
$this->errorMessage = $this->exception->getMessage();
|
||||||
|
$this->errorData = $this->exception->getData();
|
||||||
|
} elseif ($this->exception instanceof Exception) {
|
||||||
|
$this->errorCode = $this->exception->getCode();
|
||||||
|
$this->errorMessage = $this->exception->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
124
vendor/fguillot/json-rpc/src/JsonRPC/Response/ResponseParser.php
vendored
Normal file
124
vendor/fguillot/json-rpc/src/JsonRPC/Response/ResponseParser.php
vendored
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Response;
|
||||||
|
|
||||||
|
use BadFunctionCallException;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use JsonRPC\Exception\InvalidJsonFormatException;
|
||||||
|
use JsonRPC\Exception\InvalidJsonRpcFormatException;
|
||||||
|
use JsonRPC\Exception\ResponseException;
|
||||||
|
use JsonRPC\Validator\JsonFormatValidator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ResponseParser
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Request
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ResponseParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Payload
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
private $payload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get new object instance
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @return ResponseParser
|
||||||
|
*/
|
||||||
|
public static function create()
|
||||||
|
{
|
||||||
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set payload
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $payload
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withPayload($payload)
|
||||||
|
{
|
||||||
|
$this->payload = $payload;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse response
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @throws InvalidJsonFormatException
|
||||||
|
* @throws InvalidJsonRpcFormatException
|
||||||
|
* @throws ResponseException
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function parse()
|
||||||
|
{
|
||||||
|
JsonFormatValidator::validate($this->payload);
|
||||||
|
|
||||||
|
if ($this->isBatchResponse()) {
|
||||||
|
$results = array();
|
||||||
|
|
||||||
|
foreach ($this->payload as $response) {
|
||||||
|
$results[] = self::create()
|
||||||
|
->withPayload($response)
|
||||||
|
->parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->payload['error']['code'])) {
|
||||||
|
$this->handleExceptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return isset($this->payload['result']) ? $this->payload['result'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle exceptions
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @throws InvalidJsonFormatException
|
||||||
|
* @throws InvalidJsonRpcFormatException
|
||||||
|
* @throws ResponseException
|
||||||
|
*/
|
||||||
|
private function handleExceptions()
|
||||||
|
{
|
||||||
|
switch ($this->payload['error']['code']) {
|
||||||
|
case -32700:
|
||||||
|
throw new InvalidJsonFormatException('Parse error: '.$this->payload['error']['message']);
|
||||||
|
case -32600:
|
||||||
|
throw new InvalidJsonRpcFormatException('Invalid Request: '.$this->payload['error']['message']);
|
||||||
|
case -32601:
|
||||||
|
throw new BadFunctionCallException('Procedure not found: '.$this->payload['error']['message']);
|
||||||
|
case -32602:
|
||||||
|
throw new InvalidArgumentException('Invalid arguments: '.$this->payload['error']['message']);
|
||||||
|
default:
|
||||||
|
throw new ResponseException(
|
||||||
|
$this->payload['error']['message'],
|
||||||
|
$this->payload['error']['code'],
|
||||||
|
null,
|
||||||
|
isset($this->payload['error']['data']) ? $this->payload['error']['data'] : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if we have a batch response
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private function isBatchResponse()
|
||||||
|
{
|
||||||
|
return array_keys($this->payload) === range(0, count($this->payload) - 1);
|
||||||
|
}
|
||||||
|
}
|
535
vendor/fguillot/json-rpc/src/JsonRPC/Server.php
vendored
535
vendor/fguillot/json-rpc/src/JsonRPC/Server.php
vendored
@ -3,16 +3,13 @@
|
|||||||
namespace JsonRPC;
|
namespace JsonRPC;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use BadFunctionCallException;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use InvalidArgumentException;
|
use JsonRPC\Request\BatchRequestParser;
|
||||||
use LogicException;
|
use JsonRPC\Request\RequestParser;
|
||||||
use ReflectionFunction;
|
use JsonRPC\Response\ResponseBuilder;
|
||||||
use ReflectionMethod;
|
use JsonRPC\Validator\HostValidator;
|
||||||
|
use JsonRPC\Validator\JsonFormatValidator;
|
||||||
class InvalidJsonRpcFormat extends Exception {};
|
use JsonRPC\Validator\UserValidator;
|
||||||
class InvalidJsonFormat extends Exception {};
|
|
||||||
class AuthenticationFailure extends Exception {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JsonRPC server class
|
* JsonRPC server class
|
||||||
@ -22,6 +19,14 @@ class AuthenticationFailure extends Exception {};
|
|||||||
*/
|
*/
|
||||||
class Server
|
class Server
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Allowed hosts
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $hosts = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data received from the client
|
* Data received from the client
|
||||||
*
|
*
|
||||||
@ -30,30 +35,6 @@ class Server
|
|||||||
*/
|
*/
|
||||||
private $payload = array();
|
private $payload = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* List of procedures
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $callbacks = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of classes
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $classes = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of instances
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $instances = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of exception classes that should be relayed to client
|
* List of exception classes that should be relayed to client
|
||||||
*
|
*
|
||||||
@ -62,14 +43,6 @@ class Server
|
|||||||
*/
|
*/
|
||||||
private $exceptions = array();
|
private $exceptions = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* Method name to execute before the procedure
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $before = '';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Username
|
* Username
|
||||||
*
|
*
|
||||||
@ -86,32 +59,47 @@ class Server
|
|||||||
*/
|
*/
|
||||||
private $password = '';
|
private $password = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allowed users
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $users = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* $_SERVER
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $serverVariable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProcedureHandler object
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var ProcedureHandler
|
||||||
|
*/
|
||||||
|
private $procedureHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $request
|
* @param string $request
|
||||||
|
* @param array $server
|
||||||
*/
|
*/
|
||||||
public function __construct($request = '')
|
public function __construct($request = '', array $server = array())
|
||||||
{
|
{
|
||||||
if ($request !== '') {
|
if ($request !== '') {
|
||||||
$this->payload = json_decode($request, true);
|
$this->payload = json_decode($request, true);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$this->payload = json_decode(file_get_contents('php://input'), true);
|
$this->payload = json_decode(file_get_contents('php://input'), true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
$this->serverVariable = $server ?: $_SERVER;
|
||||||
* Set a payload
|
$this->procedureHandler = new ProcedureHandler();
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $payload
|
|
||||||
* @return Server
|
|
||||||
*/
|
|
||||||
public function setPayload(array $payload)
|
|
||||||
{
|
|
||||||
$this->payload = $payload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,17 +112,28 @@ class Server
|
|||||||
public function setAuthenticationHeader($header)
|
public function setAuthenticationHeader($header)
|
||||||
{
|
{
|
||||||
if (! empty($header)) {
|
if (! empty($header)) {
|
||||||
|
|
||||||
$header = 'HTTP_'.str_replace('-', '_', strtoupper($header));
|
$header = 'HTTP_'.str_replace('-', '_', strtoupper($header));
|
||||||
|
$value = $this->getServerVariable($header);
|
||||||
|
|
||||||
if (isset($_SERVER[$header])) {
|
if (! empty($value)) {
|
||||||
list($this->username, $this->password) = explode(':', @base64_decode($_SERVER[$header]));
|
list($this->username, $this->password) = explode(':', base64_decode($value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get ProcedureHandler
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return ProcedureHandler
|
||||||
|
*/
|
||||||
|
public function getProcedureHandler()
|
||||||
|
{
|
||||||
|
return $this->procedureHandler;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get username
|
* Get username
|
||||||
*
|
*
|
||||||
@ -143,7 +142,7 @@ class Server
|
|||||||
*/
|
*/
|
||||||
public function getUsername()
|
public function getUsername()
|
||||||
{
|
{
|
||||||
return $this->username ?: @$_SERVER['PHP_AUTH_USER'];
|
return $this->username ?: $this->getServerVariable('PHP_AUTH_USER');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,66 +153,32 @@ class Server
|
|||||||
*/
|
*/
|
||||||
public function getPassword()
|
public function getPassword()
|
||||||
{
|
{
|
||||||
return $this->password ?: @$_SERVER['PHP_AUTH_PW'];
|
return $this->password ?: $this->getServerVariable('PHP_AUTH_PW');
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send authentication failure response
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public function sendAuthenticationFailureResponse()
|
|
||||||
{
|
|
||||||
header('WWW-Authenticate: Basic realm="JsonRPC"');
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
header('HTTP/1.0 401 Unauthorized');
|
|
||||||
echo '{"error": "Authentication failed"}';
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send forbidden response
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public function sendForbiddenResponse()
|
|
||||||
{
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
header('HTTP/1.0 403 Forbidden');
|
|
||||||
echo '{"error": "Access Forbidden"}';
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IP based client restrictions
|
* IP based client restrictions
|
||||||
*
|
*
|
||||||
* Return an HTTP error 403 if the client is not allowed
|
|
||||||
*
|
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $hosts List of hosts
|
* @param array $hosts List of hosts
|
||||||
|
* @return Server
|
||||||
*/
|
*/
|
||||||
public function allowHosts(array $hosts)
|
public function allowHosts(array $hosts)
|
||||||
{
|
{
|
||||||
if (! in_array($_SERVER['REMOTE_ADDR'], $hosts)) {
|
$this->hosts = $hosts;
|
||||||
$this->sendForbiddenResponse();
|
return $this;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP Basic authentication
|
* HTTP Basic authentication
|
||||||
*
|
*
|
||||||
* Return an HTTP error 401 if the client is not allowed
|
|
||||||
*
|
|
||||||
* @access public
|
* @access public
|
||||||
* @param array $users Map of username/password
|
* @param array $users Dictionary of username/password
|
||||||
* @return Server
|
* @return Server
|
||||||
*/
|
*/
|
||||||
public function authentication(array $users)
|
public function authentication(array $users)
|
||||||
{
|
{
|
||||||
if (! isset($users[$this->getUsername()]) || $users[$this->getUsername()] !== $this->getPassword()) {
|
$this->users = $users;
|
||||||
$this->sendAuthenticationFailureResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +192,7 @@ class Server
|
|||||||
*/
|
*/
|
||||||
public function register($procedure, Closure $callback)
|
public function register($procedure, Closure $callback)
|
||||||
{
|
{
|
||||||
$this->callbacks[$procedure] = $callback;
|
$this->procedureHandler->withCallback($procedure, $callback);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,11 +207,7 @@ class Server
|
|||||||
*/
|
*/
|
||||||
public function bind($procedure, $class, $method = '')
|
public function bind($procedure, $class, $method = '')
|
||||||
{
|
{
|
||||||
if ($method === '') {
|
$this->procedureHandler->withClassAndMethod($procedure, $class, $method);
|
||||||
$method = $procedure;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->classes[$procedure] = array($class, $method);
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +220,7 @@ class Server
|
|||||||
*/
|
*/
|
||||||
public function attach($instance)
|
public function attach($instance)
|
||||||
{
|
{
|
||||||
$this->instances[] = $instance;
|
$this->procedureHandler->withObject($instance);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,112 +247,10 @@ class Server
|
|||||||
*/
|
*/
|
||||||
public function before($before)
|
public function before($before)
|
||||||
{
|
{
|
||||||
$this->before = $before;
|
$this->procedureHandler->withBeforeMethod($before);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the response to the client
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $data Data to send to the client
|
|
||||||
* @param array $payload Incoming data
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getResponse(array $data, array $payload = array())
|
|
||||||
{
|
|
||||||
if (! array_key_exists('id', $payload)) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = array(
|
|
||||||
'jsonrpc' => '2.0',
|
|
||||||
'id' => $payload['id']
|
|
||||||
);
|
|
||||||
|
|
||||||
$response = array_merge($response, $data);
|
|
||||||
|
|
||||||
@header('Content-Type: application/json');
|
|
||||||
return json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the payload and test if the parsed JSON is ok
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function checkJsonFormat()
|
|
||||||
{
|
|
||||||
if (! is_array($this->payload)) {
|
|
||||||
throw new InvalidJsonFormat('Malformed payload');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test if all required JSON-RPC parameters are here
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function checkRpcFormat()
|
|
||||||
{
|
|
||||||
if (! isset($this->payload['jsonrpc']) ||
|
|
||||||
! isset($this->payload['method']) ||
|
|
||||||
! is_string($this->payload['method']) ||
|
|
||||||
$this->payload['jsonrpc'] !== '2.0' ||
|
|
||||||
(isset($this->payload['params']) && ! is_array($this->payload['params']))) {
|
|
||||||
|
|
||||||
throw new InvalidJsonRpcFormat('Invalid JSON RPC payload');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if we have a batch request
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
private function isBatchRequest()
|
|
||||||
{
|
|
||||||
return array_keys($this->payload) === range(0, count($this->payload) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle batch request
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function handleBatchRequest()
|
|
||||||
{
|
|
||||||
$responses = array();
|
|
||||||
|
|
||||||
foreach ($this->payload as $payload) {
|
|
||||||
|
|
||||||
if (! is_array($payload)) {
|
|
||||||
|
|
||||||
$responses[] = $this->getResponse(array(
|
|
||||||
'error' => array(
|
|
||||||
'code' => -32600,
|
|
||||||
'message' => 'Invalid Request'
|
|
||||||
)),
|
|
||||||
array('id' => null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
$server = clone($this);
|
|
||||||
$server->setPayload($payload);
|
|
||||||
$response = $server->execute();
|
|
||||||
|
|
||||||
if (! empty($response)) {
|
|
||||||
$responses[] = $response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return empty($responses) ? '' : '['.implode(',', $responses).']';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse incoming requests
|
* Parse incoming requests
|
||||||
*
|
*
|
||||||
@ -400,249 +259,57 @@ class Server
|
|||||||
*/
|
*/
|
||||||
public function execute()
|
public function execute()
|
||||||
{
|
{
|
||||||
|
$responseBuilder = ResponseBuilder::create();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
$this->procedureHandler
|
||||||
|
->withUsername($this->getUsername())
|
||||||
|
->withPassword($this->getPassword());
|
||||||
|
|
||||||
$this->checkJsonFormat();
|
JsonFormatValidator::validate($this->payload);
|
||||||
|
HostValidator::validate($this->hosts, $this->getServerVariable('REMOTE_ADDR'));
|
||||||
|
UserValidator::validate($this->users, $this->getUsername(), $this->getPassword());
|
||||||
|
|
||||||
if ($this->isBatchRequest()){
|
$response = $this->parseRequest();
|
||||||
return $this->handleBatchRequest();
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$response = $responseBuilder->withException($e)->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkRpcFormat();
|
$responseBuilder->sendHeaders();
|
||||||
|
return $response;
|
||||||
$result = $this->executeProcedure(
|
|
||||||
$this->payload['method'],
|
|
||||||
empty($this->payload['params']) ? array() : $this->payload['params']
|
|
||||||
);
|
|
||||||
|
|
||||||
return $this->getResponse(array('result' => $result), $this->payload);
|
|
||||||
}
|
|
||||||
catch (InvalidJsonFormat $e) {
|
|
||||||
|
|
||||||
return $this->getResponse(array(
|
|
||||||
'error' => array(
|
|
||||||
'code' => -32700,
|
|
||||||
'message' => 'Parse error'
|
|
||||||
)),
|
|
||||||
array('id' => null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (InvalidJsonRpcFormat $e) {
|
|
||||||
|
|
||||||
return $this->getResponse(array(
|
|
||||||
'error' => array(
|
|
||||||
'code' => -32600,
|
|
||||||
'message' => 'Invalid Request'
|
|
||||||
)),
|
|
||||||
array('id' => null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (BadFunctionCallException $e) {
|
|
||||||
|
|
||||||
return $this->getResponse(array(
|
|
||||||
'error' => array(
|
|
||||||
'code' => -32601,
|
|
||||||
'message' => 'Method not found'
|
|
||||||
)),
|
|
||||||
$this->payload
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (InvalidArgumentException $e) {
|
|
||||||
|
|
||||||
return $this->getResponse(array(
|
|
||||||
'error' => array(
|
|
||||||
'code' => -32602,
|
|
||||||
'message' => 'Invalid params'
|
|
||||||
)),
|
|
||||||
$this->payload
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (AuthenticationFailure $e) {
|
|
||||||
$this->sendAuthenticationFailureResponse();
|
|
||||||
}
|
|
||||||
catch (AccessDeniedException $e) {
|
|
||||||
$this->sendForbiddenResponse();
|
|
||||||
}
|
|
||||||
catch (ResponseException $e) {
|
|
||||||
return $this->getResponse(array(
|
|
||||||
'error' => array(
|
|
||||||
'code' => $e->getCode(),
|
|
||||||
'message' => $e->getMessage(),
|
|
||||||
'data' => $e->getData(),
|
|
||||||
)),
|
|
||||||
$this->payload
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
|
|
||||||
foreach ($this->exceptions as $class) {
|
|
||||||
if ($e instanceof $class) {
|
|
||||||
return $this->getResponse(array(
|
|
||||||
'error' => array(
|
|
||||||
'code' => $e->getCode(),
|
|
||||||
'message' => $e->getMessage()
|
|
||||||
)),
|
|
||||||
$this->payload
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the procedure
|
* Parse incoming request
|
||||||
*
|
*
|
||||||
* @access public
|
* @access private
|
||||||
* @param string $procedure Procedure name
|
* @return string
|
||||||
* @param array $params Procedure params
|
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
public function executeProcedure($procedure, array $params = array())
|
private function parseRequest()
|
||||||
{
|
{
|
||||||
if (isset($this->callbacks[$procedure])) {
|
if (BatchRequestParser::isBatchRequest($this->payload)) {
|
||||||
return $this->executeCallback($this->callbacks[$procedure], $params);
|
return BatchRequestParser::create()
|
||||||
}
|
->withPayload($this->payload)
|
||||||
else if (isset($this->classes[$procedure]) && method_exists($this->classes[$procedure][0], $this->classes[$procedure][1])) {
|
->withProcedureHandler($this->procedureHandler)
|
||||||
return $this->executeMethod($this->classes[$procedure][0], $this->classes[$procedure][1], $params);
|
->parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->instances as $instance) {
|
return RequestParser::create()
|
||||||
if (method_exists($instance, $procedure)) {
|
->withPayload($this->payload)
|
||||||
return $this->executeMethod($instance, $procedure, $params);
|
->withProcedureHandler($this->procedureHandler)
|
||||||
}
|
->parse();
|
||||||
}
|
|
||||||
|
|
||||||
throw new BadFunctionCallException('Unable to find the procedure');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a callback
|
* Check existence and get value of server variable
|
||||||
*
|
*
|
||||||
* @access public
|
* @access private
|
||||||
* @param Closure $callback Callback
|
* @param string $variable
|
||||||
* @param array $params Procedure params
|
* @return string|null
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
public function executeCallback(Closure $callback, $params)
|
private function getServerVariable($variable)
|
||||||
{
|
{
|
||||||
$reflection = new ReflectionFunction($callback);
|
return isset($this->serverVariable[$variable]) ? $this->serverVariable[$variable] : null;
|
||||||
|
|
||||||
$arguments = $this->getArguments(
|
|
||||||
$params,
|
|
||||||
$reflection->getParameters(),
|
|
||||||
$reflection->getNumberOfRequiredParameters(),
|
|
||||||
$reflection->getNumberOfParameters()
|
|
||||||
);
|
|
||||||
|
|
||||||
return $reflection->invokeArgs($arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a method
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param mixed $class Class name or instance
|
|
||||||
* @param string $method Method name
|
|
||||||
* @param array $params Procedure params
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function executeMethod($class, $method, $params)
|
|
||||||
{
|
|
||||||
$instance = is_string($class) ? new $class : $class;
|
|
||||||
|
|
||||||
// Execute before action
|
|
||||||
if (! empty($this->before)) {
|
|
||||||
if (is_callable($this->before)) {
|
|
||||||
call_user_func_array($this->before, array($this->getUsername(), $this->getPassword(), get_class($class), $method));
|
|
||||||
}
|
|
||||||
else if (method_exists($instance, $this->before)) {
|
|
||||||
$instance->{$this->before}($this->getUsername(), $this->getPassword(), get_class($class), $method);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$reflection = new ReflectionMethod($class, $method);
|
|
||||||
|
|
||||||
$arguments = $this->getArguments(
|
|
||||||
$params,
|
|
||||||
$reflection->getParameters(),
|
|
||||||
$reflection->getNumberOfRequiredParameters(),
|
|
||||||
$reflection->getNumberOfParameters()
|
|
||||||
);
|
|
||||||
|
|
||||||
return $reflection->invokeArgs($instance, $arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get procedure arguments
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $request_params Incoming arguments
|
|
||||||
* @param array $method_params Procedure arguments
|
|
||||||
* @param integer $nb_required_params Number of required parameters
|
|
||||||
* @param integer $nb_max_params Maximum number of parameters
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getArguments(array $request_params, array $method_params, $nb_required_params, $nb_max_params)
|
|
||||||
{
|
|
||||||
$nb_params = count($request_params);
|
|
||||||
|
|
||||||
if ($nb_params < $nb_required_params) {
|
|
||||||
throw new InvalidArgumentException('Wrong number of arguments');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($nb_params > $nb_max_params) {
|
|
||||||
throw new InvalidArgumentException('Too many arguments');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->isPositionalArguments($request_params, $method_params)) {
|
|
||||||
return $request_params;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getNamedArguments($request_params, $method_params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if we have positional parametes
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $request_params Incoming arguments
|
|
||||||
* @param array $method_params Procedure arguments
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isPositionalArguments(array $request_params, array $method_params)
|
|
||||||
{
|
|
||||||
return array_keys($request_params) === range(0, count($request_params) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get named arguments
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param array $request_params Incoming arguments
|
|
||||||
* @param array $method_params Procedure arguments
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getNamedArguments(array $request_params, array $method_params)
|
|
||||||
{
|
|
||||||
$params = array();
|
|
||||||
|
|
||||||
foreach ($method_params as $p) {
|
|
||||||
|
|
||||||
$name = $p->getName();
|
|
||||||
|
|
||||||
if (isset($request_params[$name])) {
|
|
||||||
$params[$name] = $request_params[$name];
|
|
||||||
}
|
|
||||||
else if ($p->isDefaultValueAvailable()) {
|
|
||||||
$params[$name] = $p->getDefaultValue();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new InvalidArgumentException('Missing argument: '.$name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $params;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
vendor/fguillot/json-rpc/src/JsonRPC/Validator/HostValidator.php
vendored
Normal file
30
vendor/fguillot/json-rpc/src/JsonRPC/Validator/HostValidator.php
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Validator;
|
||||||
|
|
||||||
|
use JsonRPC\Exception\AccessDeniedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class HostValidator
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Validator
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class HostValidator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Validate
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param array $hosts
|
||||||
|
* @param string $remoteAddress
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
*/
|
||||||
|
public static function validate(array $hosts, $remoteAddress)
|
||||||
|
{
|
||||||
|
if (! empty($hosts) && ! in_array($remoteAddress, $hosts)) {
|
||||||
|
throw new AccessDeniedException('Access Forbidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonEncodingValidator.php
vendored
Normal file
44
vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonEncodingValidator.php
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Validator;
|
||||||
|
|
||||||
|
use JsonRPC\Exception\ResponseEncodingFailureException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class JsonEncodingValidator
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Validator
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class JsonEncodingValidator
|
||||||
|
{
|
||||||
|
public static function validate()
|
||||||
|
{
|
||||||
|
$jsonError = json_last_error();
|
||||||
|
|
||||||
|
if ($jsonError !== JSON_ERROR_NONE) {
|
||||||
|
switch ($jsonError) {
|
||||||
|
case JSON_ERROR_DEPTH:
|
||||||
|
$errorMessage = 'Maximum stack depth exceeded';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_STATE_MISMATCH:
|
||||||
|
$errorMessage = 'Underflow or the modes mismatch';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_CTRL_CHAR:
|
||||||
|
$errorMessage = 'Unexpected control character found';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_SYNTAX:
|
||||||
|
$errorMessage = 'Syntax error, malformed JSON';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_UTF8:
|
||||||
|
$errorMessage = 'Malformed UTF-8 characters, possibly incorrectly encoded';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$errorMessage = 'Unknown error';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ResponseEncodingFailureException($errorMessage, $jsonError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonFormatValidator.php
vendored
Normal file
30
vendor/fguillot/json-rpc/src/JsonRPC/Validator/JsonFormatValidator.php
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Validator;
|
||||||
|
|
||||||
|
use JsonRPC\Exception\InvalidJsonFormatException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class JsonFormatValidator
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Validator
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class JsonFormatValidator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Validate
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param mixed $payload
|
||||||
|
* @throws InvalidJsonFormatException
|
||||||
|
*/
|
||||||
|
public static function validate($payload)
|
||||||
|
{
|
||||||
|
if (! is_array($payload)) {
|
||||||
|
throw new InvalidJsonFormatException('Malformed payload');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
35
vendor/fguillot/json-rpc/src/JsonRPC/Validator/RpcFormatValidator.php
vendored
Normal file
35
vendor/fguillot/json-rpc/src/JsonRPC/Validator/RpcFormatValidator.php
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Validator;
|
||||||
|
|
||||||
|
use JsonRPC\Exception\InvalidJsonRpcFormatException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RpcFormatValidator
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Validator
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class RpcFormatValidator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Validate
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param array $payload
|
||||||
|
* @throws InvalidJsonRpcFormatException
|
||||||
|
*/
|
||||||
|
public static function validate(array $payload)
|
||||||
|
{
|
||||||
|
if (! isset($payload['jsonrpc']) ||
|
||||||
|
! isset($payload['method']) ||
|
||||||
|
! is_string($payload['method']) ||
|
||||||
|
$payload['jsonrpc'] !== '2.0' ||
|
||||||
|
(isset($payload['params']) && ! is_array($payload['params']))) {
|
||||||
|
|
||||||
|
throw new InvalidJsonRpcFormatException('Invalid JSON RPC payload');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
21
vendor/fguillot/json-rpc/src/JsonRPC/Validator/UserValidator.php
vendored
Normal file
21
vendor/fguillot/json-rpc/src/JsonRPC/Validator/UserValidator.php
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonRPC\Validator;
|
||||||
|
|
||||||
|
use JsonRPC\Exception\AuthenticationFailureException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UserValidator
|
||||||
|
*
|
||||||
|
* @package JsonRPC\Validator
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class UserValidator
|
||||||
|
{
|
||||||
|
public static function validate(array $users, $username, $password)
|
||||||
|
{
|
||||||
|
if (! empty($users) && (! isset($users[$username]) || $users[$username] !== $password)) {
|
||||||
|
throw new AuthenticationFailureException('Access not allowed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user