# Path: starlette/datastructures.py
# class URL:
#     def __init__(
#         self,
#         url: str = "",
#         scope: typing.Optional[Scope] = None,
#         **components: typing.Any,
#     ) -> None:
#         if scope is not None:
#             assert not url, 'Cannot set both "url" and "scope".'
#             assert not components, 'Cannot set both "scope" and "**components".'
#             scheme = scope.get("scheme", "http")
#             server = scope.get("server", None)
#             path = scope.get("root_path", "") + scope["path"]
#             query_string = scope.get("query_string", b"")
# 
#             host_header = None
#             for key, value in scope["headers"]:
#                 if key == b"host":
#                     host_header = value.decode("latin-1")
#                     break
# 
#             if host_header is not None:
#                 url = f"{scheme}://{host_header}{path}"
#             elif server is None:
#                 url = path
#             else:
#                 host, port = server
#                 default_port = {"http": 80, "https": 443, "ws": 80, "wss": 443}[scheme]
#                 if port == default_port:
#                     url = f"{scheme}://{host}{path}"
#                 else:
#                     url = f"{scheme}://{host}:{port}{path}"
# 
#             if query_string:
#                 url += "?" + query_string.decode()
#         elif components:
#             assert not url, 'Cannot set both "url" and "**components".'
#             url = URL("").replace(**components).components.geturl()
# 
#         self._url = url
# 
#     @property
#     def components(self) -> SplitResult:
#         if not hasattr(self, "_components"):
#             self._components = urlsplit(self._url)
#         return self._components
# 
#     @property
#     def scheme(self) -> str:
#         return self.components.scheme
# 
#     @property
#     def netloc(self) -> str:
#         return self.components.netloc
# 
#     @property
#     def path(self) -> str:
#         return self.components.path
# 
#     @property
#     def query(self) -> str:
#         return self.components.query
# 
#     @property
#     def fragment(self) -> str:
#         return self.components.fragment
# 
#     @property
#     def username(self) -> typing.Union[None, str]:
#         return self.components.username
# 
#     @property
#     def password(self) -> typing.Union[None, str]:
#         return self.components.password
# 
#     @property
#     def hostname(self) -> typing.Union[None, str]:
#         return self.components.hostname
# 
#     @property
#     def port(self) -> typing.Optional[int]:
#         return self.components.port
# 
#     @property
#     def is_secure(self) -> bool:
#         return self.scheme in ("https", "wss")
# 
#     def replace(self, **kwargs: typing.Any) -> "URL":
#         if (
#             "username" in kwargs
#             or "password" in kwargs
#             or "hostname" in kwargs
#             or "port" in kwargs
#         ):
#             hostname = kwargs.pop("hostname", self.hostname)
#             port = kwargs.pop("port", self.port)
#             username = kwargs.pop("username", self.username)
#             password = kwargs.pop("password", self.password)
# 
#             netloc = hostname
#             if port is not None:
#                 netloc += f":{port}"
#             if username is not None:
#                 userpass = username
#                 if password is not None:
#                     userpass += f":{password}"
#                 netloc = f"{userpass}@{netloc}"
# 
#             kwargs["netloc"] = netloc
# 
#         components = self.components._replace(**kwargs)
#         return self.__class__(components.geturl())
# 
#     def include_query_params(self, **kwargs: typing.Any) -> "URL":
#         params = MultiDict(parse_qsl(self.query, keep_blank_values=True))
#         params.update({str(key): str(value) for key, value in kwargs.items()})
#         query = urlencode(params.multi_items())
#         return self.replace(query=query)
# 
#     def replace_query_params(self, **kwargs: typing.Any) -> "URL":
#         query = urlencode([(str(key), str(value)) for key, value in kwargs.items()])
#         return self.replace(query=query)
# 
#     def remove_query_params(
#         self, keys: typing.Union[str, typing.Sequence[str]]
#     ) -> "URL":
#         if isinstance(keys, str):
#             keys = [keys]
#         params = MultiDict(parse_qsl(self.query, keep_blank_values=True))
#         for key in keys:
#             params.pop(key, None)
#         query = urlencode(params.multi_items())
#         return self.replace(query=query)
# 
#     def __eq__(self, other: typing.Any) -> bool:
#         return str(self) == str(other)
# 
#     def __str__(self) -> str:
#         return self._url
# 
#     def __repr__(self) -> str:
#         url = str(self)
#         if self.password:
#             url = str(self.replace(password="********"))
#         return f"{self.__class__.__name__}({repr(url)})"
# 
# Path: starlette/responses.py
# class RedirectResponse(Response):
#     def __init__(
#         self,
#         url: typing.Union[str, URL],
#         status_code: int = 307,
#         headers: typing.Mapping[str, str] = None,
#         background: BackgroundTask = None,
#     ) -> None:
#         super().__init__(
#             content=b"", status_code=status_code, headers=headers, background=background
#         )
#         self.headers["location"] = quote(str(url), safe=":/%#?=@[]!$&'()*+,;")
# 
# Path: starlette/types.py



from starlette.datastructures import URL
from starlette.responses import RedirectResponse
from starlette.types import ASGIApp, Receive, Scope, Send


class HTTPSRedirectMiddleware:
    def __init__(self, app: ASGIApp) -> None:
        self.app = app


# Path: starlette/datastructures.py
# class URL:
#     def __init__(
#         self,
#         url: str = "",
#         scope: typing.Optional[Scope] = None,
#         **components: typing.Any,
#     ) -> None:
#         if scope is not None:
#             assert not url, 'Cannot set both "url" and "scope".'
#             assert not components, 'Cannot set both "scope" and "**components".'
#             scheme = scope.get("scheme", "http")
#             server = scope.get("server", None)
#             path = scope.get("root_path", "") + scope["path"]
#             query_string = scope.get("query_string", b"")
# 
#             host_header = None
#             for key, value in scope["headers"]:
#                 if key == b"host":
#                     host_header = value.decode("latin-1")
#                     break
# 
#             if host_header is not None:
#                 url = f"{scheme}://{host_header}{path}"
#             elif server is None:
#                 url = path
#             else:
#                 host, port = server
#                 default_port = {"http": 80, "https": 443, "ws": 80, "wss": 443}[scheme]
#                 if port == default_port:
#                     url = f"{scheme}://{host}{path}"
#                 else:
#                     url = f"{scheme}://{host}:{port}{path}"
# 
#             if query_string:
#                 url += "?" + query_string.decode()
#         elif components:
#             assert not url, 'Cannot set both "url" and "**components".'
#             url = URL("").replace(**components).components.geturl()
# 
#         self._url = url
# 
#     @property
#     def components(self) -> SplitResult:
#         if not hasattr(self, "_components"):
#             self._components = urlsplit(self._url)
#         return self._components
# 
#     @property
#     def scheme(self) -> str:
#         return self.components.scheme
# 
#     @property
#     def netloc(self) -> str:
#         return self.components.netloc
# 
#     @property
#     def path(self) -> str:
#         return self.components.path
# 
#     @property
#     def query(self) -> str:
#         return self.components.query
# 
#     @property
#     def fragment(self) -> str:
#         return self.components.fragment
# 
#     @property
#     def username(self) -> typing.Union[None, str]:
#         return self.components.username
# 
#     @property
#     def password(self) -> typing.Union[None, str]:
#         return self.components.password
# 
#     @property
#     def hostname(self) -> typing.Union[None, str]:
#         return self.components.hostname
# 
#     @property
#     def port(self) -> typing.Optional[int]:
#         return self.components.port
# 
#     @property
#     def is_secure(self) -> bool:
#         return self.scheme in ("https", "wss")
# 
#     def replace(self, **kwargs: typing.Any) -> "URL":
#         if (
#             "username" in kwargs
#             or "password" in kwargs
#             or "hostname" in kwargs
#             or "port" in kwargs
#         ):
#             hostname = kwargs.pop("hostname", self.hostname)
#             port = kwargs.pop("port", self.port)
#             username = kwargs.pop("username", self.username)
#             password = kwargs.pop("password", self.password)
# 
#             netloc = hostname
#             if port is not None:
#                 netloc += f":{port}"
#             if username is not None:
#                 userpass = username
#                 if password is not None:
#                     userpass += f":{password}"
#                 netloc = f"{userpass}@{netloc}"
# 
#             kwargs["netloc"] = netloc
# 
#         components = self.components._replace(**kwargs)
#         return self.__class__(components.geturl())
# 
#     def include_query_params(self, **kwargs: typing.Any) -> "URL":
#         params = MultiDict(parse_qsl(self.query, keep_blank_values=True))
#         params.update({str(key): str(value) for key, value in kwargs.items()})
#         query = urlencode(params.multi_items())
#         return self.replace(query=query)
# 
#     def replace_query_params(self, **kwargs: typing.Any) -> "URL":
#         query = urlencode([(str(key), str(value)) for key, value in kwargs.items()])
#         return self.replace(query=query)
# 
#     def remove_query_params(
#         self, keys: typing.Union[str, typing.Sequence[str]]
#     ) -> "URL":
#         if isinstance(keys, str):
#             keys = [keys]
#         params = MultiDict(parse_qsl(self.query, keep_blank_values=True))
#         for key in keys:
#             params.pop(key, None)
#         query = urlencode(params.multi_items())
#         return self.replace(query=query)
# 
#     def __eq__(self, other: typing.Any) -> bool:
#         return str(self) == str(other)
# 
#     def __str__(self) -> str:
#         return self._url
# 
#     def __repr__(self) -> str:
#         url = str(self)
#         if self.password:
#             url = str(self.replace(password="********"))
#         return f"{self.__class__.__name__}({repr(url)})"
# 
# Path: starlette/responses.py
# class RedirectResponse(Response):
#     def __init__(
#         self,
#         url: typing.Union[str, URL],
#         status_code: int = 307,
#         headers: typing.Mapping[str, str] = None,
#         background: BackgroundTask = None,
#     ) -> None:
#         super().__init__(
#             content=b"", status_code=status_code, headers=headers, background=background
#         )
#         self.headers["location"] = quote(str(url), safe=":/%#?=@[]!$&'()*+,;")
# 
# Path: starlette/types.py



# Path: starlette/middleware/httpsredirect.py
from starlette.datastructures import URL
from starlette.responses import RedirectResponse
from starlette.types import ASGIApp, Receive, Scope, Send



class HTTPSRedirectMiddleware:
    def __init__(self, app: ASGIApp) -> None:
        self.app = app


    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: