diff --git a/endpoints/v2/blob.py b/endpoints/v2/blob.py index 79113bad0..fa9886af5 100644 --- a/endpoints/v2/blob.py +++ b/endpoints/v2/blob.py @@ -5,7 +5,7 @@ from flask import url_for, request, redirect, Response, abort as flask_abort import resumablehashlib -from app import storage, app +from app import storage, app, get_app_url from auth.registry_jwt_auth import process_registry_jwt_auth from data import database from data.interfaces.v2 import pre_oci_model as model @@ -128,8 +128,9 @@ def start_blob_upload(namespace_name, repo_name): headers={ 'Docker-Upload-UUID': new_upload_uuid, 'Range': _render_range(0), - 'Location': url_for('v2.upload_chunk', repository='%s/%s' % (namespace_name, repo_name), - upload_uuid=new_upload_uuid) + 'Location': get_app_url() + url_for('v2.upload_chunk', + repository='%s/%s' % (namespace_name, repo_name), + upload_uuid=new_upload_uuid) }, ) @@ -156,8 +157,9 @@ def start_blob_upload(namespace_name, repo_name): status=201, headers={ 'Docker-Content-Digest': digest, - 'Location': url_for('v2.download_blob', repository='%s/%s' % (namespace_name, repo_name), - digest=digest), + 'Location': get_app_url() + url_for('v2.download_blob', + repository='%s/%s' % (namespace_name, repo_name), + digest=digest), }, ) @@ -205,7 +207,7 @@ def upload_chunk(namespace_name, repo_name, upload_uuid): return Response( status=204, headers={ - 'Location': _current_request_path(), + 'Location': _current_request_url(), 'Range': _render_range(updated_blob_upload.byte_count, with_bytes_prefix=False), 'Docker-Upload-UUID': upload_uuid, }, @@ -242,8 +244,9 @@ def monolithic_upload_or_last_chunk(namespace_name, repo_name, upload_uuid): status=201, headers={ 'Docker-Content-Digest': digest, - 'Location': url_for('v2.download_blob', repository='%s/%s' % (namespace_name, repo_name), - digest=digest), + 'Location': get_app_url() + url_for('v2.download_blob', + repository='%s/%s' % (namespace_name, repo_name), + digest=digest), } ) @@ -284,8 +287,8 @@ def _render_range(num_uploaded_bytes, with_bytes_prefix=True): return '{0}0-{1}'.format('bytes=' if with_bytes_prefix else '', num_uploaded_bytes - 1) -def _current_request_path(): - return '{0}{1}'.format(request.script_root, request.path) +def _current_request_url(): + return '{0}{1}{2}'.format(get_app_url(), request.script_root, request.path) def _abort_range_not_satisfiable(valid_end, upload_uuid): @@ -295,7 +298,7 @@ def _abort_range_not_satisfiable(valid_end, upload_uuid): TODO(jzelinskie): Unify this with the V2RegistryException class. """ - flask_abort(Response(status=416, headers={'Location': _current_request_path(), + flask_abort(Response(status=416, headers={'Location': _current_request_url(), 'Range': '0-{0}'.format(valid_end), 'Docker-Upload-UUID': upload_uuid})) diff --git a/test/registry_tests.py b/test/registry_tests.py index dcca9c45f..1a320f40d 100644 --- a/test/registry_tests.py +++ b/test/registry_tests.py @@ -29,7 +29,7 @@ from jwkest.jwk import RSAKey import endpoints.decorated # required for side effect -from app import app, storage, instance_keys +from app import app, storage, instance_keys, get_app_url from data.database import close_db_filter, configure, DerivedStorageForImage, QueueItem, Image from data import model from digest.checksums import compute_simple @@ -603,7 +603,14 @@ class V2RegistryPushMixin(V2RegistryMixin): expected_code=202, auth='jwt') upload_uuid = response.headers['Docker-Upload-UUID'] - location = response.headers['Location'][len(self.get_server_url()):] + + server_hostname = get_app_url() + new_upload_location = response.headers['Location'] + self.assertTrue(new_upload_location.startswith(server_hostname)) + + # We need to make this relative just for the tests because the live server test + # case modifies the port. + location = response.headers['Location'][len(server_hostname):] # PATCH the image data into the layer. if chunks is None: