gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
34.04k stars 2.59k forks source link

Certain static files are requested over http (instead of https) behind kubernetes proxy #9381

Open flacomalone opened 2 months ago

flacomalone commented 2 months ago

Describe the bug

After attempting to reproduce the settings shown in https://www.gradio.app/guides/running-gradio-on-your-web-server-with-nginx as well as having tried several solutions discussed in other issues in this repo and others (FastAPI, Nginx, etc.) I find myself clueless how to solve this issue.

Basically, I have my dockerised gradio application that does some pretty basic stuff, being one of them displaying some audios. The application works well in localhost. The problem comes when I deploy it on kubernetes cluster (the url runs on https). This cluster features both an k8s ingress controller and an nginx load balancer which setup the SSL connection for the client.

Overall, the app seems fine, but SOME static files (/assets/index-DuXXhepF.css, favicon.ico and the aforementioned audio files in wav format) are not received correctly. For the .css and favicon file it returns a 404 status code (the app seems fine, though), but for the audios there is a mixed block issue. If I have a look at the request, I can see that the request is made to http://......

image

The audio can still be accessed by that URL, and can be effectively downloaded via browser. Moreover, if I attempt to make the request again manually this time changing the scheme to https, the audio is received successfully:

image

Moreover, if I perform a port forwarding from k8s to localhost everything seems fine, which goes to tell that the problem is probably in the proxy.

My question is: why some some of these files are being requested over http, causing this error?

Have you searched existing issues? 🔎

Reproduction

The gradio app is the least important thing here I think. Just assume that it displays an audio that is publicly available

import gradio as gr

audio_bytes = # take any random audio and load it as numpy, for example

with gr.Blocks() as demo:
    audio = gr.Audio(value=audio_bytes)

demo.queue()
demo.launch(
    favicon_path="favicon.png",
    server_name="0.0.0.0",
    server_port=8080,
    root_path="/text-to-speech-experimental",

for my kubernetes ingress.yaml file I have the following:

  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "100m"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Proto $scheme;
      more_set_input_headers "Forwarded: for=$remote_addr;host=$host;proto=https";

I have also tried setting up the env variable FORWARDED_ALLOW_IPS="*" for testing purposes, but it still renders the same result.

Screenshot

No response

Logs

No response

System Info

Gradio Environment Information:
------------------------------
Operating System: Linux
gradio version: 4.44.0
gradio_client version: 1.3.0

------------------------------------------------
gradio dependencies in your environment:

aiofiles: 23.2.1
anyio: 4.4.0
fastapi: 0.115.0
ffmpy: 0.4.0
gradio-client==1.3.0 is not installed.
httpx: 0.27.2
huggingface-hub: 0.25.0
importlib-resources: 6.4.5
jinja2: 3.1.4
markupsafe: 2.1.5
matplotlib: 3.9.2
uvicorn: 0.30.6
authlib; extra == 'oauth' is not installed.
itsdangerous; extra == 'oauth' is not installed.

gradio_client dependencies in your environment:

fsspec: 2024.9.0
httpx: 0.27.2
huggingface-hub: 0.25.0
packaging: 24.1
typing-extensions: 4.12.2
websockets: 12.0

Severity

Blocking usage of gradio

cornzz commented 2 months ago

I also had the favicon issue with a custom root_path and at least that you can work around, see my comment here.

flacomalone commented 1 day ago

UPDATE:

I solved it by adding the following configuration to my ingress.yaml:

annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/configuration-snippet: |
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto https;
        add_header Content-Security-Policy "upgrade-insecure-requests";

Thanks to RHOWL3 for posting his solution in this link.