Merge "s3request: refactor error handling while reading input" into stable/2025.1

This commit is contained in:
Zuul
2025-08-06 23:12:48 +00:00
committed by Gerrit Code Review

View File

@@ -16,6 +16,7 @@
import base64 import base64
import binascii import binascii
from collections import defaultdict, OrderedDict from collections import defaultdict, OrderedDict
import contextlib
from email.header import Header from email.header import Header
from hashlib import sha1, sha256 from hashlib import sha1, sha256
import hmac import hmac
@@ -1032,13 +1033,8 @@ class S3Request(swob.Request):
if te or ml: if te or ml:
# Limit the read similar to how SLO handles manifests # Limit the read similar to how SLO handles manifests
try: with self.translate_read_errors():
body = self.body_file.read(max_length) body = self.body_file.read(max_length)
except S3InputSHA256Mismatch as err:
raise XAmzContentSHA256Mismatch(
client_computed_content_s_h_a256=err.expected,
s3_computed_content_s_h_a256=err.computed,
)
else: else:
# No (or zero) Content-Length provided, and not chunked transfer; # No (or zero) Content-Length provided, and not chunked transfer;
# no body. Assume zero-length, and enforce a required body below. # no body. Assume zero-length, and enforce a required body below.
@@ -1467,6 +1463,18 @@ class S3Request(swob.Request):
return code_map[method] return code_map[method]
@contextlib.contextmanager
def translate_read_errors(self):
try:
yield
except S3InputSHA256Mismatch as err:
# hopefully by now any modifications to the path (e.g. tenant to
# account translation) will have been made by auth middleware
raise XAmzContentSHA256Mismatch(
client_computed_content_s_h_a256=err.expected,
s3_computed_content_s_h_a256=err.computed,
)
def _get_response(self, app, method, container, obj, def _get_response(self, app, method, container, obj,
headers=None, body=None, query=None): headers=None, body=None, query=None):
""" """
@@ -1485,21 +1493,13 @@ class S3Request(swob.Request):
body=body, query=query) body=body, query=query)
try: try:
sw_resp = sw_req.get_response(app) with self.translate_read_errors():
except S3InputSHA256Mismatch as err: sw_resp = sw_req.get_response(app)
# hopefully by now any modifications to the path (e.g. tenant to finally:
# account translation) will have been made by auth middleware
self.environ['s3api.backend_path'] = sw_req.environ['PATH_INFO']
raise XAmzContentSHA256Mismatch(
client_computed_content_s_h_a256=err.expected,
s3_computed_content_s_h_a256=err.computed,
)
else:
# reuse account # reuse account
_, self.account, _ = split_path(sw_resp.environ['PATH_INFO'], _, self.account, _ = split_path(sw_req.environ['PATH_INFO'],
2, 3, True) 2, 3, True)
# Update s3.backend_path from the response environ self.environ['s3api.backend_path'] = sw_req.environ['PATH_INFO']
self.environ['s3api.backend_path'] = sw_resp.environ['PATH_INFO']
# keep a record of the backend policy index so that the s3api can add # keep a record of the backend policy index so that the s3api can add
# it to the headers of whatever response it returns, which may not # it to the headers of whatever response it returns, which may not