I have a Flask-Restful application running on nginx with uwsgi. Some of its endpoints are supposed to return an 202 Accepted
response with Location:
header.
I didn't specify any protocol or hostname when I put the Location:
header from my python code.
class MyEndpoint(MethodView):
def get(self):
...
return {"status": "Accepted"}, 202, {"Location": "/api/another/endpoint"}
However, when I actually try a request, it somehow puts protocol and hostname to the location header.
$ curl -I "https://api.myhost.com/api/myendpoint"
HTTP/1.1 202 ACCEPTED
Server: nginx/1.1.19
Date: Thu, 30 Jun 2016 03:18:53 GMT
Content-Type: application/json
Content-Length: 23
Connection: keep-alive
Location: http://api.myhost.com/api/another/endpoint
This is a problem because even though I have requested the first endpoint over HTTPS, but the Location:
header comes with HTTP. When I try another request to the /api/another/endpoint
, the browser refused to do it saying that it's an insecure XMLHttpRequest.
I don't think it's done by Flask, since I didn't put api.myhost.com
in nowhere of my application settings. I suspect it's nginx's work, but I don't know how to fix it.
This is my nginx configuration.
server {
listen 80;
listen 443 ssl;
server_name api.myhost.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
location / { try_files $uri @my_api; }
location @my_api {
include uwsgi_params;
uwsgi_pass unix:/var/run/uwsgi/my-api.sock;
}
}
All I want is for the Location:
header value to echo the request's protocol and hostname, or to strip off the host part and leave the path part only.