From 01cce9b823f391c8248963e25cc0974912231b4a Mon Sep 17 00:00:00 2001 From: Aaron Parecki Date: Sat, 14 Jul 2018 09:16:41 -0700 Subject: [PATCH] sends an Accept header when fetching posts --- lib/XRay/Fetcher.php | 27 ++++++++++++++++++++++--- lib/XRay/MediaType.php | 40 +++++++++++++++++++++++++++++++++++++ tests/MediaTypeTest.php | 44 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 lib/XRay/MediaType.php create mode 100644 tests/MediaTypeTest.php diff --git a/lib/XRay/Fetcher.php b/lib/XRay/Fetcher.php index dd9e861..a272b01 100644 --- a/lib/XRay/Fetcher.php +++ b/lib/XRay/Fetcher.php @@ -70,6 +70,9 @@ class Fetcher { } $headers = []; + + $headers[] = 'Accept: text/html, application/json, application/xml, text/xml'; + if(isset($opts['token'])) $headers[] = 'Authorization: Bearer ' . $opts['token']; @@ -84,16 +87,34 @@ class Fetcher { ]; } + // Show an error if the content type returned is not a recognized type + $format = null; + if(isset($result['headers']['Content-Type']) && is_string($result['headers']['Content-Type'])) { + $type = new MediaType($result['headers']['Content-Type']); + $format = $type->format; + } + + if(!$format || + !in_array($format, ['html', 'json', 'xml'])) { + return [ + 'error' => 'invalid_content', + 'error_description' => 'The server did not return a recognized content type', + 'content_type' => $result['headers']['Content-Type'], + 'url' => $result['url'], + 'code' => $result['code'] + ]; + } + if(trim($result['body']) == '') { if($result['code'] == 410) { // 410 Gone responses are valid and should not return an error - return $this->respond($response, 200, [ + return [ 'data' => [ - 'type' => 'unknown' + 'type' => 'deleted' ], 'url' => $result['url'], 'code' => $result['code'] - ]); + ]; } return [ diff --git a/lib/XRay/MediaType.php b/lib/XRay/MediaType.php new file mode 100644 index 0000000..3ec9270 --- /dev/null +++ b/lib/XRay/MediaType.php @@ -0,0 +1,40 @@ + type: application, subtype: json, format: json + // "application/ld+json" => type: application, subtype: "ld+json", format: json + public function __construct($string) { + if(strstr($string, ';')) { + list($type, $parameters) = explode(';', $string, 2); + + $parameters = explode(';', $parameters); + foreach($parameters as $p) { + list($k, $v) = explode('=', trim($p)); + if($k == 'charset') + $this->charset = $v; + } + } else { + $type = $string; + } + + list($type, $subtype) = explode('/', $type); + + $this->type = $type; + $this->subtype = $subtype; + $this->format = $subtype; + + if(strstr($subtype, '+')) { + list($a, $b) = explode('+', $subtype, 2); + $this->format = $b; + } + } + +} diff --git a/tests/MediaTypeTest.php b/tests/MediaTypeTest.php new file mode 100644 index 0000000..0f05b20 --- /dev/null +++ b/tests/MediaTypeTest.php @@ -0,0 +1,44 @@ +assertEquals('text', $type->type); + $this->assertEquals('html', $type->subtype); + $this->assertEquals('html', $type->format); + $this->assertEquals(null, $type->charset); + } + + public function testParseTextHtmlUtf8() { + $type = new p3k\XRay\MediaType('text/html; charset=UTF-8'); + $this->assertEquals('text', $type->type); + $this->assertEquals('html', $type->subtype); + $this->assertEquals('html', $type->format); + $this->assertEquals('UTF-8', $type->charset); + } + + public function testParseTextHtmlUtf8Extra() { + $type = new p3k\XRay\MediaType('text/html; hello=world; charset=UTF-8'); + $this->assertEquals('text', $type->type); + $this->assertEquals('html', $type->subtype); + $this->assertEquals('html', $type->format); + $this->assertEquals('UTF-8', $type->charset); + } + + public function testParseApplicationJson() { + $type = new p3k\XRay\MediaType('application/json'); + $this->assertEquals('application', $type->type); + $this->assertEquals('json', $type->subtype); + $this->assertEquals('json', $type->format); + $this->assertEquals(null, $type->charset); + } + + public function testParseApplicationJsonFeed() { + $type = new p3k\XRay\MediaType('application/feed+json'); + $this->assertEquals('application', $type->type); + $this->assertEquals('feed+json', $type->subtype); + $this->assertEquals('json', $type->format); + $this->assertEquals(null, $type->charset); + } + +}