Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-s3 for openSUSE:Factory checked in at 2026-08-31 15:58:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-s3 (Old) and /work/SRC/openSUSE:Factory/.aws-c-s3.new.1265 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-s3" Mon Aug 31 15:58:06 2026 rev:47 rq:1374825 version:0.13.7 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-s3/aws-c-s3.changes 2026-08-14 22:06:30.093976011 +0200 +++ /work/SRC/openSUSE:Factory/.aws-c-s3.new.1265/aws-c-s3.changes 2026-08-31 15:58:08.343989364 +0200 @@ -1,0 +2,11 @@ +Tue Aug 25 12:59:50 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to version 0.13.7 + * Clean up docs by @azkrishpy in (#665) + * fix(copy-object): forward request-payer to the source-size HEAD + by @TingDaoK in (#654) + * update doc on endpoint resolver update script by @azkrishpy in (#667) +- from version 0.13.6 + * CI/CD improvements by @azkrishpy in (#666) + +------------------------------------------------------------------- @@ -4 +15 @@ -- Update to version +- Update to version 0.13.5 Old: ---- v0.13.5.tar.gz New: ---- v0.13.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-s3.spec ++++++ --- /var/tmp/diff_new_pack.jHICBd/_old 2026-08-31 15:58:08.987011818 +0200 +++ /var/tmp/diff_new_pack.jHICBd/_new 2026-08-31 15:58:08.989011888 +0200 @@ -19,7 +19,7 @@ %define library_version 1.0.0 %define library_soversion 0unstable Name: aws-c-s3 -Version: 0.13.5 +Version: 0.13.7 Release: 0 Summary: AWS Cross-Platform, C99 wrapper for cryptography primitives License: Apache-2.0 ++++++ v0.13.5.tar.gz -> v0.13.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/.github/workflows/block-needs-review.yml new/aws-c-s3-0.13.7/.github/workflows/block-needs-review.yml --- old/aws-c-s3-0.13.5/.github/workflows/block-needs-review.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-s3-0.13.7/.github/workflows/block-needs-review.yml 2026-08-22 00:06:52.000000000 +0200 @@ -0,0 +1,12 @@ +name: Block needs-review merges + +on: + pull_request: + types: [opened, synchronize, reopened, labeled, unlabeled] + +permissions: + pull-requests: read + +jobs: + gate: + uses: awslabs/aws-crt-builder/.github/workflows/block-needs-review-label.yml@main diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/.github/workflows/check-abi.yml new/aws-c-s3-0.13.7/.github/workflows/check-abi.yml --- old/aws-c-s3-0.13.5/.github/workflows/check-abi.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-s3-0.13.7/.github/workflows/check-abi.yml 2026-08-22 00:06:52.000000000 +0200 @@ -0,0 +1,41 @@ +name: Check ABI compliance + +on: + pull_request: + types: [opened, synchronize, reopened] + +concurrency: + group: check-abi-${{ github.event.pull_request.number }} + cancel-in-progress: true + +env: + PACKAGE_NAME: aws-c-s3 + CRT_CI_ROLE: ${{ secrets.CRT_CI_ROLE_ARN }} + AWS_DEFAULT_REGION: us-east-1 + +permissions: + id-token: write + contents: read + pull-requests: write + +jobs: + check-abi: + name: check-abi + runs-on: ubuntu-24.04 + steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check ABI + uses: awslabs/aws-crt-builder/.github/actions/check-abi@main + with: + lib-name: ${{ env.PACKAGE_NAME }} + builder-version: latest + builder-source: releases diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/.github/workflows/release.yml new/aws-c-s3-0.13.7/.github/workflows/release.yml --- old/aws-c-s3-0.13.5/.github/workflows/release.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-s3-0.13.7/.github/workflows/release.yml 2026-08-22 00:06:52.000000000 +0200 @@ -0,0 +1,44 @@ +name: Release + +on: + workflow_dispatch: + inputs: + dry-run: + description: 'Compute and summarize the bump/version but do not commit, tag, or publish anything.' + required: false + default: 'false' + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +env: + PACKAGE_NAME: aws-c-s3 + CRT_CI_ROLE: ${{ secrets.CRT_CI_ROLE_ARN }} + AWS_DEFAULT_REGION: us-east-1 + +permissions: + id-token: write + contents: write + pull-requests: read + +jobs: + release: + name: release + runs-on: ubuntu-24.04 + steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ env.CRT_CI_ROLE }} + aws-region: ${{ env.AWS_DEFAULT_REGION }} + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Release + uses: awslabs/aws-crt-builder/.github/actions/auto-release@main + with: + lib-name: ${{ env.PACKAGE_NAME }} + dry-run: ${{ inputs.dry-run }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/CMakeLists.txt new/aws-c-s3-0.13.7/CMakeLists.txt --- old/aws-c-s3-0.13.5/CMakeLists.txt 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/CMakeLists.txt 2026-08-22 00:06:52.000000000 +0200 @@ -66,6 +66,7 @@ aws_add_sanitizers(${PROJECT_NAME}) # We are not ABI stable yet +# TODO: switch to VERSION derived from the VERSION file (via aws_get_version) once SOVERSION is set explicitly, to avoid changing the SONAME. set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0.0) set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION 0unstable) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/VERSION new/aws-c-s3-0.13.7/VERSION --- old/aws-c-s3-0.13.5/VERSION 1970-01-01 01:00:00.000000000 +0100 +++ new/aws-c-s3-0.13.7/VERSION 2026-08-22 00:06:52.000000000 +0200 @@ -0,0 +1 @@ +0.13.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/docs/memory_aware_request_execution.md new/aws-c-s3-0.13.7/docs/memory_aware_request_execution.md --- old/aws-c-s3-0.13.5/docs/memory_aware_request_execution.md 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/docs/memory_aware_request_execution.md 2026-08-22 00:06:52.000000000 +0200 @@ -16,7 +16,7 @@ parallel. CRT S3 client used to allocate part sized buffer for each of those requests and release it right after the request was done. That approach, resulted in a lot of very short lived allocations and allocator thrashing, -overall leading to memory use spikes considerably higher than whats needed. To +overall leading to memory use spikes considerably higher than what's needed. To address that, the client is switching to a pooled buffer approach, discussed below. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/include/aws/s3/s3_client.h new/aws-c-s3-0.13.7/include/aws/s3/s3_client.h --- old/aws-c-s3-0.13.5/include/aws/s3/s3_client.h 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/include/aws/s3/s3_client.h 2026-08-22 00:06:52.000000000 +0200 @@ -695,7 +695,7 @@ */ aws_s3_buffer_pool_factory_fn *buffer_pool_factory_fn; - /* User data thats passed into pool factory. */ + /* User data that's passed into pool factory. */ void *buffer_pool_user_data; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/scripts/update_s3_endpoint_resolver_artifacts.py new/aws-c-s3-0.13.7/scripts/update_s3_endpoint_resolver_artifacts.py --- old/aws-c-s3-0.13.5/scripts/update_s3_endpoint_resolver_artifacts.py 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/scripts/update_s3_endpoint_resolver_artifacts.py 2026-08-22 00:06:52.000000000 +0200 @@ -1,7 +1,33 @@ -# This script pulls latest 'partitions.json' and 's3-endpoint-rule-set.json' from Git. -# You will need a secret in secrets manager which has the 'ruleset-url' and 'ruleset-token'. -# It uses the latest files to generate 'source/s3_endpoint_resolver/aws_s3_endpoint_rule_set.c' and -# 'source/s3_endpoint_resolver/aws_s3_endpoint_resolver_partition.c' +# Regenerates the compiled-in S3 endpoint-resolver data for aws-c-s3. +# +# The S3 client resolves endpoints from an endpoint rule set plus a partitions +# table. Instead of downloading these at runtime, aws-c-s3 embeds them as C +# source so the rules are compiled into the library. This script produces that +# source from the latest upstream definitions. +# +# What it does: +# 1. Obtains the endpoint rule set and the partitions definition. +# - Rule set: extracted from the public S3 service model, at +# shapes -> com.amazonaws.s3#AmazonS3 -> traits -> smithy.rules#endpointRuleSet. +# - Partitions: the aws-sdk-cpp partitions.json. +# 2. Serializes each JSON as a compact C byte array exposed via an +# aws_byte_cursor. +# 3. Overwrites the generated sources (do NOT edit these by hand): +# source/s3_endpoint_resolver/aws_s3_endpoint_rule_set.c +# source/s3_endpoint_resolver/aws_s3_endpoint_resolver_partition.c +# +# Usage: +# python scripts/update_s3_endpoint_resolver_artifacts.py +# Pull both inputs from their upstream defaults and regenerate. +# python scripts/update_s3_endpoint_resolver_artifacts.py \ +# --ruleset path/to/ruleset.json --partitions path/to/partitions.json +# Regenerate from local JSON files instead (handy for testing a specific +# rule set / partitions snapshot). +# +# This runs on a daily schedule: each run regenerates the files from the latest +# upstream definitions, and if the result differs from what is already committed, +# the updated .c files are picked up so the change ships with the next build. +# Fetching the upstream defaults requires network access. import argparse import json diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/source/s3.c new/aws-c-s3-0.13.7/source/s3.c --- old/aws-c-s3-0.13.5/source/s3.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/source/s3.c 2026-08-22 00:06:52.000000000 +0200 @@ -38,7 +38,7 @@ AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_LIST_PARTS_PARSE_FAILED, "Failed to parse response from ListParts"), AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_RESUMED_PART_CHECKSUM_MISMATCH, "Checksum does not match previously uploaded part"), AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_RESUME_FAILED, "Resuming request failed"), - AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_OBJECT_MODIFIED, "The object modifed during download."), + AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_OBJECT_MODIFIED, "The object modified during download."), AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_NON_RECOVERABLE_ASYNC_ERROR, "Async error received from S3 and not recoverable from retry."), AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE, "The metric data is not available, the requests ends before the metric happens."), AWS_DEFINE_ERROR_INFO_S3(AWS_ERROR_S3_INCORRECT_CONTENT_LENGTH, "Request body length must match Content-Length header."), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/source/s3_auto_ranged_get.c new/aws-c-s3-0.13.7/source/s3_auto_ranged_get.c --- old/aws-c-s3-0.13.5/source/s3_auto_ranged_get.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/source/s3_auto_ranged_get.c 2026-08-22 00:06:52.000000000 +0200 @@ -623,8 +623,8 @@ break; } - /* if the inital message had a ranged header, there should also be a Content-Range header that specifies the - * object range and total object size. Otherwise, the size and range should be equal to the + /* if the initial message had a ranged header, there should also be a Content-Range header that specifies + * the object range and total object size. Otherwise, the size and range should be equal to the * total_content_length. */ if (!auto_ranged_get->initial_message_has_range_header) { object_size = content_length; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/source/s3_client.c new/aws-c-s3-0.13.7/source/s3_client.c --- old/aws-c-s3-0.13.5/source/s3_client.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/source/s3_client.c 2026-08-22 00:06:52.000000000 +0200 @@ -94,7 +94,7 @@ static const uint32_t s_endpoints_cleanup_time_offset_in_s = 5; /** - * The envrionment variable name for memory limit control. + * The environment variable name for memory limit control. */ static const char *s_memory_limit_env_var = "AWS_CRT_S3_MEMORY_LIMIT_IN_GIB"; @@ -170,7 +170,7 @@ /* Returns the max number of connections allowed. * - * When meta request is NULL, this will return the overall allowed number of connections based on the clinet + * When meta request is NULL, this will return the overall allowed number of connections based on the client * configurations. * * If meta_request is not NULL, this will return the number of connections allowed based on the meta request @@ -331,7 +331,7 @@ } uint64_t mem_limit_configured = 0; if (client_config->memory_limit_in_bytes == 0) { - /* Try to read from the envrionment variable for memory limit */ + /* Try to read from the environment variable for memory limit */ struct aws_string *memory_limit_from_env_var = aws_get_env_nonempty(allocator, s_memory_limit_env_var); if (memory_limit_from_env_var) { uint64_t mem_limit_in_gib = 0; @@ -340,7 +340,7 @@ aws_string_destroy(memory_limit_from_env_var); AWS_LOGF_ERROR( AWS_LS_S3_CLIENT, - "Cannot create client from client_config; envrionment variable: %s, is not set correctly, only " + "Cannot create client from client_config; environment variable: %s, is not set correctly, only " "integers supported.", s_memory_limit_env_var); aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); @@ -348,13 +348,13 @@ } aws_string_destroy(memory_limit_from_env_var); uint64_t mem_limit_in_bytes = 0; - /* Covert mem_limit_in_gib to bytes */ + /* Convert mem_limit_in_gib to bytes */ if (aws_mul_u64_checked(mem_limit_in_gib, 1024, &mem_limit_in_bytes) || aws_mul_u64_checked(mem_limit_in_bytes, 1024, &mem_limit_in_bytes) || aws_mul_u64_checked(mem_limit_in_bytes, 1024, &mem_limit_in_bytes)) { AWS_LOGF_ERROR( AWS_LS_S3_CLIENT, - "Cannot create client from client_config; envrionment variable: %s, overflow detected.", + "Cannot create client from client_config; environment variable: %s, overflow detected.", s_memory_limit_env_var); aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); return NULL; @@ -1465,7 +1465,7 @@ if (num_parts > 2) { uint64_t aligned_part_size = aws_s3_buffer_pool_derive_aligned_buffer_size(client->buffer_pool, part_size); - /* Incase of overflow, fallback to no alignment. */ + /* In case of overflow, fallback to no alignment. */ aligned_part_size = aligned_part_size > SIZE_MAX ? part_size : aligned_part_size; part_size = (size_t)aligned_part_size; /* update the number of parts as well. */ @@ -2291,7 +2291,7 @@ /** * When upload with streaming, the prepare stage will not read into buffer. - * But it should prevent more requests to be preapred so that the request will not staying in the + * But it should prevent more requests to be prepared so that the request will not stay in the * queue to wait for the connection available. Prevents the credentials to be expired during waiting * for too long. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/source/s3_default_buffer_pool.c new/aws-c-s3-0.13.7/source/s3_default_buffer_pool.c --- old/aws-c-s3-0.13.5/source/s3_default_buffer_pool.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/source/s3_default_buffer_pool.c 2026-08-22 00:06:52.000000000 +0200 @@ -576,11 +576,11 @@ } size_t primary_overallocation = aws_sub_size_saturating(buffer_pool->primary_allocated, buffer_pool->primary_used); - /* Reserved can be more tha allocated */ + /* Reserved can be more than allocated */ primary_overallocation = aws_sub_size_saturating(primary_overallocation, buffer_pool->primary_reserved); size_t special_overallocation = aws_sub_size_saturating(buffer_pool->special_blocks_allocated, buffer_pool->special_blocks_used); - /* Reserved can be more tha allocated */ + /* Reserved can be more than allocated */ special_overallocation = aws_sub_size_saturating(special_overallocation, buffer_pool->special_blocks_reserved); size_t total_overallocation = aws_add_size_saturating(special_overallocation, primary_overallocation); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/source/s3_default_meta_request.c new/aws-c-s3-0.13.7/source/s3_default_meta_request.c --- old/aws-c-s3-0.13.5/source/s3_default_meta_request.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/source/s3_default_meta_request.c 2026-08-22 00:06:52.000000000 +0200 @@ -389,7 +389,7 @@ struct aws_s3_upload_request_checksum_context *checksum_context = NULL; /** - * Note: CompleteMPU is unique in the sence that checksum on the object level is the full object checksum for + * Note: CompleteMPU is unique in the sense that checksum on the object level is the full object checksum for * all parts and not checksum of the body. So avoid any additional checksum handling if default req is * completeMPU. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/source/s3_part_streaming_input_stream.c new/aws-c-s3-0.13.7/source/s3_part_streaming_input_stream.c --- old/aws-c-s3-0.13.5/source/s3_part_streaming_input_stream.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/source/s3_part_streaming_input_stream.c 2026-08-22 00:06:52.000000000 +0200 @@ -40,8 +40,8 @@ size_t chunk_load_size; /* The reading counters */ - /* Incase the `offset` is not aligned with page size. The offset - page_aligned_offset will be aligned the page size - * to load the chunk. And read from the chunk can start from this `page_aligned_offset` */ + /* In case the `offset` is not aligned with page size. The offset - page_aligned_offset will be aligned the page + * size to load the chunk. And read from the chunk can start from this `page_aligned_offset` */ size_t page_aligned_offset; /* The offset of the chunk in the `reading_chunk_buf` that will start reading. */ size_t in_chunk_offset; @@ -92,7 +92,7 @@ /* Align the remaining length with the page size. */ if (remaining_length < impl->chunk_load_size) { size_t aligned_remaining_length = remaining_length % impl->page_size; - /* Read more tha needed to align with the page size. */ + /* Read more than needed to align with the page size. */ if (aligned_remaining_length > 0) { remaining_length = remaining_length + impl->page_size - aligned_remaining_length; AWS_LOGF_TRACE( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/source/s3_request_messages.c new/aws-c-s3-0.13.7/source/s3_request_messages.c --- old/aws-c-s3-0.13.5/source/s3_request_messages.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/source/s3_request_messages.c 2026-08-22 00:06:52.000000000 +0200 @@ -254,6 +254,20 @@ AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-checksum-type"); static const struct aws_byte_cursor s_checksum_type_full_object = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("full_object"); +static const struct { + struct aws_byte_cursor src_name; + struct aws_byte_cursor dst_name; +} s_copy_source_forwarded_headers[] = { + { + .src_name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-request-payer"), + .dst_name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-request-payer"), + }, + { + .src_name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-source-expected-bucket-owner"), + .dst_name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-expected-bucket-owner"), + }, +}; + const size_t g_s3_abort_multipart_upload_excluded_headers_count = AWS_ARRAY_SIZE(g_s3_abort_multipart_upload_excluded_headers); @@ -536,6 +550,44 @@ } static const struct aws_byte_cursor s_slash_char = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/"); + +/** + * Forward the request-scoped headers from the original CopyObject request onto the source-object HEAD that is used to + * size the copy. This HEAD is built from a fresh message, so headers that gate access to the source object are dropped + * unless we copy them explicitly: + * - x-amz-request-payer: required, or the HEAD is rejected with 403 on a Requester Pays bucket. + * - x-amz-source-expected-bucket-owner: on a CopyObject this asserts the *source* bucket owner, which maps to + * x-amz-expected-bucket-owner on a HEAD of the source object. (The plain x-amz-expected-bucket-owner on a CopyObject + * asserts the *destination* owner and must NOT be forwarded to the source HEAD.) + */ +static int s_s3_copy_source_object_head_forward_headers( + struct aws_http_message *base_message, + struct aws_http_message *message) { + + struct aws_http_headers *base_headers = aws_http_message_get_headers(base_message); + if (base_headers == NULL) { + return AWS_OP_SUCCESS; + } + + for (size_t i = 0; i < AWS_ARRAY_SIZE(s_copy_source_forwarded_headers); ++i) { + struct aws_byte_cursor value; + if (aws_http_headers_get(base_headers, s_copy_source_forwarded_headers[i].src_name, &value) == AWS_OP_SUCCESS) { + struct aws_http_header header = { + .name = s_copy_source_forwarded_headers[i].dst_name, + .value = value, + }; + if (aws_http_message_add_header(message, header)) { + return AWS_OP_ERR; + } + } else { + /* Avoid leaking the error code. */ + aws_reset_error(); + } + } + + return AWS_OP_SUCCESS; +} + /** * For the CopyObject operation, create the initial HEAD message to retrieve the size of the copy source. */ @@ -574,6 +626,10 @@ if (aws_http_message_set_request_path(message, path)) { goto error_cleanup; } + + if (s_s3_copy_source_object_head_forward_headers(base_message, message)) { + goto error_cleanup; + } return message; } @@ -658,6 +714,10 @@ goto error_cleanup; } + if (s_s3_copy_source_object_head_forward_headers(base_message, message)) { + goto error_cleanup; + } + aws_byte_buf_clean_up(&head_object_host_header); return message; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/tests/CMakeLists.txt new/aws-c-s3-0.13.7/tests/CMakeLists.txt --- old/aws-c-s3-0.13.5/tests/CMakeLists.txt 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/tests/CMakeLists.txt 2026-08-22 00:06:52.000000000 +0200 @@ -24,6 +24,7 @@ add_test_case(test_s3_upload_part_message_fail) add_test_case(test_s3_complete_multipart_message_new) add_test_case(test_s3_abort_multipart_upload_message_new) +add_test_case(test_s3_get_source_object_size_message_new) add_net_test_case(test_s3_put_object_custom_md5) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/tests/s3_mock_server_tests.c new/aws-c-s3-0.13.7/tests/s3_mock_server_tests.c --- old/aws-c-s3-0.13.5/tests/s3_mock_server_tests.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/tests/s3_mock_server_tests.c 2026-08-22 00:06:52.000000000 +0200 @@ -2693,7 +2693,7 @@ put_options.message = message; ASSERT_SUCCESS(aws_s3_tester_send_meta_request_with_options(&tester, &put_options, NULL)); - /* 2. Create request with host info missmatch endpoint override */ + /* 2. Create request with host info mismatch endpoint override */ struct aws_http_header host_header = { .name = g_host_header_name, .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("bad_host"), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/tests/s3_request_messages_tests.c new/aws-c-s3-0.13.7/tests/s3_request_messages_tests.c --- old/aws-c-s3-0.13.5/tests/s3_request_messages_tests.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/tests/s3_request_messages_tests.c 2026-08-22 00:06:52.000000000 +0200 @@ -17,6 +17,7 @@ #include <aws/http/request_response.h> #include <aws/io/stream.h> #include <aws/io/tls_channel_handler.h> +#include <aws/io/uri.h> #include <aws/testing/aws_test_harness.h> #include <inttypes.h> @@ -1010,3 +1011,126 @@ return 0; } + +/* Assert that a header is present on a message and equal to the expected value. */ +static int s_assert_header_value(struct aws_http_message *message, const char *name, const char *expected_value) { + struct aws_http_headers *headers = aws_http_message_get_headers(message); + ASSERT_TRUE(headers != NULL); + + struct aws_byte_cursor name_cursor = aws_byte_cursor_from_c_str(name); + struct aws_byte_cursor value; + AWS_ZERO_STRUCT(value); + ASSERT_SUCCESS(aws_http_headers_get(headers, name_cursor, &value)); + + struct aws_byte_cursor expected_cursor = aws_byte_cursor_from_c_str(expected_value); + ASSERT_TRUE(aws_byte_cursor_eq(&value, &expected_cursor)); + + return AWS_OP_SUCCESS; +} + +/* Assert that a header is NOT present on a message. */ +static int s_assert_header_absent(struct aws_http_message *message, const char *name) { + struct aws_http_headers *headers = aws_http_message_get_headers(message); + ASSERT_TRUE(headers != NULL); + + struct aws_byte_cursor name_cursor = aws_byte_cursor_from_c_str(name); + struct aws_byte_cursor value; + AWS_ZERO_STRUCT(value); + ASSERT_FAILS(aws_http_headers_get(headers, name_cursor, &value)); + + return AWS_OP_SUCCESS; +} + +/* Builds a representative CopyObject request message: it carries the destination Host, the source reference via + * x-amz-copy-source, and the access-gating headers whose forwarding to the source-size HEAD is under test. */ +static int s_create_copy_object_message(struct aws_allocator *allocator, struct aws_http_message **out_message) { + struct aws_http_message *message = aws_http_message_new_request(allocator); + ASSERT_TRUE(message != NULL); + + ASSERT_SUCCESS(aws_http_message_set_request_method(message, aws_byte_cursor_from_c_str("PUT"))); + ASSERT_SUCCESS(aws_http_message_set_request_path(message, aws_byte_cursor_from_c_str("/dest-key"))); + + const struct aws_http_header headers[] = { + s_http_header_from_c_str("Host", "dest-bucket.s3.us-east-1.amazonaws.com"), + s_http_header_from_c_str("x-amz-copy-source", "/source-bucket/source-key"), + s_http_header_from_c_str("x-amz-request-payer", "requester"), + /* Asserts the DESTINATION owner -- must NOT be forwarded to a HEAD of the source object. */ + s_http_header_from_c_str("x-amz-expected-bucket-owner", "111111111111"), + /* Asserts the SOURCE owner -- must be forwarded to the source HEAD as x-amz-expected-bucket-owner. */ + s_http_header_from_c_str("x-amz-source-expected-bucket-owner", "222222222222"), + }; + ASSERT_SUCCESS(aws_http_message_add_header_array(message, headers, AWS_ARRAY_SIZE(headers))); + + *out_message = message; + return AWS_OP_SUCCESS; +} + +/* Verifies that the source-object-size HEAD built for a CopyObject forwards the access-gating headers from the original + * request. Without this, a Requester Pays source object returns 403 on the size HEAD and the whole copy fails. Covers + * both the source_uri branch (mountpoint path) and the x-amz-copy-source fallback branch. */ +AWS_TEST_CASE(test_s3_get_source_object_size_message_new, s_test_s3_get_source_object_size_message_new) +static int s_test_s3_get_source_object_size_message_new(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + aws_s3_library_init(allocator); + + /* --- Branch 1: source_uri provided (the mountpoint-s3 path). --- */ + { + struct aws_http_message *base_message = NULL; + ASSERT_SUCCESS(s_create_copy_object_message(allocator, &base_message)); + + struct aws_uri source_uri; + AWS_ZERO_STRUCT(source_uri); + struct aws_byte_cursor uri_str = + aws_byte_cursor_from_c_str("https://source-bucket.s3.us-east-1.amazonaws.com/source-key"); + ASSERT_SUCCESS(aws_uri_init_parse(&source_uri, allocator, &uri_str)); + + struct aws_http_message *head_message = + aws_s3_get_source_object_size_message_new(allocator, base_message, &source_uri); + ASSERT_TRUE(head_message != NULL); + + ASSERT_SUCCESS(s_test_http_message_request_method(head_message, "HEAD")); + struct aws_byte_cursor expected_path = aws_byte_cursor_from_c_str("/source-key"); + ASSERT_SUCCESS(s_test_http_message_request_path(head_message, &expected_path)); + ASSERT_SUCCESS(s_assert_header_value(head_message, "Host", "source-bucket.s3.us-east-1.amazonaws.com")); + + /* Requester Pays must be forwarded verbatim. */ + ASSERT_SUCCESS(s_assert_header_value(head_message, "x-amz-request-payer", "requester")); + /* The source owner must map onto the HEAD's expected-bucket-owner -- NOT the destination owner. */ + ASSERT_SUCCESS(s_assert_header_value(head_message, "x-amz-expected-bucket-owner", "222222222222")); + /* The CopyObject-only source-owner header itself is not a valid header on a plain HEAD. */ + ASSERT_SUCCESS(s_assert_header_absent(head_message, "x-amz-source-expected-bucket-owner")); + + aws_http_message_release(head_message); + aws_uri_clean_up(&source_uri); + aws_http_message_release(base_message); + } + + /* --- Branch 2: no source_uri, source parsed from the x-amz-copy-source header (fallback path). --- */ + { + struct aws_http_message *base_message = NULL; + ASSERT_SUCCESS(s_create_copy_object_message(allocator, &base_message)); + + struct aws_uri empty_uri; + AWS_ZERO_STRUCT(empty_uri); + + struct aws_http_message *head_message = + aws_s3_get_source_object_size_message_new(allocator, base_message, &empty_uri); + ASSERT_TRUE(head_message != NULL); + + ASSERT_SUCCESS(s_test_http_message_request_method(head_message, "HEAD")); + struct aws_byte_cursor expected_path = aws_byte_cursor_from_c_str("/source-key"); + ASSERT_SUCCESS(s_test_http_message_request_path(head_message, &expected_path)); + + ASSERT_SUCCESS(s_assert_header_value(head_message, "x-amz-request-payer", "requester")); + ASSERT_SUCCESS(s_assert_header_value(head_message, "x-amz-expected-bucket-owner", "222222222222")); + ASSERT_SUCCESS(s_assert_header_absent(head_message, "x-amz-source-expected-bucket-owner")); + + aws_http_message_release(head_message); + aws_http_message_release(base_message); + } + + aws_s3_library_clean_up(); + + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/tests/s3_tester.c new/aws-c-s3-0.13.7/tests/s3_tester.c --- old/aws-c-s3-0.13.5/tests/s3_tester.c 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/tests/s3_tester.c 2026-08-22 00:06:52.000000000 +0200 @@ -66,7 +66,7 @@ /* If `$CRT_S3_TEST_BUCKET_NAME` environment variable is set, use that; otherwise, use aws-c-s3-test-bucket */ struct aws_byte_cursor g_test_bucket_name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("aws-c-s3-test-bucket"); -/* If `$CRT_S3_TEST_BUCKET_NAME` envrionment variable is set, use `$CRT_S3_TEST_BUCKET_NAME-public`; otherwise, use +/* If `$CRT_S3_TEST_BUCKET_NAME` environment variable is set, use `$CRT_S3_TEST_BUCKET_NAME-public`; otherwise, use * aws-c-s3-test-bucket-public */ struct aws_byte_cursor g_test_public_bucket_name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("aws-c-s3-test-bucket-public"); /* If `$CRT_S3_TEST_BUCKET_NAME` environment variable is set, use diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/tests/s3_tester.h new/aws-c-s3-0.13.7/tests/s3_tester.h --- old/aws-c-s3-0.13.5/tests/s3_tester.h 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/tests/s3_tester.h 2026-08-22 00:06:52.000000000 +0200 @@ -334,7 +334,7 @@ /* Wait for the correct number of aws_s3_tester_notify_meta_request_finished to be called */ void aws_s3_tester_wait_for_meta_request_finish(struct aws_s3_tester *tester); -/* Wait forthe correct number of aws_s3_tester_notify_meta_request_shutdown to be called. */ +/* Wait for the correct number of aws_s3_tester_notify_meta_request_shutdown to be called. */ void aws_s3_tester_wait_for_meta_request_shutdown(struct aws_s3_tester *tester); /* Notify the tester that a meta request has finished. */ @@ -483,7 +483,7 @@ void aws_s3_tester_wait_for_client_shutdown(struct aws_s3_tester *tester); /* - * Value to populate test stream with. Useful for cases where we need to verify that cheksums fail. + * Value to populate test stream with. Useful for cases where we need to verify that checksums fail. */ enum aws_s3_test_stream_value { TEST_STREAM_VALUE_1, @@ -537,7 +537,7 @@ /* If `$CRT_S3_TEST_BUCKET_NAME` environment variable is set, use that; otherwise, use aws-c-s3-test-bucket */ extern struct aws_byte_cursor g_test_bucket_name; -/* If `$CRT_S3_TEST_BUCKET_NAME` envrionment variable is set, use `$CRT_S3_TEST_BUCKET_NAME-public`; otherwise, use +/* If `$CRT_S3_TEST_BUCKET_NAME` environment variable is set, use `$CRT_S3_TEST_BUCKET_NAME-public`; otherwise, use * aws-c-s3-test-bucket-public */ extern struct aws_byte_cursor g_test_public_bucket_name; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-s3-0.13.5/tests/test_helper/README.md new/aws-c-s3-0.13.7/tests/test_helper/README.md --- old/aws-c-s3-0.13.5/tests/test_helper/README.md 2026-08-06 19:29:07.000000000 +0200 +++ new/aws-c-s3-0.13.7/tests/test_helper/README.md 2026-08-22 00:06:52.000000000 +0200 @@ -26,9 +26,9 @@ * Create `<BUCKET_NAME>` in us-west-2. + Add the lifecycle to automatic clean up the `upload/` and clean up incomplete multipart uploads after one day. + Upload files: - - `pre-existing-10MB-aes256-c` [SSE-C](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html#sse-c-highlights) encrypted fille - - `pre-existing-10MB-aes256` [SSE-S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/specifying-s3-encryption.html) encrypted fille - - `pre-existing-10MB-kms` [SSE-KMS](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html) encrypted fille + - `pre-existing-10MB-aes256-c` [SSE-C](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html#sse-c-highlights) encrypted file + - `pre-existing-10MB-aes256` [SSE-S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/specifying-s3-encryption.html) encrypted file + - `pre-existing-10MB-kms` [SSE-KMS](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html) encrypted file - `pre-existing-10MB` - `pre-existing-1MB` - `pre-existing-1MB-@`
