Diff
Modified: trunk/Sungrazr/Server/Adapter/JsonRpc.php (103 => 104)
--- trunk/Sungrazr/Server/Adapter/JsonRpc.php 2007-12-20 20:18:19 UTC (rev 103)
+++ trunk/Sungrazr/Server/Adapter/JsonRpc.php 2007-12-21 01:31:07 UTC (rev 104)
@@ -21,6 +21,39 @@
/**
*
+ * User-provided configuration.
+ *
+ * Config keys are ...
+ *
+ * `content_types`
+ * : (array) List of acceptable content types for inbound requests.
+ *
+ * @var array
+ *
+ */
+ protected $_Sungrazr_Server_Adapter = array(
+ 'return' => false,
+ 'headers' => array(),
+ 'content_types' => array(
+ 'request' => array(
+ 'application/json'
+ ),
+ 'response' => array(
+ 'text/javascript',
+ 'text/x-javascript',
+ 'application/javascript',
+ 'application/x-javascript',
+ ),
+ ),
+ 'server_request' => array(
+ 'class' => 'Solar_Request',
+ 'spec' => null,
+ ),
+
+ );
+
+ /**
+ *
* From the request: method being called
*
* @param string
@@ -95,10 +128,10 @@
* @return mixed
*
*/
- public function handle(Solar_Request $request)
+ public function handle()
{
// avoid bad/inappropriate requests if possible
- if (! $this->_validate($request)) {
+ if (! $this->_validate()) {
return;
}
@@ -106,8 +139,7 @@
$callback = $this->_server_api[$this->method]['callback'];
$obj = Solar::factory($callback[0],
array(
- 'caller' => $this,
- 'request' => $request
+ 'caller' => $this
)
);
$this->result = call_user_func_array(
@@ -185,7 +217,7 @@
* @return bool
*
*/
- protected function _loadInput(Solar_Request $request)
+ protected function _loadInput()
{
$input = file_get_contents('php://input');
if (empty($input)) {
@@ -196,7 +228,7 @@
}
// pick out content length from raw input
- $len = $request->http('Content-Length', false);
+ $len = $this->_request->http('Content-Length', false);
if (! $len) {
return $this->fault(
'No Content-Length information found in request.',
@@ -240,7 +272,7 @@
*
*/
protected function _serialize()
- {
+ {
return json_encode(array(
'result' => $this->result,
'error' => $this->error,
@@ -276,14 +308,18 @@
* @return bool
*
*/
- protected function _validate($request)
+ protected function _validate()
{
// JSON-RPC over HTTP must be a POST
- $ok = $this->_validateRequestMethod($request);
+ $ok = $this->_validateRequestMethod();
if ($ok !== true) return false;
+
+ // Confirm that the content-type is acceptable
+ $ok = $this->_validateRequestContentType();
+ if ($ok !== true) return false;
// attempt to load the request
- $ok = $this->_loadInput($request);
+ $ok = $this->_loadInput();
if ($ok !== true) return false;
// special request?
@@ -365,6 +401,27 @@
/**
*
+ * Make sure the request content type is acceptable.
+ *
+ * Returns a server fault on failure, **TRUE** on success.
+ *
+ * @return mixed
+ *
+ */
+ protected function _validateRequestContentType()
+ {
+ $ct = strtolower($this->_request->server('CONTENT_TYPE', 'unknown'));
+ if (! in_array($ct, $this->_config['content_types']['request'])) {
+ return $this->fault(
+ "JSON-RPC does not support Content-Type {$ct} requests.",
+ 400
+ );
+ }
+ return true;
+ }
+
+ /**
+ *
* Make sure the request is a POST.
*
* Returns a server fault on failure, **TRUE** on success.
@@ -372,10 +429,10 @@
* @return mixed
*
*/
- protected function _validateRequestMethod($request)
+ protected function _validateRequestMethod()
{
// JSON-RPC over HTTP must be a POST
- if (! $request->isPost()) {
+ if (! $this->_request->isPost()) {
return $this->fault(
'JSON-RPC calls over HTTP must be made using POST requests',
100
Modified: trunk/Sungrazr/Server/Adapter/Rest.php (103 => 104)
--- trunk/Sungrazr/Server/Adapter/Rest.php 2007-12-20 20:18:19 UTC (rev 103)
+++ trunk/Sungrazr/Server/Adapter/Rest.php 2007-12-21 01:31:07 UTC (rev 104)
@@ -28,7 +28,7 @@
* @return mixed
*
*/
- public function handle(Solar_Request $request)
+ public function handle()
{
}
Modified: trunk/Sungrazr/Server/Adapter/XmlRpc.php (103 => 104)
--- trunk/Sungrazr/Server/Adapter/XmlRpc.php 2007-12-20 20:18:19 UTC (rev 103)
+++ trunk/Sungrazr/Server/Adapter/XmlRpc.php 2007-12-21 01:31:07 UTC (rev 104)
@@ -28,7 +28,7 @@
* @return mixed
*
*/
- public function handle(Solar_Request $request)
+ public function handle()
{
}
Modified: trunk/Sungrazr/Server/Adapter.php (103 => 104)
--- trunk/Sungrazr/Server/Adapter.php 2007-12-20 20:18:19 UTC (rev 103)
+++ trunk/Sungrazr/Server/Adapter.php 2007-12-21 01:31:07 UTC (rev 104)
@@ -44,12 +44,36 @@
* `headers`
* : (array) Associative array of headers to return with every response.
*
+ * `content_types`
+ * : (array) List of acceptable content types for requests and responses.
+ * The Content-Type of the inbound request is checked against the
+ * 'request' list prior to unserializing the inbound request. The Accept
+ * header of the request is examined for preferred types of supported
+ * responses in the serialization of the response. If Accept header
+ * is omitted or indicates a wildcard, the first supported response
+ * type is used.
+ *
+ * `server_request`
+ * : (array) Parameters for the request object dependency used within the
+ * Adapter This bypasses the Solar_Request dependency that Solar sets up
+ * by default to allow for extended request objects easily. The first
+ * element of the array is the class name to pass to [[Solar::dependency]],
+ * and the second is the second parameter to pass to Solar::dependency.
+ *
* @var array
*
*/
protected $_Sungrazr_Server_Adapter = array(
- 'return' => false,
- 'headers' => array()
+ 'return' => false,
+ 'headers' => array(),
+ 'content_types' => array(
+ 'request' => array('text/xml'),
+ 'response' => array('text/xml'),
+ ),
+ 'server_request' => array(
+ 'class' => 'Solar_Request',
+ 'spec' => null,
+ ),
);
/**
@@ -72,6 +96,15 @@
/**
*
+ * Solar_Request-based dependency.
+ *
+ * @var Solar_Request
+ *
+ */
+ protected $_request;
+
+ /**
+ *
* Array of introspective API information, indexed by callable method
* names instead of internal class names.
*
@@ -79,7 +112,7 @@
*
*/
protected $_server_api = array();
-
+
/**
*
* Special introspective methods provided by the server.
@@ -101,6 +134,20 @@
// basic construction
parent::__construct($config);
+ // pick up config options
+ $this->_headers = array_merge($this->_headers,
+ $this->_config['headers']);
+
+ // set up request dependency
+ if (! Solar::isRegistered('server_request')) {
+ Solar::register(
+ 'server_request',
+ $this->_config['server_request']['class'],
+ $this->_config['server_request']['spec']
+ );
+ }
+ $this->_request = Solar::registry('server_request');
+
// make extra-sure that no headers are output prematurely
ob_start();
@@ -167,14 +214,13 @@
*
* Handle a request.
*
- * Dispatches server request to appropriate method and returns a response.
+ * Dispatches server-side call to appropriate method and returns a
+ * response.
*
- * @param mixed $request
- *
* @return mixed
*
*/
- abstract public function handle(Solar_Request $request);
+ abstract public function handle();
/**
*
@@ -271,7 +317,7 @@
*
*/
protected function _response()
- {
+ {
$response = $this->serialize();
if (! $this->_config['return']) {
@@ -282,6 +328,28 @@
$this->_headers
);
+ // set output type appropriately
+ if (empty($this->_headers['Content-Type'])) {
+ // start with default
+ $content_type = $this->_config['content_types']['response'][0];
+
+ // now check if caller would prefer something specific that
+ // is supported
+ $accept = $this->_request->http('Accept', false);
+ if ($accept && strpos($accept, '*/*') === false) {
+ // Accept header contains no wildcard
+ foreach ($this->_config['content_types']['response'] as $rt) {
+ if (strpos($accept, $rt) !== false) {
+ $content_type = $rt;
+ break;
+ }
+ }
+ }
+
+ // set the type
+ $this->_headers['Content-Type'] = $content_type;
+ }
+
// append to Server header
$server_class = get_class($this);
if (! empty($this->_headers['Server'])) {
Modified: trunk/Sungrazr/Server/Handler.php (103 => 104)
--- trunk/Sungrazr/Server/Handler.php 2007-12-20 20:18:19 UTC (rev 103)
+++ trunk/Sungrazr/Server/Handler.php 2007-12-21 01:31:07 UTC (rev 104)
@@ -30,15 +30,15 @@
* `caller`
* : (Sungrazr_Server_Adapter) The server adapter that loaded this class.
*
- * `request`
- * : (Solar_Request) The incoming request to the API.
+ * `server_request`
+ * : (dependency) Server's Solar_Request dependency
*
* @var array
*
*/
protected $_Sungrazr_Server_Handler = array(
- 'caller' => null,
- 'request' => null,
+ 'caller' => null,
+ 'server_request' => 'server_request'
);
/**
@@ -64,6 +64,15 @@
/**
*
+ * The server's Solar_Request dependency
+ *
+ * @var Solar_Request
+ *
+ */
+ protected $_request;
+
+ /**
+ *
* Web Services request type, picked from last segment of the caller's
* class name and lowercased. (Ex: jsonrpc, xmlrpc, rest, etc.)
*
@@ -88,6 +97,11 @@
$this->_type = strtolower(end(explode('_', $caller_class)));
}
+ $this->_request = Solar::dependency(
+ 'Solar_Request',
+ $this->_config['server_request']
+ );
+
// special setup
$this->_setup();
}