Skip to content

Commit 96b6c4b

Browse files
add test case
1 parent d595859 commit 96b6c4b

2 files changed

Lines changed: 60 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: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import pytest
2525
from requests.exceptions import HTTPError
26+
from requests.adapters import HTTPAdapter
2627
from requests_mock import Mocker
2728

2829
import pyiceberg
@@ -49,6 +50,7 @@
4950
from pyiceberg.transforms import IdentityTransform, TruncateTransform
5051
from pyiceberg.typedef import RecursiveDict
5152
from pyiceberg.utils.config import Config
53+
from requests import Request
5254

5355
TEST_URI = "https://iceberg-test-catalog/"
5456
TEST_CREDENTIALS = "client:secret_with:colon"
@@ -451,6 +453,62 @@ def test_list_tables_200_sigv4(rest_mock: Mocker) -> None:
451453
assert rest_mock.called
452454

453455

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

0 commit comments

Comments
 (0)