Parse and validate a WebSocket URI. Args: uri: WebSocket URI. Returns: Parsed WebSocket URI. Raises: InvalidURI: If ``uri`` isn't a valid WebSocket URI.
(uri: str)
| 58 | |
| 59 | |
| 60 | def parse_uri(uri: str) -> WebSocketURI: |
| 61 | """ |
| 62 | Parse and validate a WebSocket URI. |
| 63 | |
| 64 | Args: |
| 65 | uri: WebSocket URI. |
| 66 | |
| 67 | Returns: |
| 68 | Parsed WebSocket URI. |
| 69 | |
| 70 | Raises: |
| 71 | InvalidURI: If ``uri`` isn't a valid WebSocket URI. |
| 72 | |
| 73 | """ |
| 74 | parsed = urllib.parse.urlparse(uri) |
| 75 | if parsed.scheme not in ["ws", "wss"]: |
| 76 | raise InvalidURI(uri, "scheme isn't ws or wss") |
| 77 | if parsed.hostname is None: |
| 78 | raise InvalidURI(uri, "hostname isn't provided") |
| 79 | if parsed.fragment != "": |
| 80 | raise InvalidURI(uri, "fragment identifier is meaningless") |
| 81 | |
| 82 | secure = parsed.scheme == "wss" |
| 83 | host = parsed.hostname |
| 84 | port = parsed.port or (443 if secure else 80) |
| 85 | path = parsed.path |
| 86 | query = parsed.query |
| 87 | username = parsed.username |
| 88 | password = parsed.password |
| 89 | # urllib.parse.urlparse accepts URLs with a username but without a |
| 90 | # password. This doesn't make sense for HTTP Basic Auth credentials. |
| 91 | if username is not None and password is None: |
| 92 | raise InvalidURI(uri, "username provided without password") |
| 93 | |
| 94 | try: |
| 95 | uri.encode("ascii") |
| 96 | except UnicodeEncodeError: |
| 97 | # Input contains non-ASCII characters. |
| 98 | # It must be an IRI. Convert it to a URI. |
| 99 | host = host.encode("idna").decode() |
| 100 | path = urllib.parse.quote(path, safe=DELIMS) |
| 101 | query = urllib.parse.quote(query, safe=DELIMS) |
| 102 | if username is not None: |
| 103 | assert password is not None |
| 104 | username = urllib.parse.quote(username, safe=DELIMS) |
| 105 | password = urllib.parse.quote(password, safe=DELIMS) |
| 106 | |
| 107 | return WebSocketURI(secure, host, port, path, query, username, password) |
searching dependent graphs…