|
<?php |
|
|
|
namespace JsonRPC; |
|
|
|
use Closure; |
|
use Exception; |
|
use JsonRPC\Request\BatchRequestParser; |
|
use JsonRPC\Request\RequestParser; |
|
use JsonRPC\Response\ResponseBuilder; |
|
use JsonRPC\Validator\HostValidator; |
|
use JsonRPC\Validator\JsonFormatValidator; |
|
use JsonRPC\Validator\UserValidator; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Server |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $hosts = array(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $payload = array(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $localExceptions = array(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $username = ''; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $password = ''; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $users = array(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $serverVariable; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $procedureHandler; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $middlewareHandler; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $responseBuilder; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $requestParser; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $batchRequestParser; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function __construct( |
|
$request = '', |
|
array $server = array(), |
|
ResponseBuilder $responseBuilder = null, |
|
RequestParser $requestParser = null, |
|
BatchRequestParser $batchRequestParser = null, |
|
ProcedureHandler $procedureHandler = null, |
|
MiddlewareHandler $middlewareHandler = null |
|
) { |
|
if ($request !== '') { |
|
$this->payload = json_decode($request, true); |
|
} else { |
|
$this->payload = json_decode(file_get_contents('php://input'), true); |
|
} |
|
|
|
$this->serverVariable = $server ?: $_SERVER; |
|
$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(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setAuthenticationHeader($header) |
|
{ |
|
if (! empty($header)) { |
|
$header = 'HTTP_'.str_replace('-', '_', strtoupper($header)); |
|
$value = $this->getServerVariable($header); |
|
|
|
if (! empty($value)) { |
|
list($this->username, $this->password) = explode(':', base64_decode($value)); |
|
} |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getProcedureHandler() |
|
{ |
|
return $this->procedureHandler; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getMiddlewareHandler() |
|
{ |
|
return $this->middlewareHandler; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getUsername() |
|
{ |
|
return $this->username ?: $this->getServerVariable('PHP_AUTH_USER'); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getPassword() |
|
{ |
|
return $this->password ?: $this->getServerVariable('PHP_AUTH_PW'); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function allowHosts(array $hosts) |
|
{ |
|
$this->hosts = $hosts; |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function authentication(array $users) |
|
{ |
|
$this->users = $users; |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function register($procedure, Closure $callback) |
|
{ |
|
$this->procedureHandler->withCallback($procedure, $callback); |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function bind($procedure, $class, $method = '') |
|
{ |
|
$this->procedureHandler->withClassAndMethod($procedure, $class, $method); |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function attach($instance) |
|
{ |
|
$this->procedureHandler->withObject($instance); |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function withLocalException($exception) |
|
{ |
|
$this->localExceptions[] = $exception; |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function execute() |
|
{ |
|
try { |
|
JsonFormatValidator::validate($this->payload); |
|
HostValidator::validate($this->hosts, $this->getServerVariable('REMOTE_ADDR')); |
|
UserValidator::validate($this->users, $this->getUsername(), $this->getPassword()); |
|
|
|
$this->middlewareHandler |
|
->withUsername($this->getUsername()) |
|
->withPassword($this->getPassword()) |
|
; |
|
|
|
$response = $this->parseRequest(); |
|
|
|
} catch (Exception $e) { |
|
$response = $this->handleExceptions($e); |
|
} |
|
|
|
$this->responseBuilder->sendHeaders(); |
|
return $response; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function handleExceptions(Exception $e) |
|
{ |
|
foreach ($this->localExceptions as $exception) { |
|
if ($e instanceof $exception) { |
|
throw $e; |
|
} |
|
} |
|
|
|
return $this->responseBuilder->withException($e)->build(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function parseRequest() |
|
{ |
|
if (BatchRequestParser::isBatchRequest($this->payload)) { |
|
return $this->batchRequestParser |
|
->withPayload($this->payload) |
|
->withProcedureHandler($this->procedureHandler) |
|
->withMiddlewareHandler($this->middlewareHandler) |
|
->withLocalException($this->localExceptions) |
|
->parse(); |
|
} |
|
|
|
return $this->requestParser |
|
->withPayload($this->payload) |
|
->withProcedureHandler($this->procedureHandler) |
|
->withMiddlewareHandler($this->middlewareHandler) |
|
->withLocalException($this->localExceptions) |
|
->parse(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function getServerVariable($variable) |
|
{ |
|
return isset($this->serverVariable[$variable]) ? $this->serverVariable[$variable] : null; |
|
} |
|
} |
|
|