comparison sat/plugins/plugin_comp_ap_gateway/__init__.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 996e0f84935e
comparison
equal deleted inserted replaced
3976:db45d49518f6 3977:6fa4ca0c047e
18 18
19 import base64 19 import base64
20 import calendar 20 import calendar
21 import hashlib 21 import hashlib
22 import json 22 import json
23 from os import access
24 from pathlib import Path 23 from pathlib import Path
25 from pprint import pformat 24 from pprint import pformat
26 import re 25 import re
27 from typing import ( 26 from typing import (
28 Any, 27 Any,
31 Dict, 30 Dict,
32 List, 31 List,
33 Optional, 32 Optional,
34 Set, 33 Set,
35 Tuple, 34 Tuple,
36 Type,
37 Union, 35 Union,
38 overload, 36 overload,
39 ) 37 )
40 from urllib import parse 38 from urllib import parse
41 39
264 # mention specified inside the item directly). See documentation for details. 262 # mention specified inside the item directly). See documentation for details.
265 self.auto_mentions = C.bool( 263 self.auto_mentions = C.bool(
266 self.host.memory.getConfig(CONF_SECTION, "auto_mentions", C.BOOL_TRUE) 264 self.host.memory.getConfig(CONF_SECTION, "auto_mentions", C.BOOL_TRUE)
267 ) 265 )
268 266
267 html_redirect: Dict[str, Union[str, dict]] = self.host.memory.getConfig(
268 CONF_SECTION, 'html_redirect_dict', {}
269 )
270 self.html_redirect: Dict[str, List[dict]] = {}
271 for url_type, target in html_redirect.items():
272 if isinstance(target, str):
273 target = {"url": target}
274 elif not isinstance(target, dict):
275 raise exceptions.ConfigError(
276 f"html_redirect target must be a URL or a dict, not {target!r}"
277 )
278 filters = target.setdefault("filters", {})
279 if "url" not in target:
280 log.warning(f"invalid HTML redirection, missing target URL: {target}")
281 continue
282 # a slash in the url_type is a syntactic shortcut to have a node filter
283 if "/" in url_type:
284 url_type, node_filter = url_type.split("/", 1)
285 filters["node"] = node_filter
286 self.html_redirect.setdefault(url_type, []).append(target)
287
269 # HTTP server launch 288 # HTTP server launch
270 self.server = HTTPServer(self) 289 self.server = HTTPServer(self)
271 if connection_type == 'http': 290 if connection_type == 'http':
272 reactor.listenTCP(self.http_port, self.server) 291 reactor.listenTCP(self.http_port, self.server)
273 else: 292 else:
359 if resp.code >= 300: 378 if resp.code >= 300:
360 text = await resp.text() 379 text = await resp.text()
361 if resp.code == 404: 380 if resp.code == 404:
362 raise exceptions.NotFound(f"Can't find resource at {url}") 381 raise exceptions.NotFound(f"Can't find resource at {url}")
363 else: 382 else:
364 msg = f"HTTP error {resp.code}: {text}" 383 msg = f"HTTP error {resp.code} (url: {url}): {text}"
365 raise exceptions.ExternalRequestError(msg) 384 raise exceptions.ExternalRequestError(msg)
366 try: 385 try:
367 return await treq.json_content(resp) 386 return await treq.json_content(resp)
368 except Exception as e: 387 except Exception as e:
369 raise error.StanzaError( 388 raise error.StanzaError(