Merge pull request #8980 from owncloud/better-accept-header
handle http accept headers more gracefully
This commit is contained in:
commit
3e1576011f
|
@ -52,9 +52,9 @@ class Dispatcher {
|
|||
* @param IRequest $request the incoming request
|
||||
*/
|
||||
public function __construct(Http $protocol,
|
||||
MiddlewareDispatcher $middlewareDispatcher,
|
||||
ControllerMethodReflector $reflector,
|
||||
IRequest $request) {
|
||||
MiddlewareDispatcher $middlewareDispatcher,
|
||||
ControllerMethodReflector $reflector,
|
||||
IRequest $request) {
|
||||
$this->protocol = $protocol;
|
||||
$this->middlewareDispatcher = $middlewareDispatcher;
|
||||
$this->reflector = $reflector;
|
||||
|
@ -75,7 +75,7 @@ class Dispatcher {
|
|||
$out = array(null, array(), null);
|
||||
|
||||
try {
|
||||
// prefill reflector with everything thats needed for the
|
||||
// prefill reflector with everything thats needed for the
|
||||
// middlewares
|
||||
$this->reflector->reflect($controller, $methodName);
|
||||
|
||||
|
@ -132,14 +132,14 @@ class Dispatcher {
|
|||
// it to the type annotated in the @param annotation
|
||||
$value = $this->request->getParam($param, $default);
|
||||
$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
|
||||
if(($type === 'bool' || $type === 'boolean') &&
|
||||
$value === 'false' &&
|
||||
$value === 'false' &&
|
||||
(
|
||||
$this->request->method === 'GET' ||
|
||||
strpos($this->request->getHeader('Content-Type'),
|
||||
strpos($this->request->getHeader('Content-Type'),
|
||||
'application/x-www-form-urlencoded') !== false
|
||||
)
|
||||
) {
|
||||
|
@ -148,7 +148,7 @@ class Dispatcher {
|
|||
} elseif(in_array($type, $types)) {
|
||||
settype($value, $type);
|
||||
}
|
||||
|
||||
|
||||
$arguments[] = $value;
|
||||
}
|
||||
|
||||
|
@ -156,21 +156,14 @@ class Dispatcher {
|
|||
|
||||
// format response if not of type response
|
||||
if(!($response instanceof Response)) {
|
||||
|
||||
|
||||
// get format from the url format or request format parameter
|
||||
$format = $this->request->getParam('format');
|
||||
|
||||
|
||||
// if none is given try the first Accept header
|
||||
if($format === null) {
|
||||
$header = $this->request->getHeader('Accept');
|
||||
$formats = explode(',', $header);
|
||||
|
||||
if($header !== null && count($formats) > 0) {
|
||||
$accept = strtolower(trim($formats[0]));
|
||||
$format = str_replace('application/', '', $accept);
|
||||
} else {
|
||||
$format = 'json';
|
||||
}
|
||||
$headers = $this->request->getHeader('Accept');
|
||||
$format = $controller->getResponderByHTTPHeader($headers);
|
||||
}
|
||||
|
||||
$response = $controller->buildResponse($response, $format);
|
||||
|
|
|
@ -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 = strtolower(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
|
||||
* @param string $format
|
||||
|
|
|
@ -30,6 +30,14 @@ use OCP\AppFramework\Http\JSONResponse;
|
|||
|
||||
|
||||
class ChildController extends Controller {
|
||||
|
||||
public function __construct($appName, $request) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->registerResponder('tom', function ($respone) {
|
||||
return 'hi';
|
||||
});
|
||||
}
|
||||
|
||||
public function custom($in) {
|
||||
$this->registerResponder('json', function ($response) {
|
||||
return new JSONResponse(array(strlen($response)));
|
||||
|
@ -161,5 +169,29 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
public function testResponderAcceptHeaderParsedUpperCase() {
|
||||
$responder = $this->controller->getResponderByHTTPHeader(
|
||||
'*/*, apPlication/ToM, application/json'
|
||||
);
|
||||
|
||||
$this->assertEquals('tom', $responder);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue