component AP gateway: parse body immediately on POST request:
the body is parsed immediately during a `POST` request: this avoids duplication of code, and allows to check the body data before continuing (will be used to filter some requests in a future patch).
This commit is contained in:
parent
d6f710bd0b
commit
4d14a623fc
1 changed files with 41 additions and 32 deletions
|
|
@ -560,6 +560,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
async def APActorRequest(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
account_jid: jid.JID,
|
||||
node: Optional[str],
|
||||
ap_account: str,
|
||||
|
|
@ -662,6 +663,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
async def APOutboxPageRequest(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
account_jid: jid.JID,
|
||||
node: Optional[str],
|
||||
ap_account: str,
|
||||
|
|
@ -709,7 +711,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
)
|
||||
for item in reversed(items)
|
||||
]
|
||||
data = {
|
||||
ret_data = {
|
||||
"@context": ["https://www.w3.org/ns/activitystreams"],
|
||||
"id": url,
|
||||
"type": "OrderedCollectionPage",
|
||||
|
|
@ -724,19 +726,20 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
last= metadata["rsm"]["last"]
|
||||
except KeyError:
|
||||
last = None
|
||||
data["prev"] = f"{base_url}?{parse.urlencode({'after': last})}"
|
||||
ret_data["prev"] = f"{base_url}?{parse.urlencode({'after': last})}"
|
||||
if metadata["rsm"]["index"] != 0:
|
||||
try:
|
||||
first= metadata["rsm"]["first"]
|
||||
except KeyError:
|
||||
first = None
|
||||
data["next"] = f"{base_url}?{parse.urlencode({'before': first})}"
|
||||
ret_data["next"] = f"{base_url}?{parse.urlencode({'before': first})}"
|
||||
|
||||
return data
|
||||
return ret_data
|
||||
|
||||
async def APOutboxRequest(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
account_jid: jid.JID,
|
||||
node: Optional[str],
|
||||
ap_account: str,
|
||||
|
|
@ -794,24 +797,16 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
async def APInboxRequest(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
account_jid: Optional[jid.JID],
|
||||
node: Optional[str],
|
||||
ap_account: Optional[str],
|
||||
ap_url: str,
|
||||
signing_actor: Optional[str]
|
||||
) -> None:
|
||||
assert data is not None
|
||||
if signing_actor is None:
|
||||
raise exceptions.InternalError("signing_actor must be set for inbox requests")
|
||||
try:
|
||||
data = json.load(request.content)
|
||||
if not isinstance(data, dict):
|
||||
raise ValueError("data should be an object")
|
||||
except (json.JSONDecodeError, ValueError) as e:
|
||||
return self.responseCode(
|
||||
request,
|
||||
http.BAD_REQUEST,
|
||||
f"invalid json in inbox request: {e}"
|
||||
)
|
||||
await self.checkSigningActor(data, signing_actor)
|
||||
activity_type = (data.get("type") or "").lower()
|
||||
if not activity_type in ACTIVITY_TYPES_LOWER:
|
||||
|
|
@ -844,6 +839,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
async def APFollowersRequest(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
account_jid: jid.JID,
|
||||
node: Optional[str],
|
||||
ap_account: Optional[str],
|
||||
|
|
@ -882,6 +878,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
async def APFollowingRequest(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
account_jid: jid.JID,
|
||||
node: Optional[str],
|
||||
ap_account: Optional[str],
|
||||
|
|
@ -921,6 +918,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
async def APRequest(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict] = None,
|
||||
signing_actor: Optional[str] = None
|
||||
) -> None:
|
||||
if self.apg.verbose:
|
||||
|
|
@ -929,14 +927,8 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
"",
|
||||
f"<<< got {request.method.decode()} request - {request.uri.decode()}"
|
||||
]
|
||||
try:
|
||||
data = json.load(request.content)
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
pass
|
||||
else:
|
||||
if data is not None:
|
||||
to_log.append(pformat(data))
|
||||
finally:
|
||||
request.content.seek(0)
|
||||
if self.apg.verbose>=3:
|
||||
headers = "\n".join(
|
||||
f" {k.decode()}: {v.decode()}"
|
||||
|
|
@ -990,7 +982,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
if request_type != "shared_inbox":
|
||||
raise exceptions.DataError(f"Invalid request type: {request_type!r}")
|
||||
ret_data = await self.APInboxRequest(
|
||||
request, None, None, None, ap_url, signing_actor
|
||||
request, data, None, None, None, ap_url, signing_actor
|
||||
)
|
||||
elif request_type == "avatar":
|
||||
if len(extra_args) != 1:
|
||||
|
|
@ -1013,7 +1005,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
raise exceptions.DataError(f"Invalid request type: {request_type!r}")
|
||||
method = getattr(self, f"AP{request_type.title()}Request")
|
||||
ret_data = await method(
|
||||
request, account_jid, node, ap_account, ap_url, signing_actor
|
||||
request, data, account_jid, node, ap_account, ap_url, signing_actor
|
||||
)
|
||||
if ret_data is not None:
|
||||
request.setHeader("content-type", CONTENT_TYPE_AP)
|
||||
|
|
@ -1027,7 +1019,26 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
log.info("\n".join(to_log))
|
||||
request.finish()
|
||||
|
||||
async def APPostRequest(self, request: "HTTPRequest"):
|
||||
async def APPostRequest(self, request: "HTTPRequest") -> None:
|
||||
try:
|
||||
data = json.load(request.content)
|
||||
if not isinstance(data, dict):
|
||||
log.warning(f"JSON data should be an object (uri={request.uri.decode()})")
|
||||
self.responseCode(
|
||||
request,
|
||||
http.BAD_REQUEST,
|
||||
f"invalid body, was expecting a JSON object"
|
||||
)
|
||||
request.finish()
|
||||
return
|
||||
except (json.JSONDecodeError, ValueError) as e:
|
||||
self.responseCode(
|
||||
request,
|
||||
http.BAD_REQUEST,
|
||||
f"invalid json in inbox request: {e}"
|
||||
)
|
||||
request.finish()
|
||||
return
|
||||
try:
|
||||
signing_actor = await self.checkSignature(request)
|
||||
except exceptions.EncryptionError as e:
|
||||
|
|
@ -1050,7 +1061,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
|
||||
# default response code, may be changed, e.g. in case of exception
|
||||
try:
|
||||
return await self.APRequest(request, signing_actor)
|
||||
return await self.APRequest(request, data, signing_actor)
|
||||
except Exception as e:
|
||||
self._onRequestError(failure.Failure(e), request)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue