No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

80 líneas
2.0 KiB

  1. """
  2. :mod:`websockets.uri` parses WebSocket URIs.
  3. See `section 3 of RFC 6455`_.
  4. .. _section 3 of RFC 6455: http://tools.ietf.org/html/rfc6455#section-3
  5. """
  6. import urllib.parse
  7. from typing import NamedTuple, Optional, Tuple
  8. from .exceptions import InvalidURI
  9. __all__ = ["parse_uri", "WebSocketURI"]
  10. # Consider converting to a dataclass when dropping support for Python < 3.7.
  11. class WebSocketURI(NamedTuple):
  12. secure: bool
  13. host: str
  14. port: int
  15. resource_name: str
  16. user_info: Optional[Tuple[str, str]]
  17. # Declare the docstring normally when dropping support for Python < 3.6.1.
  18. WebSocketURI.__doc__ = """
  19. WebSocket URI.
  20. :param bool secure: secure flag
  21. :param str host: lower-case host
  22. :param int port: port, always set even if it's the default
  23. :param str resource_name: path and optional query
  24. :param str user_info: ``(username, password)`` tuple when the URI contains
  25. `User Information`_, else ``None``.
  26. .. _User Information: https://tools.ietf.org/html/rfc3986#section-3.2.1
  27. """
  28. # Work around https://bugs.python.org/issue19931
  29. WebSocketURI.secure.__doc__ = ""
  30. WebSocketURI.host.__doc__ = ""
  31. WebSocketURI.port.__doc__ = ""
  32. WebSocketURI.resource_name.__doc__ = ""
  33. WebSocketURI.user_info.__doc__ = ""
  34. def parse_uri(uri: str) -> WebSocketURI:
  35. """
  36. Parse and validate a WebSocket URI.
  37. :raises ValueError: if ``uri`` isn't a valid WebSocket URI.
  38. """
  39. parsed = urllib.parse.urlparse(uri)
  40. try:
  41. assert parsed.scheme in ["ws", "wss"]
  42. assert parsed.params == ""
  43. assert parsed.fragment == ""
  44. assert parsed.hostname is not None
  45. except AssertionError as exc:
  46. raise InvalidURI(uri) from exc
  47. secure = parsed.scheme == "wss"
  48. host = parsed.hostname
  49. port = parsed.port or (443 if secure else 80)
  50. resource_name = parsed.path or "/"
  51. if parsed.query:
  52. resource_name += "?" + parsed.query
  53. user_info = None
  54. if parsed.username or parsed.password:
  55. user_info = (parsed.username, parsed.password)
  56. return WebSocketURI(secure, host, port, resource_name, user_info)