def get_root_url(
    request: fastapi.Request, route_path: str, root_path: str | None
) -> str:
    """
    Gets the root url of the Gradio app (i.e. the public url of the app) without a trailing slash.

    This is how the root_url is resolved:
    1. If a user provides a `root_path` manually that is a full URL, it is returned directly.
    2. If the request has an x-forwarded-host header (e.g. because it is behind a proxy), the root url is
    constructed from the x-forwarded-host header. In this case, `route_path` is not used to construct the root url.
    3. Otherwise, the root url is constructed from the request url. The query parameters and `route_path` are stripped off.
    And if a relative `root_path` is provided, and it is not already the subpath of the URL, it is appended to the root url.

    In cases (2) and (3), We also check to see if the x-forwarded-proto header is present, and if so, convert the root url to https.
    And if there are multiple hosts in the x-forwarded-host or multiple protocols in the x-forwarded-proto, the first one is used.
    """

    if root_path and client_utils.is_http_url_like(root_path):
        return root_path.rstrip("/")

    root_url = get_request_origin(request, route_path)

    if root_path and root_url.path != root_path:
        root_url = root_url.copy_with(path=root_path)

    return str(root_url).rstrip("/")

    Gets the root url of the Gradio app (i.e. the public url of the app) without a trailing slash.

    This is how the root_url is resolved:
    1. If a user provides a `root_path` manually that is a full URL, it is returned directly.
    2. If the request has an x-forwarded-host header (e.g. because it is behind a proxy), the root url is
    constructed from the x-forwarded-host header. In this case, `route_path` is not used to construct the root url.
    3. Otherwise, the root url is constructed from the request url. The query parameters and `route_path` are stripped off.
    And if a relative `root_path` is provided, and it is not already the subpath of the URL, it is appended to the root url.

    In cases (2) and (3), We also check to see if the x-forwarded-proto header is present, and if so, convert the root url to https.
    And if there are multiple hosts in the x-forwarded-host or multiple protocols in the x-forwarded-proto, the first one is used.
    
gradio/route_utils.py