@@ -512,9 +512,10 @@ def test_sigv4_sign_request_without_body(rest_mock: Mocker) -> None:
512512 assert isinstance (adapter , HTTPAdapter )
513513 adapter .add_headers (prepared )
514514
515- assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256" )
515+ assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256 Credential= " )
516516 assert prepared .headers ["Original-Authorization" ] == f"Bearer { existing_token } "
517517 assert prepared .headers ["x-amz-content-sha256" ] == EMPTY_BODY_SHA256
518+ assert "SignedHeaders=" in prepared .headers ["Authorization" ]
518519
519520
520521def test_sigv4_sign_request_with_body (rest_mock : Mocker ) -> None :
@@ -543,9 +544,74 @@ def test_sigv4_sign_request_with_body(rest_mock: Mocker) -> None:
543544 assert isinstance (adapter , HTTPAdapter )
544545 adapter .add_headers (prepared )
545546
546- assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256" )
547+ assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256 Credential=" )
548+ assert "SignedHeaders=" in prepared .headers ["Authorization" ]
549+ # Conflicting Authorization header is relocated
547550 assert prepared .headers ["Original-Authorization" ] == f"Bearer { existing_token } "
548- assert prepared .headers .get ("x-amz-content-sha256" ) != EMPTY_BODY_SHA256
551+ assert prepared .headers ["x-amz-content-sha256" ] == "nhKdVGKGU3IMGjYlod9xKUVc7/H5K6zTWj60yJOM80k="
552+
553+
554+ def test_sigv4_content_sha256_with_bytes_body (rest_mock : Mocker ) -> None :
555+ existing_token = "existing_token"
556+
557+ catalog = RestCatalog (
558+ "rest" ,
559+ ** {
560+ "uri" : TEST_URI ,
561+ "token" : existing_token ,
562+ "rest.sigv4-enabled" : "true" ,
563+ "rest.signing-region" : "us-west-2" ,
564+ "client.access-key-id" : "id" ,
565+ "client.secret-access-key" : "secret" ,
566+ },
567+ )
568+
569+ body_content = b'{"namespace": "test_namespace"}'
570+ prepared = catalog ._session .prepare_request (
571+ Request (
572+ "POST" ,
573+ f"{ TEST_URI } v1/namespaces" ,
574+ data = body_content ,
575+ )
576+ )
577+ adapter = catalog ._session .adapters [catalog .uri ]
578+ assert isinstance (adapter , HTTPAdapter )
579+ adapter .add_headers (prepared )
580+
581+ assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256 Credential=" )
582+ assert "SignedHeaders=" in prepared .headers ["Authorization" ]
583+ assert prepared .headers ["x-amz-content-sha256" ] == "sD20bEQP+WnwKPT7jxn7PIACGciAeWjQPlzFCK5Fifo="
584+
585+
586+ def test_sigv4_conflicting_sigv4_headers (rest_mock : Mocker ) -> None :
587+ catalog = RestCatalog (
588+ "rest" ,
589+ ** {
590+ "uri" : TEST_URI ,
591+ "rest.sigv4-enabled" : "true" ,
592+ "rest.signing-region" : "us-west-2" ,
593+ "client.access-key-id" : "id" ,
594+ "client.secret-access-key" : "secret" ,
595+ },
596+ )
597+
598+ prepared = catalog ._session .prepare_request (Request ("GET" , f"{ TEST_URI } v1/config" ))
599+ adapter = catalog ._session .adapters [catalog .uri ]
600+ assert isinstance (adapter , HTTPAdapter )
601+
602+ # Inject conflicting SigV4 headers before signing
603+ prepared .headers ["x-amz-content-sha256" ] = "fake"
604+ prepared .headers ["X-Amz-Date" ] = "fake"
605+
606+ adapter .add_headers (prepared )
607+
608+ # Matching Java SDK: conflicting headers are relocated with "Original-" prefix
609+ assert prepared .headers .get ("Original-x-amz-content-sha256" ) == "fake"
610+ assert prepared .headers .get ("Original-X-Amz-Date" ) == "fake"
611+ # SigV4 headers are set correctly after signing
612+ assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256 Credential=" )
613+ assert prepared .headers ["x-amz-content-sha256" ] == EMPTY_BODY_SHA256
614+ assert "X-Amz-Date" in prepared .headers
549615
550616
551617def test_sigv4_adapter_default_retry_config (rest_mock : Mocker ) -> None :
0 commit comments