Mercurial > libervia-backend
comparison sat/plugins/plugin_comp_ap_gateway/http_server.py @ 3977:6fa4ca0c047e
component AP gateway: HTML redirection:
when a request is done on AP endpoint and `Accept` header is not set to
`application/json`, the request can now be redirected to a configurable URL.
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 11 Nov 2022 13:51:20 +0100 |
parents | 0aa7023dcd08 |
children | 9b5092225e46 |
comparison
equal
deleted
inserted
replaced
3976:db45d49518f6 | 3977:6fa4ca0c047e |
---|---|
24 from collections import deque | 24 from collections import deque |
25 import unicodedata | 25 import unicodedata |
26 | 26 |
27 from twisted.web import http, resource as web_resource, server | 27 from twisted.web import http, resource as web_resource, server |
28 from twisted.web import static | 28 from twisted.web import static |
29 from twisted.web import util as web_util | |
29 from twisted.python import failure | 30 from twisted.python import failure |
30 from twisted.internet import defer | 31 from twisted.internet import defer |
31 from twisted.words.protocols.jabber import jid, error | 32 from twisted.words.protocols.jabber import jid, error |
32 from wokkel import pubsub, rsm | 33 from wokkel import pubsub, rsm |
33 | 34 |
38 from sat.core.log import getLogger | 39 from sat.core.log import getLogger |
39 from sat.tools.common import date_utils, uri | 40 from sat.tools.common import date_utils, uri |
40 from sat.memory.sqla_mapping import SubscriptionState | 41 from sat.memory.sqla_mapping import SubscriptionState |
41 | 42 |
42 from .constants import ( | 43 from .constants import ( |
43 NS_AP, CONTENT_TYPE_AP, TYPE_ACTOR, TYPE_INBOX, TYPE_SHARED_INBOX, TYPE_OUTBOX, | 44 NS_AP, MEDIA_TYPE_AP, CONTENT_TYPE_AP, TYPE_ACTOR, TYPE_INBOX, TYPE_SHARED_INBOX, |
44 TYPE_EVENT, AP_REQUEST_TYPES, PAGE_SIZE, ACTIVITY_TYPES_LOWER, | 45 TYPE_OUTBOX, TYPE_EVENT, AP_REQUEST_TYPES, PAGE_SIZE, ACTIVITY_TYPES_LOWER, |
45 ACTIVIY_NO_ACCOUNT_ALLOWED, SIGN_HEADERS, HS2019, SIGN_EXP, TYPE_FOLLOWERS, | 46 ACTIVIY_NO_ACCOUNT_ALLOWED, SIGN_HEADERS, HS2019, SIGN_EXP, TYPE_FOLLOWERS, |
46 TYPE_FOLLOWING, TYPE_ITEM, TYPE_LIKE, TYPE_REACTION, ST_AP_CACHE | 47 TYPE_FOLLOWING, TYPE_ITEM, TYPE_LIKE, TYPE_REACTION, ST_AP_CACHE |
47 ) | 48 ) |
48 from .regex import RE_SIG_PARAM | 49 from .regex import RE_SIG_PARAM |
49 | 50 |
947 ap_url = parse.urljoin( | 948 ap_url = parse.urljoin( |
948 f"https://{self.apg.public_url}", | 949 f"https://{self.apg.public_url}", |
949 path | 950 path |
950 ) | 951 ) |
951 request_type, extra_args = self.apg.parseAPURL(ap_url) | 952 request_type, extra_args = self.apg.parseAPURL(ap_url) |
953 if ((request.getHeader("accept") != MEDIA_TYPE_AP | |
954 and request_type in self.apg.html_redirect)): | |
955 # this is not a AP request, and we have a redirections for it | |
956 kw = {} | |
957 if extra_args: | |
958 kw["jid"], kw["node"] = await self.apg.getJIDAndNode(extra_args[0]) | |
959 kw["jid_user"] = kw["jid"].user | |
960 if kw["node"] is None: | |
961 kw["node"] = self.apg._m.namespace | |
962 if len(extra_args) > 1: | |
963 kw["item"] = extra_args[1] | |
964 else: | |
965 kw["item"] = "" | |
966 else: | |
967 kw["jid"], kw["jid_user"], kw["node"], kw["item"] = "", "", "", "" | |
968 | |
969 redirections = self.apg.html_redirect[request_type] | |
970 for redirection in redirections: | |
971 filters = redirection["filters"] | |
972 if not filters: | |
973 break | |
974 # if we have filter, they must all match | |
975 elif all(v in kw[k] for k,v in filters.items()): | |
976 break | |
977 else: | |
978 # no redirection is matching | |
979 redirection = None | |
980 | |
981 if redirection is not None: | |
982 kw = {k: parse.quote(str(v), safe="") for k,v in kw.items()} | |
983 target_url = redirection["url"].format(**kw) | |
984 content = web_util.redirectTo(target_url.encode(), request) | |
985 request.write(content) | |
986 request.finish() | |
987 return | |
988 | |
952 if len(extra_args) == 0: | 989 if len(extra_args) == 0: |
953 if request_type != "shared_inbox": | 990 if request_type != "shared_inbox": |
954 raise exceptions.DataError(f"Invalid request type: {request_type!r}") | 991 raise exceptions.DataError(f"Invalid request type: {request_type!r}") |
955 ret_data = await self.APInboxRequest( | 992 ret_data = await self.APInboxRequest( |
956 request, None, None, None, ap_url, signing_actor | 993 request, None, None, None, ap_url, signing_actor |