From 8e4fbd063649bde2fda7ce5c7490403c9e28b29b Mon Sep 17 00:00:00 2001 From: Russ Michell Date: Thu, 31 May 2018 12:11:12 +1200 Subject: [PATCH] FIX: Fixes #63 Conditionally permit additional GET request in POST context. (#64) --- src/RestfulServer.php | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/RestfulServer.php b/src/RestfulServer.php index 69a60e0..0f93e33 100644 --- a/src/RestfulServer.php +++ b/src/RestfulServer.php @@ -41,6 +41,10 @@ use SilverStripe\CMS\Model\SiteTree; */ class RestfulServer extends Controller { + /** + * @config + * @var array + */ private static $url_handlers = array( '$ClassName!/$ID/$Relation' => 'handleAction', '' => 'notFound' @@ -62,10 +66,24 @@ class RestfulServer extends Controller * If no extension is given in the request, resolve to this extension * (and subsequently the {@link self::$default_mimetype}. * + * @config * @var string */ private static $default_extension = "xml"; + /** + * Whether or not to send an additional "Location" header for POST requests + * to satisfy HTTP 1.1: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + * + * Note: With this enabled (the default), no POST request for resource creation + * will return an HTTP 201. Because of the addition of the "Location" header, + * all responses become a straight HTTP 200. + * + * @config + * @var boolean + */ + private static $location_header_on_create = true; + /** * If no extension is given, resolve the request to this mimetype. * @@ -584,10 +602,15 @@ class RestfulServer extends Controller $type = ".{$types[0]}"; } - $urlSafeClassName = $this->sanitiseClassName(get_class($obj)); - $apiBase = $this->config()->api_base; - $objHref = Director::absoluteURL($apiBase . "$urlSafeClassName/$obj->ID" . $type); - $this->getResponse()->addHeader('Location', $objHref); + // Deviate slightly from the spec: Helps datamodel API access restrict + // to consulting just canCreate(), not canView() as a result of the additional + // "Location" header. + if ($this->config()->get('location_header_on_create')) { + $urlSafeClassName = $this->sanitiseClassName(get_class($obj)); + $apiBase = $this->config()->api_base; + $objHref = Director::absoluteURL($apiBase . "$urlSafeClassName/$obj->ID" . $type); + $this->getResponse()->addHeader('Location', $objHref); + } return $responseFormatter->convertDataObject($obj); }