python-restx / flask-restx

Fork of Flask-RESTPlus: Fully featured framework for fast, easy and documented API development with Flask
https://flask-restx.readthedocs.io/en/latest/
Other
2.16k stars 335 forks source link

Swagger and Apache curl's do not match #548

Open itinneed2022 opened 1 year ago

itinneed2022 commented 1 year ago

I'm running flask restx behind an apache proxy. My team only gets one server for all our tools so it's kind of necessary.

I'm setting my namespace up like so:

namespace = Namespace('hosts', 'host endpoints', validate=True, authorizations=authorizations, path="/hosts")

The two endpoints are for a virtual machine name and a PUT that takes a json at '/'.

But in order to work w/ port 443 and https, I'm having to proxy my requests through apache and gunicorn. Apache config:

<VirtualHost *:443>
  ServerName webdev02.mycompany.com

  ## Vhost docroot
  DocumentRoot "/etc/httpd/htdocs"

  <Directory "/etc/httpd/htdocs">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  ## Logging
  ErrorLog "/var/log/httpd/httpd_error_log"
  ServerSignature Off
  CustomLog "/var/log/httpd/httpd_access_log" "mainserver"

  ## Server aliases
  ServerAlias webdev02.mycompany.com

  ## Custom fragment
  ## Custom fragment
  SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
  CustomLog "/var/log/httpd/httpd_access_log" combined env=!forwarded
  CustomLog "/var/log/httpd/httpd_access_log" proxy env=forwarded
<Location "literally 11 other applications">
  RequestHeader set X-Forwarded-Port 443
  ProxyPass http://127.0.0.1:80##/
</Location>
<Location /my_application>
  ProxyPass http://127.0.0.1:8082/
</Location>
<Location /swaggerui> # this has to be done to find the swaggerui page
  ProxyPass http://127.0.0.1:8082/swaggerui
</Location>
<Location /swagger.json> # because my_application represents the project running on port 8082, I have to redirect here to retrieve the swagger.json file
  ProxyPass http://webdev02.mycompany.com/my_application/swagger.json
</Location>
<Location /hosts/> # this is the start of my problems
  ProxyPass http://webdev02.mycompany.com/my_application/hosts/
</Location>
  SetEnv HTTPS On

</VirtualHost>

A curl requests works like so:

curl -X 'GET' \
  'https://webdev02.mycompany.com/my_application/hosts/myserver.mycompany.com' \
  -H 'accept: application/json'
{"vmname": "myserver.mycompany.com", "OS": "Red Hat Enterprise Linux 8", "PatchWindow": "1_Mon_AM_6"}

the problem: my swagger page does not recognize that it is behind Apache and Gunicorn. When I go to my doc page, select that same endpoint above and hit execute, it outputs the CURL like this:

curl -X 'GET' \
  'https://webdev02.mycompany.com/hosts/myserver.mycompany.com' \
  -H 'accept: application/json'

I've tried ProxyFix from werkzeug.middleware.proxy_fix and that has done nothing. How do I get a flask-restx project to recognize its behind a proxy?

I should mention I've seen a previous post on this but it hasn't resolved my issue.

peter-doggart commented 1 year ago

Can you debug a request on the flask app and grab the X-Forwarded-* headers to see what is being set during the forwarding?

itinneed2022 commented 1 year ago

How would I do that?

pydevmans commented 1 year ago

Hello @itinneed2022, It can be if your Resource class are not configured with decorator api.expect as documented here.