@@ -493,9 +493,10 @@ def test_sigv4_sign_request_without_body(rest_mock: Mocker) -> None:
493493 assert isinstance (adapter , HTTPAdapter )
494494 adapter .add_headers (prepared )
495495
496- assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256" )
496+ assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256 Credential= " )
497497 assert prepared .headers ["Original-Authorization" ] == f"Bearer { existing_token } "
498498 assert prepared .headers ["x-amz-content-sha256" ] == EMPTY_BODY_SHA256
499+ assert "SignedHeaders=" in prepared .headers ["Authorization" ]
499500
500501
501502def test_sigv4_sign_request_with_body (rest_mock : Mocker ) -> None :
@@ -524,9 +525,74 @@ def test_sigv4_sign_request_with_body(rest_mock: Mocker) -> None:
524525 assert isinstance (adapter , HTTPAdapter )
525526 adapter .add_headers (prepared )
526527
527- assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256" )
528+ assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256 Credential=" )
529+ assert "SignedHeaders=" in prepared .headers ["Authorization" ]
530+ # Conflicting Authorization header is relocated
528531 assert prepared .headers ["Original-Authorization" ] == f"Bearer { existing_token } "
529- assert prepared .headers .get ("x-amz-content-sha256" ) != EMPTY_BODY_SHA256
532+ assert prepared .headers ["x-amz-content-sha256" ] == "nhKdVGKGU3IMGjYlod9xKUVc7/H5K6zTWj60yJOM80k="
533+
534+
535+ def test_sigv4_content_sha256_with_bytes_body (rest_mock : Mocker ) -> None :
536+ existing_token = "existing_token"
537+
538+ catalog = RestCatalog (
539+ "rest" ,
540+ ** {
541+ "uri" : TEST_URI ,
542+ "token" : existing_token ,
543+ "rest.sigv4-enabled" : "true" ,
544+ "rest.signing-region" : "us-west-2" ,
545+ "client.access-key-id" : "id" ,
546+ "client.secret-access-key" : "secret" ,
547+ },
548+ )
549+
550+ body_content = b'{"namespace": "test_namespace"}'
551+ prepared = catalog ._session .prepare_request (
552+ Request (
553+ "POST" ,
554+ f"{ TEST_URI } v1/namespaces" ,
555+ data = body_content ,
556+ )
557+ )
558+ adapter = catalog ._session .adapters [catalog .uri ]
559+ assert isinstance (adapter , HTTPAdapter )
560+ adapter .add_headers (prepared )
561+
562+ assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256 Credential=" )
563+ assert "SignedHeaders=" in prepared .headers ["Authorization" ]
564+ assert prepared .headers ["x-amz-content-sha256" ] == "sD20bEQP+WnwKPT7jxn7PIACGciAeWjQPlzFCK5Fifo="
565+
566+
567+ def test_sigv4_conflicting_sigv4_headers (rest_mock : Mocker ) -> None :
568+ catalog = RestCatalog (
569+ "rest" ,
570+ ** {
571+ "uri" : TEST_URI ,
572+ "rest.sigv4-enabled" : "true" ,
573+ "rest.signing-region" : "us-west-2" ,
574+ "client.access-key-id" : "id" ,
575+ "client.secret-access-key" : "secret" ,
576+ },
577+ )
578+
579+ prepared = catalog ._session .prepare_request (Request ("GET" , f"{ TEST_URI } v1/config" ))
580+ adapter = catalog ._session .adapters [catalog .uri ]
581+ assert isinstance (adapter , HTTPAdapter )
582+
583+ # Inject conflicting SigV4 headers before signing
584+ prepared .headers ["x-amz-content-sha256" ] = "fake"
585+ prepared .headers ["X-Amz-Date" ] = "fake"
586+
587+ adapter .add_headers (prepared )
588+
589+ # Matching Java SDK: conflicting headers are relocated with "Original-" prefix
590+ assert prepared .headers .get ("Original-x-amz-content-sha256" ) == "fake"
591+ assert prepared .headers .get ("Original-X-Amz-Date" ) == "fake"
592+ # SigV4 headers are set correctly after signing
593+ assert prepared .headers ["Authorization" ].startswith ("AWS4-HMAC-SHA256 Credential=" )
594+ assert prepared .headers ["x-amz-content-sha256" ] == EMPTY_BODY_SHA256
595+ assert "X-Amz-Date" in prepared .headers
530596
531597
532598def test_list_tables_404 (rest_mock : Mocker ) -> None :
0 commit comments