Django、Nginx、HTTPs 和 HttpResponseRedirect
Django, Nginx, HTTPs and HttpResponseRedirect
我在尝试 return 来自 Django 的 HttpResponseRedirect 时收到来自 Nginx 的 404 错误。这一切都在 HTTPs 下发生 流程是这样的:
- 用户转到页面
- 在表格中输入一些信息
- 视图在 POST 之后处理表单,然后尝试将用户重定向到不同的页面。
除此之外,Nginx 并没有重定向到该页面,而是最终服务于它的 404 页面。
我可以让它在开发中工作,而不是在 Nginx 和 HTTPs 下,所以我怀疑这与我的 Nginx 设置有关。我已经在其他服务器上成功运行了,所以我不确定为什么我不能在这里运行
示例 Django 视图:
@login_required()
def index(request):
if request.method == 'POST':
form = ShortenerForm(request.POST)
if form.is_valid():
# Do stuff
return HttpResponseRedirect(reverse('shortener_thankyou'))
else:
form = ShortenerForm()
return render(request, 'shortener/index.html', {'form': form})
Nginx
upstream apollo2_app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a
# single worker for timing out).
server unix:/webapps/apollo2/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name apollo.mydomain.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl/bundle.crt;
ssl_certificate_key /etc/nginx/ssl/mydomain.com.key;
server_name apollo.mydomain.com;
client_max_body_size 4G;
keepalive_timeout 70;
access_log /webapps/apollo2/logs/nginx-access.log;
error_log /webapps/apollo2/logs/nginx-error.log;
location /static/ {
alias /webapps/apollo2/static/;
}
location /media/ {
alias /webapps/apollo2/media/;
}
location / {
# an HTTP header important enough to have its own Wikipedia entry:
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if and only if you use HTTPS, this helps Rack
# set the proper protocol for doing redirects:
# proxy_set_header X-Forwarded-Proto https;
# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
# set "proxy_buffering off" *only* for Rainbows! when doing
# Comet/long-poll stuff. It's also safe to set if you're
# using only serving fast clients with Unicorn + nginx.
# Otherwise you _want_ nginx to buffer responses to slow
# clients, really.
# proxy_buffering off;
# Try to serve static files from nginx, no point in making an
# *application* server like Unicorn/Rainbows! serve static files.
if (!-f $request_filename) {
proxy_pass http://apollo2_app_server;
break;
}
}
# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /webapps/apollo2/static/;
}
}
Nginx 错误
2015/04/24 11:04:10 [error] 18139#0: *3395 upstream prematurely closed connection while reading response header from upstream, client: 192.168.0.119, server: apollo.mydomain.com, request: "POST /shortener/ HTTP/1.1", upstream: "http://unix:/webapps/apollo2/run/gunicorn.sock:/shortener/",
我尝试了很多不同的解决方案,涉及 proxy_set_header X-Forwarded-Protocol $scheme;在 Nginx 和 Djangos SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https') 但没有运气。
原来这与Nginx、SSL或Django无关。 IT 在没有通知我的情况下更改了我们的一台 DNS 服务器。响应超时,因为它无法解析 DNS。在 /etc/resolv.conf 中更新到新的 DNS 服务器解决了这个问题。
我在尝试 return 来自 Django 的 HttpResponseRedirect 时收到来自 Nginx 的 404 错误。这一切都在 HTTPs 下发生 流程是这样的:
- 用户转到页面
- 在表格中输入一些信息
- 视图在 POST 之后处理表单,然后尝试将用户重定向到不同的页面。
除此之外,Nginx 并没有重定向到该页面,而是最终服务于它的 404 页面。
我可以让它在开发中工作,而不是在 Nginx 和 HTTPs 下,所以我怀疑这与我的 Nginx 设置有关。我已经在其他服务器上成功运行了,所以我不确定为什么我不能在这里运行
示例 Django 视图:
@login_required()
def index(request):
if request.method == 'POST':
form = ShortenerForm(request.POST)
if form.is_valid():
# Do stuff
return HttpResponseRedirect(reverse('shortener_thankyou'))
else:
form = ShortenerForm()
return render(request, 'shortener/index.html', {'form': form})
Nginx
upstream apollo2_app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a
# single worker for timing out).
server unix:/webapps/apollo2/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name apollo.mydomain.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl/bundle.crt;
ssl_certificate_key /etc/nginx/ssl/mydomain.com.key;
server_name apollo.mydomain.com;
client_max_body_size 4G;
keepalive_timeout 70;
access_log /webapps/apollo2/logs/nginx-access.log;
error_log /webapps/apollo2/logs/nginx-error.log;
location /static/ {
alias /webapps/apollo2/static/;
}
location /media/ {
alias /webapps/apollo2/media/;
}
location / {
# an HTTP header important enough to have its own Wikipedia entry:
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if and only if you use HTTPS, this helps Rack
# set the proper protocol for doing redirects:
# proxy_set_header X-Forwarded-Proto https;
# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
# set "proxy_buffering off" *only* for Rainbows! when doing
# Comet/long-poll stuff. It's also safe to set if you're
# using only serving fast clients with Unicorn + nginx.
# Otherwise you _want_ nginx to buffer responses to slow
# clients, really.
# proxy_buffering off;
# Try to serve static files from nginx, no point in making an
# *application* server like Unicorn/Rainbows! serve static files.
if (!-f $request_filename) {
proxy_pass http://apollo2_app_server;
break;
}
}
# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /webapps/apollo2/static/;
}
}
Nginx 错误
2015/04/24 11:04:10 [error] 18139#0: *3395 upstream prematurely closed connection while reading response header from upstream, client: 192.168.0.119, server: apollo.mydomain.com, request: "POST /shortener/ HTTP/1.1", upstream: "http://unix:/webapps/apollo2/run/gunicorn.sock:/shortener/",
我尝试了很多不同的解决方案,涉及 proxy_set_header X-Forwarded-Protocol $scheme;在 Nginx 和 Djangos SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https') 但没有运气。
原来这与Nginx、SSL或Django无关。 IT 在没有通知我的情况下更改了我们的一台 DNS 服务器。响应超时,因为它无法解析 DNS。在 /etc/resolv.conf 中更新到新的 DNS 服务器解决了这个问题。