diff --git a/src/JsonSchema/Uri/UriRetriever.php b/src/JsonSchema/Uri/UriRetriever.php index 65452788..41147a2a 100644 --- a/src/JsonSchema/Uri/UriRetriever.php +++ b/src/JsonSchema/Uri/UriRetriever.php @@ -32,6 +32,14 @@ class UriRetriever implements BaseUriRetrieverInterface '|^https?://json-schema.org/draft-(0[34])/schema#?|' => 'package://dist/schema/json-schema-draft-$1.json' ); + /** + * @var array A list of endpoints for media type check exclusion + */ + protected $allowedInvalidContentTypeEndpoints = array( + 'http://json-schema.org/', + 'https://json-schema.org/' + ); + /** * @var null|UriRetrieverInterface */ @@ -44,6 +52,16 @@ class UriRetriever implements BaseUriRetrieverInterface */ private $schemaCache = array(); + /** + * Adds an endpoint to the media type validation exclusion list + * + * @param string $endpoint + */ + public function addInvalidContentTypeEndpoint($endpoint) + { + $this->allowedInvalidContentTypeEndpoints[] = $endpoint; + } + /** * Guarantee the correct media type was encountered * @@ -65,9 +83,10 @@ public function confirmMediaType($uriRetriever, $uri) return; } - if (substr($uri, 0, 23) == 'http://json-schema.org/') { - //HACK; they deliver broken content types - return true; + foreach ($this->allowedInvalidContentTypeEndpoints as $endpoint) { + if (strpos($uri, $endpoint) === 0) { + return true; + } } throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE)); diff --git a/tests/Uri/UriRetrieverTest.php b/tests/Uri/UriRetrieverTest.php index 8a67a08b..24714a26 100644 --- a/tests/Uri/UriRetrieverTest.php +++ b/tests/Uri/UriRetrieverTest.php @@ -330,13 +330,36 @@ public function testRetrieveSchemaFromPackage() $this->assertEquals('454f423bd7edddf0bc77af4130ed9161', md5(json_encode($schema))); } - public function testJsonSchemaOrgMediaTypeHack() + public function testInvalidContentTypeEndpointsDefault() { $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); $retriever = new UriRetriever(); $this->assertTrue($retriever->confirmMediaType($mock, 'http://json-schema.org/')); + $this->assertTrue($retriever->confirmMediaType($mock, 'https://json-schema.org/')); + } + + /** + * @expectedException \JsonSchema\Exception\InvalidSchemaMediaTypeException + */ + public function testInvalidContentTypeEndpointsUnknown() + { + $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); + $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); + $retriever = new UriRetriever(); + + $retriever->confirmMediaType($mock, 'http://example.com'); + } + + public function testInvalidContentTypeEndpointsAdded() + { + $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); + $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); + $retriever = new UriRetriever(); + $retriever->addInvalidContentTypeEndpoint('http://example.com'); + + $retriever->confirmMediaType($mock, 'http://example.com'); } public function testSchemaCache()