New to APIFlask, but I have a small app that works fine locally. I can go to /docs to load Swagger UI then use that to successfully test my endpoints.
However, when I deploy it to my staging environment and use Swagger UI to hit an endpoint, I get a NetworkError - and if I open the browser console, I see the following error:
Blocked loading mixed active content “http://MYHOST.com/foo”
(I replaced the real domain name with MYHOST for privacy, and foo is an endpoint I use for testing basic health.)
The error message also includes a link to this reference: https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content
I'm not an expert on this particular area, but I'm guessing it's because I'm using http locally, but using https in the staging environment, and when the Swagger UI is loaded via https and then tries to hit /foo using http, it triggers the Mixed Content error.
What's the fix for this?
tl;dr - I added
--forwarded-allow-ips="*"to my gunicorn command line.The relevant behavior is described in the Gunicorn source:
This explains why I saw different behavior locally vs deployed with a real IP address, but it's still worth explaining how it specifically determines the server URL that ends up in the Swagger UI dropdown box.
The
apiflask.APIFlaskclass determines what URL(s) to put in the dropdown box based on theSERVERSconfig setting (which is inflexible) or based on the value ofrequest.url_root(src):The
APIFlaskclass inherits fromflask.Flask, which uses aRequestclass that inherits fromwerkzeug.wrappers.request.Request, which inherits fromwerkzeug.sansio.request.Request.You can see in
wrappers.request.Requestthat:url_rootproperty simply returnsself.root_url. (src)__init__method passes the value ofenviron["wsgi.url_scheme"]as the scheme arg to the parent class. (src)You can see that in
sansio.request.Request, theroot_urlproperty returns the value ofself.scheme, which is set in the__init__method. (src)That's the full chain of causality, more or less.