Skip to content

Commit 61664ee

Browse files
add test case.
1 parent d595859 commit 61664ee

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

pyiceberg/catalog/rest/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ class IdentifierKind(Enum):
216216
SIGV4 = "rest.sigv4-enabled"
217217
SIGV4_REGION = "rest.signing-region"
218218
SIGV4_SERVICE = "rest.signing-name"
219+
EMPTY_BODY_SHA256: str = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
219220
OAUTH2_SERVER_URI = "oauth2-server-uri"
220221
SNAPSHOT_LOADING_MODE = "snapshot-loading-mode"
221222
AUTH = "auth"
@@ -565,7 +566,7 @@ def add_headers(self, request: PreparedRequest, **kwargs: Any) -> None: # pylin
565566
# For empty bodies, explicitly set the content hash header to the SHA256 of an empty string
566567
body = request.body
567568
if body in (None, b"", ""):
568-
request.headers["x-amz-content-sha256"] = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
569+
request.headers["x-amz-content-sha256"] = EMPTY_BODY_SHA256
569570

570571
aws_request = AWSRequest(
571572
method=request.method, url=url, params=params, data=request.body, headers=dict(request.headers)

tests/catalog/test_rest.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
from pyiceberg.transforms import IdentityTransform, TruncateTransform
5050
from pyiceberg.typedef import RecursiveDict
5151
from pyiceberg.utils.config import Config
52+
from requests import Request
5253

5354
TEST_URI = "https://iceberg-test-catalog/"
5455
TEST_CREDENTIALS = "client:secret_with:colon"
@@ -451,6 +452,61 @@ def test_list_tables_200_sigv4(rest_mock: Mocker) -> None:
451452
assert rest_mock.called
452453

453454

455+
def test_sigv4_sign_request_without_body(rest_mock: Mocker) -> None:
456+
existing_token = "existing_token"
457+
from pyiceberg.catalog.rest import EMPTY_BODY_SHA256
458+
459+
catalog = RestCatalog(
460+
"rest",
461+
**{
462+
"uri": TEST_URI,
463+
"token": existing_token,
464+
"rest.sigv4-enabled": "true",
465+
"rest.signing-region": "us-west-2",
466+
"client.access-key-id": "id",
467+
"client.secret-access-key": "secret",
468+
},
469+
)
470+
471+
prepared = catalog._session.prepare_request(Request("GET", f"{TEST_URI}v1/config")) # pylint: disable=W0212
472+
adapter = catalog._session.adapters[catalog.uri] # pylint: disable=W0212
473+
adapter.add_headers(prepared)
474+
475+
assert prepared.headers["Authorization"].startswith("AWS4-HMAC-SHA256")
476+
assert prepared.headers["Original-Authorization"] == f"Bearer {existing_token}"
477+
assert prepared.headers["x-amz-content-sha256"] == EMPTY_BODY_SHA256
478+
479+
def test_sigv4_sign_request_with_body(rest_mock: Mocker) -> None:
480+
existing_token = "existing_token"
481+
from pyiceberg.catalog.rest import EMPTY_BODY_SHA256
482+
483+
catalog = RestCatalog(
484+
"rest",
485+
**{
486+
"uri": TEST_URI,
487+
"token": existing_token,
488+
"rest.sigv4-enabled": "true",
489+
"rest.signing-region": "us-west-2",
490+
"client.access-key-id": "id",
491+
"client.secret-access-key": "secret",
492+
},
493+
)
494+
495+
prepared = catalog._session.prepare_request( # pylint: disable=W0212
496+
Request(
497+
"POST",
498+
f"{TEST_URI}v1/namespaces",
499+
data={"namespace": "asdfasd"},
500+
)
501+
)
502+
adapter = catalog._session.adapters[catalog.uri] # pylint: disable=W0212
503+
adapter.add_headers(prepared)
504+
505+
assert prepared.headers["Authorization"].startswith("AWS4-HMAC-SHA256")
506+
assert prepared.headers["Original-Authorization"] == f"Bearer {existing_token}"
507+
assert prepared.headers.get("x-amz-content-sha256") != EMPTY_BODY_SHA256
508+
509+
454510
def test_list_tables_404(rest_mock: Mocker) -> None:
455511
namespace = "examples"
456512
rest_mock.get(

0 commit comments

Comments
 (0)