A base class for incoming HTTP connections, that is used to provide any functionality that is common to both `Request` and `WebSocket`.
| 78 | |
| 79 | |
| 80 | class HTTPConnection(Mapping[str, Any], Generic[StateT]): |
| 81 | """ |
| 82 | A base class for incoming HTTP connections, that is used to provide |
| 83 | any functionality that is common to both `Request` and `WebSocket`. |
| 84 | """ |
| 85 | |
| 86 | def __init__(self, scope: Scope, receive: Receive | None = None) -> None: |
| 87 | assert scope["type"] in ("http", "websocket") |
| 88 | self.scope = scope |
| 89 | |
| 90 | def __getitem__(self, key: str) -> Any: |
| 91 | return self.scope[key] |
| 92 | |
| 93 | def __iter__(self) -> Iterator[str]: |
| 94 | return iter(self.scope) |
| 95 | |
| 96 | def __len__(self) -> int: |
| 97 | return len(self.scope) |
| 98 | |
| 99 | # Don't use the `abc.Mapping.__eq__` implementation. |
| 100 | # Connection instances should never be considered equal |
| 101 | # unless `self is other`. |
| 102 | __eq__ = object.__eq__ |
| 103 | __hash__ = object.__hash__ |
| 104 | |
| 105 | @property |
| 106 | def app(self) -> Any: |
| 107 | return self.scope["app"] |
| 108 | |
| 109 | @property |
| 110 | def url(self) -> URL: |
| 111 | if not hasattr(self, "_url"): # pragma: no branch |
| 112 | self._url = URL(scope=self.scope) |
| 113 | return self._url |
| 114 | |
| 115 | @property |
| 116 | def base_url(self) -> URL: |
| 117 | if not hasattr(self, "_base_url"): |
| 118 | base_url_scope = dict(self.scope) |
| 119 | # This is used by request.url_for, it might be used inside a Mount which |
| 120 | # would have its own child scope with its own root_path, but the base URL |
| 121 | # for url_for should still be the top level app root path. |
| 122 | app_root_path = base_url_scope.get("app_root_path", base_url_scope.get("root_path", "")) |
| 123 | path = app_root_path |
| 124 | if not path.endswith("/"): |
| 125 | path += "/" |
| 126 | base_url_scope["path"] = path |
| 127 | base_url_scope["query_string"] = b"" |
| 128 | base_url_scope["root_path"] = app_root_path |
| 129 | self._base_url = URL(scope=base_url_scope) |
| 130 | return self._base_url |
| 131 | |
| 132 | @property |
| 133 | def headers(self) -> Headers: |
| 134 | if not hasattr(self, "_headers"): |
| 135 | self._headers = Headers(scope=self.scope) |
| 136 | return self._headers |
| 137 |