mirror of
https://github.com/suitenumerique/docs.git
synced 2026-09-30 13:35:10 +02:00
🐛(backend) handle object storage metadata keys case-insensitively
Object storage metadata keys are case insensitive per the S3 specification, but implementations don't agree on the case they give back. When head_object returns a capitalized "Status", updating the attachment status added a second, lowercase entry instead of replacing it, and the copy request ended up carrying two x-amz-meta-status headers. Ceph RadosGW loses one of them behind a proxy, which invalidates the request signature. The same assumption was made when reading the status back in media-auth and media-check, where an attachment stored on such a backend stayed in "processing" forever. Metadata read from the storage is now normalized to lowercase keys before being consumed or copied over. Signed-off-by: risk-alt <aldu6974@gmail.com>
This commit is contained in:
@@ -71,6 +71,7 @@ from core.services.search_indexers import (
|
||||
from core.tasks.access import reset_service_connections_in_cascade
|
||||
from core.tasks.mail import send_ask_for_access_mail
|
||||
from core.utils.analytics import PosthogEventName, posthog_capture
|
||||
from core.utils.dicts import lowercase_keys
|
||||
from core.utils.paths import filter_descendants
|
||||
from core.utils.s3_response_stream import content_stream
|
||||
from core.utils.treebeard import create_tree_node_with_retry
|
||||
@@ -1884,7 +1885,7 @@ class DocumentViewSet(
|
||||
extra_args = {
|
||||
"Metadata": {
|
||||
"owner": str(request.user.id),
|
||||
"status": enums.DocumentAttachmentStatus.PROCESSING,
|
||||
"status": enums.DocumentAttachmentStatus.PROCESSING.value,
|
||||
},
|
||||
"ContentType": serializer.validated_data["content_type"],
|
||||
}
|
||||
@@ -2034,7 +2035,7 @@ class DocumentViewSet(
|
||||
head_resp = s3_client.head_object(Bucket=bucket_name, Key=key)
|
||||
except ClientError as err:
|
||||
raise drf.exceptions.PermissionDenied() from err
|
||||
metadata = head_resp.get("Metadata", {})
|
||||
metadata = lowercase_keys(head_resp.get("Metadata", {}))
|
||||
# In order to be compatible with existing upload without `status` metadata,
|
||||
# we consider them as ready.
|
||||
if (
|
||||
@@ -2238,7 +2239,7 @@ class DocumentViewSet(
|
||||
{"detail": "Media not found"},
|
||||
status=drf.status.HTTP_404_NOT_FOUND,
|
||||
)
|
||||
metadata = head_resp.get("Metadata", {})
|
||||
metadata = lowercase_keys(head_resp.get("Metadata", {}))
|
||||
|
||||
body = {
|
||||
"status": metadata.get("status", enums.DocumentAttachmentStatus.PROCESSING),
|
||||
|
||||
Reference in New Issue
Block a user