Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9346269
D4502.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Subscribers
None
D4502.diff
View Options
diff --git a/swh/deposit/api/collection.py b/swh/deposit/api/collection.py
--- a/swh/deposit/api/collection.py
+++ b/swh/deposit/api/collection.py
@@ -14,7 +14,7 @@
SWHFileUploadZipParser,
SWHMultiPartParser,
)
-from .common import ACCEPT_ARCHIVE_CONTENT_TYPES, APIPost
+from .common import ACCEPT_ARCHIVE_CONTENT_TYPES, APIPost, ParsedRequestHeaders
class CollectionAPI(APIPost):
@@ -36,7 +36,7 @@
def process_post(
self,
req,
- headers: Dict[str, Any],
+ headers: ParsedRequestHeaders,
collection_name: str,
deposit_id: Optional[int] = None,
) -> Tuple[int, str, Dict[str, Any]]:
diff --git a/swh/deposit/api/common.py b/swh/deposit/api/common.py
--- a/swh/deposit/api/common.py
+++ b/swh/deposit/api/common.py
@@ -74,6 +74,20 @@
ACCEPT_ARCHIVE_CONTENT_TYPES = ["application/zip", "application/x-tar"]
+@attr.s
+class ParsedRequestHeaders:
+ content_type = attr.ib(type=str)
+ content_length = attr.ib(type=Optional[int])
+ in_progress = attr.ib(type=bool)
+ content_disposition = attr.ib(type=Optional[str])
+ content_md5sum = attr.ib(type=Optional[bytes])
+ packaging = attr.ib(type=Optional[str])
+ slug = attr.ib(type=Optional[str])
+ on_behalf_of = attr.ib(type=Optional[str])
+ metadata_relevant = attr.ib(type=Optional[str])
+ swhid = attr.ib(type=Optional[str])
+
+
class AuthenticatedAPIView(APIView):
"""Mixin intended as a based API view to enforce the basic
authentication check
@@ -89,7 +103,7 @@
"""
- def _read_headers(self, request: Request) -> Dict[str, Any]:
+ def _read_headers(self, request: Request) -> ParsedRequestHeaders:
"""Read and unify the necessary headers from the request (those are
not stored in the same location or not properly formatted).
@@ -109,14 +123,13 @@
"""
meta = request._request.META
- content_type = request.content_type
+
content_length = meta.get("CONTENT_LENGTH")
if content_length and isinstance(content_length, str):
content_length = int(content_length)
# final deposit if not provided
in_progress = meta.get("HTTP_IN_PROGRESS", False)
- content_disposition = meta.get("HTTP_CONTENT_DISPOSITION")
if isinstance(in_progress, str):
in_progress = in_progress.lower() == "true"
@@ -124,25 +137,18 @@
if content_md5sum:
content_md5sum = bytes.fromhex(content_md5sum)
- packaging = meta.get("HTTP_PACKAGING")
- slug = meta.get("HTTP_SLUG")
- on_behalf_of = meta.get("HTTP_ON_BEHALF_OF")
- metadata_relevant = meta.get("HTTP_METADATA_RELEVANT")
-
- swhid = meta.get("HTTP_X_CHECK_SWHID")
-
- return {
- "content-type": content_type,
- "content-length": content_length,
- "in-progress": in_progress,
- "content-disposition": content_disposition,
- "content-md5sum": content_md5sum,
- "packaging": packaging,
- "slug": slug,
- "on-behalf-of": on_behalf_of,
- "metadata-relevant": metadata_relevant,
- "swhid": swhid,
- }
+ return ParsedRequestHeaders(
+ content_type=request.content_type,
+ content_length=content_length,
+ in_progress=in_progress,
+ content_disposition=meta.get("HTTP_CONTENT_DISPOSITION"),
+ content_md5sum=content_md5sum,
+ packaging=meta.get("HTTP_PACKAGING"),
+ slug=meta.get("HTTP_SLUG"),
+ on_behalf_of=meta.get("HTTP_ON_BEHALF_OF"),
+ metadata_relevant=meta.get("HTTP_METADATA_RELEVANT"),
+ swhid=meta.get("HTTP_X_CHECK_SWHID"),
+ )
def _compute_md5(self, filehandler) -> bytes:
"""Compute uploaded file's md5 sum.
@@ -334,7 +340,7 @@
return {}
def _check_preconditions_on(
- self, filehandler, md5sum: str, content_length: Optional[int] = None
+ self, filehandler, md5sum: Optional[bytes], content_length: Optional[int] = None
) -> Optional[Dict]:
"""Check preconditions on provided file are respected. That is the
length and/or the md5sum hash match the file's content.
@@ -379,7 +385,7 @@
def _binary_upload(
self,
request: Request,
- headers: Dict[str, Any],
+ headers: ParsedRequestHeaders,
collection_name: str,
deposit_id: Optional[int] = None,
replace_metadata: bool = False,
@@ -393,7 +399,7 @@
Args:
request (Request): the request holding information to parse
and inject in db
- headers (dict): request headers formatted
+ headers (ParsedRequestHeaders): parsed request headers
collection_name (str): the associated client
deposit_id (id): deposit identifier if provided
replace_metadata (bool): 'Update or add' request to existing
@@ -424,7 +430,7 @@
- 415 (unsupported media type) if a wrong media type is provided
"""
- content_length = headers["content-length"]
+ content_length = headers.content_length
if not content_length:
return make_error_dict(
BAD_REQUEST,
@@ -432,7 +438,7 @@
"For archive deposit, the CONTENT_LENGTH header must be sent.",
)
- content_disposition = headers["content-disposition"]
+ content_disposition = headers.content_disposition
if not content_disposition:
return make_error_dict(
BAD_REQUEST,
@@ -440,7 +446,7 @@
"For archive deposit, the CONTENT_DISPOSITION header must be sent.",
)
- packaging = headers["packaging"]
+ packaging = headers.packaging
if packaging and packaging not in ACCEPT_PACKAGINGS:
return make_error_dict(
BAD_REQUEST,
@@ -451,13 +457,13 @@
filehandler = request.FILES["file"]
precondition_status_response = self._check_preconditions_on(
- filehandler, headers["content-md5sum"], content_length
+ filehandler, headers.content_md5sum, content_length
)
if precondition_status_response:
return precondition_status_response
- slug = headers.get("slug")
+ slug = headers.slug
if check_slug_is_present and not slug:
return make_missing_slug_error()
@@ -466,7 +472,7 @@
deposit = self._deposit_put(
request,
deposit_id=deposit_id,
- in_progress=headers["in-progress"],
+ in_progress=headers.in_progress,
external_id=slug,
)
self._deposit_request_put(
@@ -495,7 +501,7 @@
def _multipart_upload(
self,
request: Request,
- headers: Dict[str, Any],
+ headers: ParsedRequestHeaders,
collection_name: str,
deposit_id: Optional[int] = None,
replace_metadata: bool = False,
@@ -511,7 +517,7 @@
Args:
request (Request): the request holding information to parse
and inject in db
- headers: request headers formatted
+ headers: parsed request headers
collection_name: the associated client
deposit_id: deposit identifier if provided
replace_metadata: 'Update or add' request to existing
@@ -542,7 +548,7 @@
- 415 (unsupported media type) if a wrong media type is provided
"""
- slug = headers.get("slug")
+ slug = headers.slug
if check_slug_is_present and not slug:
return make_missing_slug_error()
@@ -587,7 +593,7 @@
filehandler = data["application/x-tar"]
precondition_status_response = self._check_preconditions_on(
- filehandler, headers["content-md5sum"]
+ filehandler, headers.content_md5sum
)
if precondition_status_response:
@@ -607,7 +613,7 @@
deposit = self._deposit_put(
request,
deposit_id=deposit_id,
- in_progress=headers["in-progress"],
+ in_progress=headers.in_progress,
external_id=slug,
)
deposit_request_data = {
@@ -722,7 +728,7 @@
def _atom_entry(
self,
request: Request,
- headers: Dict[str, Any],
+ headers: ParsedRequestHeaders,
collection_name: str,
deposit_id: Optional[int] = None,
replace_metadata: bool = False,
@@ -734,7 +740,7 @@
Args:
request: the request holding information to parse
and inject in db
- headers: request headers formatted
+ headers: parsed request headers
collection_name: the associated client
deposit_id: deposit identifier if provided
replace_metadata: 'Update or add' request to existing
@@ -788,9 +794,9 @@
return make_error_dict(PARSING_ERROR, "Invalid SWHID reference", str(e),)
if swhid is not None:
- external_id = metadata.get("external_identifier", headers.get("slug"))
+ external_id = metadata.get("external_identifier", headers.slug)
else:
- slug = headers.get("slug")
+ slug = headers.slug
if check_slug_is_present and not slug:
return make_missing_slug_error()
@@ -799,7 +805,7 @@
deposit = self._deposit_put(
request,
deposit_id=deposit_id,
- in_progress=headers["in-progress"],
+ in_progress=headers.in_progress,
external_id=external_id,
)
@@ -841,14 +847,18 @@
}
def _empty_post(
- self, request: Request, headers: Dict, collection_name: str, deposit_id: int
+ self,
+ request: Request,
+ headers: ParsedRequestHeaders,
+ collection_name: str,
+ deposit_id: int,
) -> Dict[str, Any]:
"""Empty post to finalize an empty deposit.
Args:
request: the request holding information to parse
and inject in db
- headers: request headers formatted
+ headers: parsed request headers
collection_name: the associated client
deposit_id: deposit identifier
@@ -892,7 +902,7 @@
def additional_checks(
self,
request: Request,
- headers: Dict[str, Any],
+ headers: ParsedRequestHeaders,
collection_name: str,
deposit_id: Optional[int] = None,
) -> Dict[str, Any]:
@@ -948,7 +958,7 @@
if checks:
return checks
- if headers["on-behalf-of"]:
+ if headers.on_behalf_of:
return make_error_dict(MEDIATION_NOT_ALLOWED, "Mediation is not supported.")
checks = self.additional_checks(request, headers, collection_name, deposit_id)
@@ -958,7 +968,7 @@
return {"headers": headers}
def restrict_access(
- self, request: Request, headers: Dict, deposit: Deposit
+ self, request: Request, headers: ParsedRequestHeaders, deposit: Deposit
) -> Dict[str, Any]:
"""Allow modifications on deposit with status 'partial' only, reject the rest.
@@ -1094,7 +1104,7 @@
def process_post(
self,
request,
- headers: Dict,
+ headers: ParsedRequestHeaders,
collection_name: str,
deposit_id: Optional[int] = None,
) -> Tuple[int, str, Dict]:
@@ -1141,7 +1151,11 @@
@abstractmethod
def process_put(
- self, request: Request, headers: Dict, collection_name: str, deposit_id: int
+ self,
+ request: Request,
+ headers: ParsedRequestHeaders,
+ collection_name: str,
+ deposit_id: int,
) -> Dict[str, Any]:
"""Routine to deal with updating a deposit in some way.
diff --git a/swh/deposit/api/edit.py b/swh/deposit/api/edit.py
--- a/swh/deposit/api/edit.py
+++ b/swh/deposit/api/edit.py
@@ -13,7 +13,7 @@
from ..config import DEPOSIT_STATUS_LOAD_SUCCESS
from ..errors import BAD_REQUEST, BadRequestError, ParserError, make_error_dict
from ..parsers import SWHAtomEntryParser, SWHMultiPartParser
-from .common import APIDelete, APIPut
+from .common import APIDelete, APIPut, ParsedRequestHeaders
class EditAPI(APIPut, APIDelete):
@@ -28,7 +28,7 @@
parser_classes = (SWHMultiPartParser, SWHAtomEntryParser)
def restrict_access(
- self, request: Request, headers: Dict, deposit: Deposit
+ self, request: Request, headers: ParsedRequestHeaders, deposit: Deposit
) -> Dict[str, Any]:
"""Relax restriction access to allow metadata update on deposit with status "done" when
a swhid is provided.
@@ -36,7 +36,7 @@
"""
if (
request.method == "PUT"
- and headers["swhid"] is not None
+ and headers.swhid is not None
and deposit.status == DEPOSIT_STATUS_LOAD_SUCCESS
):
# Allow metadata update on deposit with status "done" when swhid provided
@@ -45,7 +45,11 @@
return super().restrict_access(request, headers, deposit)
def process_put(
- self, request, headers: Dict, collection_name: str, deposit_id: int
+ self,
+ request,
+ headers: ParsedRequestHeaders,
+ collection_name: str,
+ deposit_id: int,
) -> Dict[str, Any]:
"""This allows the following scenarios:
@@ -71,7 +75,7 @@
204 No content
""" # noqa
- swhid = headers.get("swhid")
+ swhid = headers.swhid
if swhid is None:
if request.content_type.startswith("multipart/"):
return self._multipart_upload(
diff --git a/swh/deposit/api/edit_media.py b/swh/deposit/api/edit_media.py
--- a/swh/deposit/api/edit_media.py
+++ b/swh/deposit/api/edit_media.py
@@ -10,7 +10,13 @@
from ..config import CONT_FILE_IRI
from ..errors import BAD_REQUEST, make_error_dict
from ..parsers import SWHFileUploadTarParser, SWHFileUploadZipParser
-from .common import ACCEPT_ARCHIVE_CONTENT_TYPES, APIDelete, APIPost, APIPut
+from .common import (
+ ACCEPT_ARCHIVE_CONTENT_TYPES,
+ APIDelete,
+ APIPost,
+ APIPut,
+ ParsedRequestHeaders,
+)
class EditMediaAPI(APIPost, APIPut, APIDelete):
@@ -28,7 +34,7 @@
)
def process_put(
- self, req, headers, collection_name: str, deposit_id: int
+ self, req, headers: ParsedRequestHeaders, collection_name: str, deposit_id: int
) -> Dict[str, Any]:
"""Replace existing content for the existing deposit.
@@ -49,7 +55,11 @@
)
def process_post(
- self, req, headers: Dict, collection_name: str, deposit_id: Optional[int] = None
+ self,
+ req,
+ headers: ParsedRequestHeaders,
+ collection_name: str,
+ deposit_id: Optional[int] = None,
) -> Tuple[int, str, Dict]:
"""Add new content to the existing deposit.
diff --git a/swh/deposit/api/private/deposit_update_status.py b/swh/deposit/api/private/deposit_update_status.py
--- a/swh/deposit/api/private/deposit_update_status.py
+++ b/swh/deposit/api/private/deposit_update_status.py
@@ -12,7 +12,7 @@
from . import APIPrivateView
from ...errors import BAD_REQUEST, make_error_dict
from ...models import DEPOSIT_STATUS_DETAIL, DEPOSIT_STATUS_LOAD_SUCCESS, Deposit
-from ..common import APIPut
+from ..common import APIPut, ParsedRequestHeaders
MANDATORY_KEYS = ["origin_url", "revision_id", "directory_id", "snapshot_id"]
@@ -26,7 +26,9 @@
parser_classes = (JSONParser,)
- def additional_checks(self, request, headers, collection_name, deposit_id=None):
+ def additional_checks(
+ self, request, headers: ParsedRequestHeaders, collection_name, deposit_id=None
+ ):
"""Enrich existing checks to the default ones.
New checks:
@@ -64,7 +66,11 @@
return {}
def process_put(
- self, request, headers: Dict, collection_name: str, deposit_id: int
+ self,
+ request,
+ headers: ParsedRequestHeaders,
+ collection_name: str,
+ deposit_id: int,
) -> Dict:
"""Update the deposit with status and SWHIDs
diff --git a/swh/deposit/api/sword_edit.py b/swh/deposit/api/sword_edit.py
--- a/swh/deposit/api/sword_edit.py
+++ b/swh/deposit/api/sword_edit.py
@@ -12,7 +12,7 @@
from ..config import EDIT_IRI, EM_IRI
from ..parsers import SWHAtomEntryParser, SWHMultiPartParser
-from .common import APIPost
+from .common import APIPost, ParsedRequestHeaders
class SwordEditAPI(APIPost):
@@ -35,7 +35,7 @@
def process_post(
self,
request,
- headers: Dict,
+ headers: ParsedRequestHeaders,
collection_name: str,
deposit_id: Optional[int] = None,
) -> Tuple[int, str, Dict]:
@@ -70,8 +70,8 @@
)
return (status.HTTP_201_CREATED, EM_IRI, data)
- content_length = headers["content-length"] or 0
- if content_length == 0 and headers["in-progress"] is False:
+ content_length = headers.content_length or 0
+ if content_length == 0 and headers.in_progress is False:
# check for final empty post
data = self._empty_post(request, headers, collection_name, deposit_id)
return (status.HTTP_200_OK, EDIT_IRI, data)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 3, 3:51 PM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3228380
Attached To
D4502: Use an attr class instead of a dict to store parsed headers.
Event Timeline
Log In to Comment