miniflux-legacy/vendor/fguillot/json-rpc/src/JsonRPC/Server.php

387 lines
9.1 KiB
PHP
Raw Normal View History

<?php
namespace JsonRPC;
use Closure;
use Exception;
2016-05-08 21:53:45 +02:00
use JsonRPC\Request\BatchRequestParser;
use JsonRPC\Request\RequestParser;
use JsonRPC\Response\ResponseBuilder;
use JsonRPC\Validator\HostValidator;
use JsonRPC\Validator\JsonFormatValidator;
use JsonRPC\Validator\UserValidator;
/**
* JsonRPC server class
*
* @package JsonRPC
* @author Frederic Guillot
*/
class Server
{
/**
2016-05-08 21:53:45 +02:00
* Allowed hosts
*
2016-08-06 02:27:09 +02:00
* @access protected
2015-08-15 03:33:39 +02:00
* @var array
*/
2016-08-06 02:27:09 +02:00
protected $hosts = array();
/**
2016-05-08 21:53:45 +02:00
* Data received from the client
*
2016-08-06 02:27:09 +02:00
* @access protected
* @var array
*/
2016-08-06 02:27:09 +02:00
protected $payload = array();
/**
2016-08-06 02:27:09 +02:00
* List of exceptions that should not be relayed to the client
*
2016-08-06 02:27:09 +02:00
* @access protected
* @var array()
*/
2016-08-06 02:27:09 +02:00
protected $localExceptions = array();
2015-02-06 03:16:34 +01:00
/**
2016-05-08 21:53:45 +02:00
* Username
2015-02-06 03:16:34 +01:00
*
2016-08-06 02:27:09 +02:00
* @access protected
2016-05-08 21:53:45 +02:00
* @var string
2015-02-06 03:16:34 +01:00
*/
2016-08-06 02:27:09 +02:00
protected $username = '';
2015-02-06 03:16:34 +01:00
2015-06-21 15:56:36 +02:00
/**
2016-05-08 21:53:45 +02:00
* Password
2015-06-21 15:56:36 +02:00
*
2016-08-06 02:27:09 +02:00
* @access protected
2016-05-08 21:53:45 +02:00
* @var string
2015-06-21 15:56:36 +02:00
*/
2016-08-06 02:27:09 +02:00
protected $password = '';
2015-06-21 15:56:36 +02:00
/**
2016-05-08 21:53:45 +02:00
* Allowed users
2015-06-21 15:56:36 +02:00
*
2016-08-06 02:27:09 +02:00
* @access protected
2016-05-08 21:53:45 +02:00
* @var array
2015-06-21 15:56:36 +02:00
*/
2016-08-06 02:27:09 +02:00
protected $users = array();
2015-06-21 15:56:36 +02:00
/**
2016-05-08 21:53:45 +02:00
* $_SERVER
2015-06-21 15:56:36 +02:00
*
2016-08-06 02:27:09 +02:00
* @access protected
2016-05-08 21:53:45 +02:00
* @var array
2015-06-21 15:56:36 +02:00
*/
2016-08-06 02:27:09 +02:00
protected $serverVariable;
2015-06-21 15:56:36 +02:00
/**
2016-05-08 21:53:45 +02:00
* ProcedureHandler object
2015-06-21 15:56:36 +02:00
*
2016-08-06 02:27:09 +02:00
* @access protected
2016-05-08 21:53:45 +02:00
* @var ProcedureHandler
2015-06-21 15:56:36 +02:00
*/
2016-08-06 02:27:09 +02:00
protected $procedureHandler;
/**
* MiddlewareHandler object
*
* @access protected
* @var MiddlewareHandler
*/
protected $middlewareHandler;
/**
* Response builder
*
* @access protected
* @var ResponseBuilder
*/
protected $responseBuilder;
/**
* Response builder
*
* @access protected
* @var RequestParser
*/
protected $requestParser;
/**
*
* Batch request parser
*
* @access protected
* @var BatchRequestParser
*/
protected $batchRequestParser;
2015-06-21 15:56:36 +02:00
/**
* Constructor
*
* @access public
2016-08-06 02:27:09 +02:00
* @param string $request
* @param array $server
* @param ResponseBuilder $responseBuilder
* @param RequestParser $requestParser
* @param BatchRequestParser $batchRequestParser
* @param ProcedureHandler $procedureHandler
* @param MiddlewareHandler $middlewareHandler
*/
2016-08-06 02:27:09 +02:00
public function __construct(
$request = '',
array $server = array(),
ResponseBuilder $responseBuilder = null,
RequestParser $requestParser = null,
BatchRequestParser $batchRequestParser = null,
ProcedureHandler $procedureHandler = null,
MiddlewareHandler $middlewareHandler = null
) {
2015-08-15 03:33:39 +02:00
if ($request !== '') {
$this->payload = json_decode($request, true);
2016-05-08 21:53:45 +02:00
} else {
2015-08-15 03:33:39 +02:00
$this->payload = json_decode(file_get_contents('php://input'), true);
}
2015-06-21 15:56:36 +02:00
2016-05-08 21:53:45 +02:00
$this->serverVariable = $server ?: $_SERVER;
2016-08-06 02:27:09 +02:00
$this->responseBuilder = $responseBuilder ?: ResponseBuilder::create();
$this->requestParser = $requestParser ?: RequestParser::create();
$this->batchRequestParser = $batchRequestParser ?: BatchRequestParser::create();
$this->procedureHandler = $procedureHandler ?: new ProcedureHandler();
$this->middlewareHandler = $middlewareHandler ?: new MiddlewareHandler();
2015-06-21 15:56:36 +02:00
}
/**
* Define alternative authentication header
*
* @access public
* @param string $header Header name
2016-08-06 02:27:09 +02:00
* @return $this
2015-06-21 15:56:36 +02:00
*/
public function setAuthenticationHeader($header)
{
if (! empty($header)) {
$header = 'HTTP_'.str_replace('-', '_', strtoupper($header));
2016-05-08 21:53:45 +02:00
$value = $this->getServerVariable($header);
2015-06-21 15:56:36 +02:00
2016-05-08 21:53:45 +02:00
if (! empty($value)) {
list($this->username, $this->password) = explode(':', base64_decode($value));
2015-06-21 15:56:36 +02:00
}
}
return $this;
}
/**
2016-05-08 21:53:45 +02:00
* Get ProcedureHandler
2015-06-21 15:56:36 +02:00
*
* @access public
2016-05-08 21:53:45 +02:00
* @return ProcedureHandler
2015-06-21 15:56:36 +02:00
*/
2016-05-08 21:53:45 +02:00
public function getProcedureHandler()
2015-06-21 15:56:36 +02:00
{
2016-05-08 21:53:45 +02:00
return $this->procedureHandler;
2015-06-21 15:56:36 +02:00
}
2016-08-06 02:27:09 +02:00
/**
* Get MiddlewareHandler
*
* @access public
* @return MiddlewareHandler
*/
public function getMiddlewareHandler()
{
return $this->middlewareHandler;
}
2015-06-21 15:56:36 +02:00
/**
2016-05-08 21:53:45 +02:00
* Get username
2015-06-21 15:56:36 +02:00
*
* @access public
* @return string
*/
2016-05-08 21:53:45 +02:00
public function getUsername()
2015-06-21 15:56:36 +02:00
{
2016-05-08 21:53:45 +02:00
return $this->username ?: $this->getServerVariable('PHP_AUTH_USER');
2015-06-21 15:56:36 +02:00
}
/**
2016-05-08 21:53:45 +02:00
* Get password
2015-06-21 15:56:36 +02:00
*
* @access public
2016-05-08 21:53:45 +02:00
* @return string
2015-06-21 15:56:36 +02:00
*/
2016-05-08 21:53:45 +02:00
public function getPassword()
2015-06-21 15:56:36 +02:00
{
2016-05-08 21:53:45 +02:00
return $this->password ?: $this->getServerVariable('PHP_AUTH_PW');
}
/**
* IP based client restrictions
*
* @access public
* @param array $hosts List of hosts
2016-08-06 02:27:09 +02:00
* @return $this
*/
2015-06-21 15:56:36 +02:00
public function allowHosts(array $hosts)
{
2016-05-08 21:53:45 +02:00
$this->hosts = $hosts;
return $this;
}
/**
* HTTP Basic authentication
*
* @access public
2016-05-08 21:53:45 +02:00
* @param array $users Dictionary of username/password
2016-08-06 02:27:09 +02:00
* @return $this
*/
public function authentication(array $users)
{
2016-05-08 21:53:45 +02:00
$this->users = $users;
2015-06-21 15:56:36 +02:00
return $this;
}
/**
* Register a new procedure
*
* @access public
2016-08-06 02:27:09 +02:00
* @deprecated Use $server->getProcedureHandler()->withCallback($procedure, $callback)
* @param string $procedure Procedure name
* @param closure $callback Callback
2016-08-06 02:27:09 +02:00
* @return $this
*/
2015-08-15 03:33:39 +02:00
public function register($procedure, Closure $callback)
{
2016-05-08 21:53:45 +02:00
$this->procedureHandler->withCallback($procedure, $callback);
2015-06-21 15:56:36 +02:00
return $this;
}
/**
* Bind a procedure to a class
*
* @access public
2016-08-06 02:27:09 +02:00
* @deprecated Use $server->getProcedureHandler()->withClassAndMethod($procedure, $class, $method);
* @param string $procedure Procedure name
* @param mixed $class Class name or instance
* @param string $method Procedure name
2016-08-06 02:27:09 +02:00
* @return $this
*/
2015-03-31 02:13:07 +02:00
public function bind($procedure, $class, $method = '')
{
2016-05-08 21:53:45 +02:00
$this->procedureHandler->withClassAndMethod($procedure, $class, $method);
2015-06-21 15:56:36 +02:00
return $this;
}
2015-02-06 03:16:34 +01:00
/**
* Bind a class instance
*
* @access public
2016-08-06 02:27:09 +02:00
* @deprecated Use $server->getProcedureHandler()->withObject($instance);
2015-02-06 03:16:34 +01:00
* @param mixed $instance Instance name
2016-08-06 02:27:09 +02:00
* @return $this
2015-02-06 03:16:34 +01:00
*/
public function attach($instance)
{
2016-05-08 21:53:45 +02:00
$this->procedureHandler->withObject($instance);
2015-06-21 15:56:36 +02:00
return $this;
}
/**
2016-08-06 02:27:09 +02:00
* Exception classes that should not be relayed to the client
2015-06-21 15:56:36 +02:00
*
* @access public
2016-08-06 02:27:09 +02:00
* @param Exception|string $exception
* @return $this
2015-06-21 15:56:36 +02:00
*/
2016-08-06 02:27:09 +02:00
public function withLocalException($exception)
2015-06-21 15:56:36 +02:00
{
2016-08-06 02:27:09 +02:00
$this->localExceptions[] = $exception;
2015-06-21 15:56:36 +02:00
return $this;
2015-02-06 03:16:34 +01:00
}
/**
* Parse incoming requests
*
* @access public
* @return string
*/
public function execute()
{
2016-05-08 21:53:45 +02:00
try {
JsonFormatValidator::validate($this->payload);
HostValidator::validate($this->hosts, $this->getServerVariable('REMOTE_ADDR'));
UserValidator::validate($this->users, $this->getUsername(), $this->getPassword());
2016-08-06 02:27:09 +02:00
$this->middlewareHandler
->withUsername($this->getUsername())
->withPassword($this->getPassword())
;
2016-05-08 21:53:45 +02:00
$response = $this->parseRequest();
2015-06-21 15:56:36 +02:00
2016-05-08 21:53:45 +02:00
} catch (Exception $e) {
2016-08-06 02:27:09 +02:00
$response = $this->handleExceptions($e);
2015-06-21 15:56:36 +02:00
}
2016-08-06 02:27:09 +02:00
$this->responseBuilder->sendHeaders();
2016-05-08 21:53:45 +02:00
return $response;
}
2016-08-06 02:27:09 +02:00
/**
* Handle exceptions
*
* @access protected
* @param Exception $e
* @return string
* @throws Exception
*/
protected function handleExceptions(Exception $e)
{
foreach ($this->localExceptions as $exception) {
if ($e instanceof $exception) {
throw $e;
}
}
return $this->responseBuilder->withException($e)->build();
}
/**
2016-05-08 21:53:45 +02:00
* Parse incoming request
*
2016-08-06 02:27:09 +02:00
* @access protected
2016-05-08 21:53:45 +02:00
* @return string
*/
2016-08-06 02:27:09 +02:00
protected function parseRequest()
{
2016-05-08 21:53:45 +02:00
if (BatchRequestParser::isBatchRequest($this->payload)) {
2016-08-06 02:27:09 +02:00
return $this->batchRequestParser
2016-05-08 21:53:45 +02:00
->withPayload($this->payload)
->withProcedureHandler($this->procedureHandler)
2016-08-06 02:27:09 +02:00
->withMiddlewareHandler($this->middlewareHandler)
->withLocalException($this->localExceptions)
2016-05-08 21:53:45 +02:00
->parse();
}
2016-08-06 02:27:09 +02:00
return $this->requestParser
2016-05-08 21:53:45 +02:00
->withPayload($this->payload)
->withProcedureHandler($this->procedureHandler)
2016-08-06 02:27:09 +02:00
->withMiddlewareHandler($this->middlewareHandler)
->withLocalException($this->localExceptions)
2016-05-08 21:53:45 +02:00
->parse();
}
/**
2016-05-08 21:53:45 +02:00
* Check existence and get value of server variable
*
2016-08-06 02:27:09 +02:00
* @access protected
2016-05-08 21:53:45 +02:00
* @param string $variable
* @return string|null
*/
2016-08-06 02:27:09 +02:00
protected function getServerVariable($variable)
{
2016-05-08 21:53:45 +02:00
return isset($this->serverVariable[$variable]) ? $this->serverVariable[$variable] : null;
}
}