def objects_acl_patch(bucket_name, object_name, entity): """Implement the 'ObjectAccessControls: patch' API.""" _, blob = testbench_utils.lookup_object(bucket_name, object_name) blob.check_preconditions(flask.request) revision = blob.get_revision(flask.request) acl = revision.patch_acl(entity, flask.request) return testbench_utils.filtered_response(flask.request, acl)
def objects_copy(source_bucket, source_object, destination_bucket, destination_object): """Implement the 'Objects: copy' API, copy an object.""" object_path, blob = testbench_utils.lookup_object(source_bucket, source_object) blob.check_preconditions( flask.request, if_generation_match='ifSourceGenerationMatch', if_generation_not_match='ifSourceGenerationNotMatch', if_metageneration_match='ifSourceMetagenerationMatch', if_metageneration_not_match='ifSourceMetagenerationNotMatch') source_revision = blob.get_revision(flask.request, 'sourceGeneration') if source_revision is None: raise error_response.ErrorResponse('Revision not found %s' % object_path, status_code=404) destination_path, destination = testbench_utils.get_object( destination_bucket, destination_object, gcs_object.GcsObject(destination_bucket, destination_object)) base_url = flask.url_for('gcs_index', _external=True) current_version = destination.copy_from(base_url, flask.request, source_revision) testbench_utils.insert_object(destination_path, destination) return testbench_utils.filtered_response(flask.request, current_version.metadata)
def objects_get(bucket_name, object_name): """Implement the 'Objects: get' API. Read objects or their metadata.""" _, blob = testbench_utils.lookup_object(bucket_name, object_name) blob.check_preconditions(flask.request) revision = blob.get_revision(flask.request) media = flask.request.args.get('alt', None) if media is None or media == 'json': return testbench_utils.filtered_response(flask.request, revision.metadata) if media != 'media': raise error_response.ErrorResponse('Invalid alt=%s parameter' % media) revision.validate_encryption_for_read(flask.request) # Respect the Range: header, if present. range_header = flask.request.headers.get('range') response_payload = revision.media begin = 0 end = len(response_payload) if range_header is not None: print("\n\n\nrange_header = %s\n\n" % range_header) m = re.match('bytes=([0-9]+)-([0-9]+)', range_header) if m: print("\n\n\nmatch = %s\n\n" % m) begin = int(m.group(1)) end = int(m.group(2)) response_payload = response_payload[begin:end + 1] # Process custome headers to test error conditions. instructions = flask.request.headers.get('x-goog-testbench-instructions') if instructions == 'return-corrupted-data': response_payload = testbench_utils.corrupt_media(response_payload) response = flask.make_response(response_payload) length = len(response_payload) content_range = 'bytes %d-%d/%d' % (begin, end - 1, length) response.headers['Content-Range'] = content_range response.headers['x-goog-hash'] = revision.x_goog_hash_header() return response
def objects_acl_list(bucket_name, object_name): """Implement the 'ObjectAccessControls: list' API.""" _, blob = testbench_utils.lookup_object(bucket_name, object_name) blob.check_preconditions(flask.request) revision = blob.get_revision(flask.request) result = {"items": revision.metadata.get("acl", [])} return testbench_utils.filtered_response(flask.request, result)
def objects_acl_update(bucket_name, object_name, entity): """Implement the 'ObjectAccessControls: update' API.""" _, blob = testbench_utils.lookup_object(bucket_name, object_name) blob.check_preconditions(flask.request) revision = blob.get_revision(flask.request) payload = json.loads(flask.request.data) acl = revision.update_acl(entity, payload.get('role', '')) return testbench_utils.filtered_response(flask.request, acl)
def objects_delete(bucket_name, object_name): """Implement the 'Objects: delete' API. Delete objects.""" object_path, blob = testbench_utils.lookup_object(bucket_name, object_name) blob.check_preconditions(flask.request) remove = blob.del_revision(flask.request) if remove: testbench_utils.delete_object(object_path) return testbench_utils.filtered_response(flask.request, {})
def objects_acl_create(bucket_name, object_name): """Implement the 'ObjectAccessControls: create' API.""" _, blob = testbench_utils.lookup_object(bucket_name, object_name) blob.check_preconditions(flask.request) revision = blob.get_revision(flask.request) payload = json.loads(flask.request.data) return testbench_utils.filtered_response( flask.request, revision.insert_acl(payload.get("entity", ""), payload.get("role", "")), )
def objects_get(bucket_name, object_name): """Implement the 'Objects: get' API. Read objects or their metadata.""" _, blob = testbench_utils.lookup_object(bucket_name, object_name) blob.check_preconditions(flask.request) revision = blob.get_revision(flask.request) media = flask.request.args.get("alt", None) if media is None or media == "json": return testbench_utils.filtered_response(flask.request, revision.metadata) if media != "media": raise error_response.ErrorResponse("Invalid alt=%s parameter" % media) revision.validate_encryption_for_read(flask.request) return objects_get_common(bucket_name, object_name, revision)
def xmlapi_get_object(bucket_name, object_name): """Implement the 'Objects: insert' API. Insert a new GCS Object.""" object_path, blob = testbench_utils.lookup_object(bucket_name, object_name) if flask.request.args.get('acl') is not None: raise error_response.ErrorResponse( 'ACL query not supported in XML API', status_code=500) if flask.request.args.get('encryption') is not None: raise error_response.ErrorResponse( 'Encryption query not supported in XML API', status_code=500) generation_match = flask.request.headers.get('if-generation-match') metageneration_match = flask.request.headers.get('if-metageneration-match') blob.check_preconditions_by_value(generation_match, None, metageneration_match, None) revision = blob.get_revision(flask.request) return objects_get_common(bucket_name, object_name, revision)
def objects_rewrite(source_bucket, source_object, destination_bucket, destination_object): """Implement the 'Objects: rewrite' API.""" base_url = flask.url_for('gcs_index', _external=True) insert_magic_bucket(base_url) object_path, blob = testbench_utils.lookup_object(source_bucket, source_object) blob.check_preconditions( flask.request, if_generation_match='ifSourceGenerationMatch', if_generation_not_match='ifSourceGenerationNotMatch', if_metageneration_match='ifSourceMetagenerationMatch', if_metageneration_not_match='ifSourceMetagenerationNotMatch') response = blob.rewrite_step(base_url, flask.request, destination_bucket, destination_object) return testbench_utils.filtered_response(flask.request, response)
def objects_compose(bucket_name, object_name): """Implement the 'Objects: compose' API: concatenate Objects.""" payload = json.loads(flask.request.data) source_objects = payload["sourceObjects"] if source_objects is None: raise error_response.ErrorResponse( "You must provide at least one source component.", status_code=400 ) if len(source_objects) > 32: raise error_response.ErrorResponse( "The number of source components provided" " (%d) exceeds the maximum (32)" % len(source_objects), status_code=400, ) composed_media = b"" for source_object in source_objects: source_object_name = source_object.get("name") if source_object_name is None: raise error_response.ErrorResponse("Required.", status_code=400) source_object_path, source_blob = testbench_utils.lookup_object( bucket_name, source_object_name ) source_revision = source_blob.get_latest() generation = source_object.get("generation") if generation is not None: source_revision = source_blob.get_revision_by_generation(generation) if source_revision is None: raise error_response.ErrorResponse( "No such object: %s" % source_object_path, status_code=404 ) object_preconditions = source_object.get("objectPreconditions") if object_preconditions is not None: if_generation_match = object_preconditions.get("ifGenerationMatch") source_blob.check_preconditions_by_value( if_generation_match, None, None, None ) composed_media += source_revision.media composed_object_path, composed_object = testbench_utils.get_object( bucket_name, object_name, gcs_object.GcsObject(bucket_name, object_name) ) composed_object.check_preconditions(flask.request) base_url = flask.url_for("gcs_index", _external=True) current_version = composed_object.compose_from( base_url, flask.request, composed_media ) testbench_utils.insert_object(composed_object_path, composed_object) return testbench_utils.filtered_response(flask.request, current_version.metadata)
def objects_get(bucket_name, object_name): """Implement the 'Objects: get' API. Read objects or their metadata.""" _, blob = testbench_utils.lookup_object(bucket_name, object_name) blob.check_preconditions(flask.request) revision = blob.get_revision(flask.request) media = flask.request.args.get('alt', None) if media is None or media == 'json': return testbench_utils.filtered_response(flask.request, revision.metadata) if media != 'media': raise error_response.ErrorResponse('Invalid alt=%s parameter' % media) revision.validate_encryption_for_read(flask.request) instructions = flask.request.headers.get('x-goog-testbench-instructions') if instructions == 'return-corrupted-data': response_payload = testbench_utils.corrupt_media(revision.media) else: response_payload = revision.media response = flask.make_response(response_payload) length = len(response_payload) response.headers['Content-Range'] = 'bytes 0-%d/%d' % (length - 1, length) response.headers['x-goog-hash'] = revision.x_goog_hash_header() return response
def xmlapi_get_object(bucket_name, object_name): """Implement the 'Objects: insert' API. Insert a new GCS Object.""" object_path, blob = testbench_utils.lookup_object(bucket_name, object_name) if flask.request.args.get('acl') is not None: raise error_response.ErrorResponse( 'ACL query not supported in XML API', status_code=500) if flask.request.args.get('encryption') is not None: raise error_response.ErrorResponse( 'Encryption query not supported in XML API', status_code=500) generation_match = flask.request.headers.get('if-generation-match') metageneration_match = flask.request.headers.get('if-metageneration-match') blob.check_preconditions_by_value(generation_match, None, metageneration_match, None) revision = blob.get_revision(flask.request) # Respect the Range: header, if present. range_header = flask.request.headers.get('range') response_payload = revision.media begin = 0 end = len(response_payload) if range_header is not None: print("\n\n\nrange_header = %s\n\n" % range_header) m = re.match('bytes=([0-9]+)-([0-9]+)', range_header) if m: print("\n\n\nmatch = %s\n\n" % m) begin = int(m.group(1)) end = int(m.group(2)) response_payload = response_payload[begin:end + 1] # Process custome headers to test error conditions. instructions = flask.request.headers.get('x-goog-testbench-instructions') if instructions == 'return-corrupted-data': response_payload = testbench_utils.corrupt_media(response_payload) response = flask.make_response(response_payload) length = len(response_payload) content_range = 'bytes %d-%d/%d' % (begin, end - 1, length) response.headers['Content-Range'] = content_range response.headers['x-goog-hash'] = revision.x_goog_hash_header() return response
def xmlapi_get_object(bucket_name, object_name): """Implement the 'Objects: insert' API. Insert a new GCS Object.""" object_path, blob = testbench_utils.lookup_object(bucket_name, object_name) if flask.request.args.get('acl') is not None: raise error_response.ErrorResponse( 'ACL query not supported in XML API', status_code=500) if flask.request.args.get('encryption') is not None: raise error_response.ErrorResponse( 'Encryption query not supported in XML API', status_code=500) generation_match = flask.request.headers.get('if-generation-match') metageneration_match = flask.request.headers.get('if-metageneration-match') blob.check_preconditions_by_value(generation_match, None, metageneration_match, None) revision = blob.get_revision(flask.request) instructions = flask.request.headers.get('x-goog-testbench-instructions') if instructions == 'return-corrupted-data': response_payload = testbench_utils.corrupt_media(revision.media) else: response_payload = revision.media response = flask.make_response(response_payload) length = len(response_payload) response.headers['Content-Range'] = 'bytes 0-%d/%d' % (length - 1, length) response.headers['x-goog-hash'] = revision.x_goog_hash_header() return response
def objects_patch(bucket_name, object_name): """Implement the 'Objects: patch' API: update an existing Object.""" _, blob = testbench_utils.lookup_object(bucket_name, object_name) blob.check_preconditions(flask.request) revision = blob.patch_revision(flask.request) return json.dumps(revision.metadata)