diff --git a/endpoints/v2/manifest.py b/endpoints/v2/manifest.py index a3a118c92..1f0ef9748 100644 --- a/endpoints/v2/manifest.py +++ b/endpoints/v2/manifest.py @@ -17,7 +17,8 @@ from endpoints.v2.errors import (BlobUnknown, ManifestInvalid, ManifestUnknown, NameInvalid, TagExpired) from endpoints.v2.labelhandlers import handle_label from image.docker import ManifestException -from image.docker.schema1 import DockerSchema1Manifest, DockerSchema1ManifestBuilder +from image.docker.schema1 import (DOCKER_SCHEMA1_MANIFEST_CONTENT_TYPE, + DockerSchema1Manifest, DockerSchema1ManifestBuilder) from image.docker.schema2 import DOCKER_SCHEMA2_CONTENT_TYPES, OCI_CONTENT_TYPES from notifications import spawn_notification from util.audit import track_and_log @@ -92,7 +93,8 @@ def fetch_manifest_by_digest(namespace_name, repo_name, manifest_ref): def _reject_manifest2_schema2(func): @wraps(func) def wrapped(*args, **kwargs): - if request.content_type in (DOCKER_SCHEMA2_CONTENT_TYPES | OCI_CONTENT_TYPES): + if _doesnt_accept_schema_v1() or \ + request.content_type in DOCKER_SCHEMA2_CONTENT_TYPES | OCI_CONTENT_TYPES: raise ManifestInvalid(detail={'message': 'manifest schema version not supported'}, http_status_code=415) return func(*args, **kwargs) @@ -100,6 +102,12 @@ def _reject_manifest2_schema2(func): return wrapped +def _doesnt_accept_schema_v1(): + # If the client doesn't specify anything, still give them Schema v1. + return len(request.accept_mimetypes) != 0 and \ + DOCKER_SCHEMA1_MANIFEST_CONTENT_TYPE not in request.accept_mimetypes + + @v2_bp.route(MANIFEST_TAGNAME_ROUTE, methods=['PUT']) @_reject_manifest2_schema2 @parse_repository_name()