handle http accept headers more gracefully

This commit is contained in:
Bernhard Posselt 2014-06-11 00:54:25 +02:00
parent 077a542d59
commit 1002281dae
3 changed files with 58 additions and 18 deletions

View File

@ -75,7 +75,7 @@ class Dispatcher {
$out = array(null, array(), null); $out = array(null, array(), null);
try { try {
// prefill reflector with everything thats needed for the // prefill reflector with everything thats needed for the
// middlewares // middlewares
$this->reflector->reflect($controller, $methodName); $this->reflector->reflect($controller, $methodName);
@ -132,14 +132,14 @@ class Dispatcher {
// it to the type annotated in the @param annotation // it to the type annotated in the @param annotation
$value = $this->request->getParam($param, $default); $value = $this->request->getParam($param, $default);
$type = $this->reflector->getType($param); $type = $this->reflector->getType($param);
// if this is submitted using GET or a POST form, 'false' should be // if this is submitted using GET or a POST form, 'false' should be
// converted to false // converted to false
if(($type === 'bool' || $type === 'boolean') && if(($type === 'bool' || $type === 'boolean') &&
$value === 'false' && $value === 'false' &&
( (
$this->request->method === 'GET' || $this->request->method === 'GET' ||
strpos($this->request->getHeader('Content-Type'), strpos($this->request->getHeader('Content-Type'),
'application/x-www-form-urlencoded') !== false 'application/x-www-form-urlencoded') !== false
) )
) { ) {
@ -148,7 +148,7 @@ class Dispatcher {
} elseif(in_array($type, $types)) { } elseif(in_array($type, $types)) {
settype($value, $type); settype($value, $type);
} }
$arguments[] = $value; $arguments[] = $value;
} }
@ -156,22 +156,15 @@ class Dispatcher {
// format response if not of type response // format response if not of type response
if(!($response instanceof Response)) { if(!($response instanceof Response)) {
// get format from the url format or request format parameter // get format from the url format or request format parameter
$format = $this->request->getParam('format'); $format = $this->request->getParam('format');
// if none is given try the first Accept header // if none is given try the first Accept header
if($format === null) { if($format === null) {
$header = $this->request->getHeader('Accept'); $headers = $this->request->getHeader('Accept');
$formats = explode(',', $header); $format = $controller->getResponderByHTTPHeader($headers);
}
if($header !== null && count($formats) > 0) {
$accept = strtolower(trim($formats[0]));
$format = str_replace('application/', '', $accept);
} else {
$format = 'json';
}
}
$response = $controller->buildResponse($response, $format); $response = $controller->buildResponse($response, $format);
} }

View File

@ -70,6 +70,30 @@ abstract class Controller {
} }
/**
* Parses an HTTP accept header and returns the supported responder type
* @param string $acceptHeader
* @return string the responder type
*/
public function getResponderByHTTPHeader($acceptHeader) {
$headers = explode(',', $acceptHeader);
// return the first matching responder
foreach ($headers as $header) {
$header = trim($header);
$responder = str_replace('application/', '', $header);
if (array_key_exists($responder, $this->responders)) {
return $responder;
}
}
// no matching header defaults to json
return 'json';
}
/** /**
* Registers a formatter for a type * Registers a formatter for a type
* @param string $format * @param string $format

View File

@ -30,6 +30,14 @@ use OCP\AppFramework\Http\JSONResponse;
class ChildController extends Controller { class ChildController extends Controller {
public function __construct($appName, $request) {
parent::__construct($appName, $request);
$this->registerResponder('tom', function ($respone) {
return 'hi';
});
}
public function custom($in) { public function custom($in) {
$this->registerResponder('json', function ($response) { $this->registerResponder('json', function ($response) {
return new JSONResponse(array(strlen($response))); return new JSONResponse(array(strlen($response)));
@ -161,5 +169,20 @@ class ControllerTest extends \PHPUnit_Framework_TestCase {
} }
public function testDefaultResponderToJSON() {
$responder = $this->controller->getResponderByHTTPHeader('*/*');
$this->assertEquals('json', $responder);
}
public function testResponderAcceptHeaderParsed() {
$responder = $this->controller->getResponderByHTTPHeader(
'*/*, application/tom, application/json'
);
$this->assertEquals('tom', $responder);
}
} }