How to handle 400 errors in Nginx when redirecting HTTP to HTTPS
I have a website like example.com over HTTP. Considering the secure stuff, I now want to change HTTP to HTTPS. And I hope that all old clients will still be able to visit my site, even if they are using example.com, which will be redirected to https via Nginx.
Of course I googled a lot, then my solution is:
upstream www {
server 127.0.0.1:4000;
}
server {
listen 80;
listen 443 ssl;
server_name localhost www example.com;
ssl on;
ssl_certificate /usr/local/etc/docs/example.crt;
ssl_certificate_key /usr/local/etc/docs/example.key;
if ($ssl_protocol = "") {
rewrite ^ https://$host$request_uri? permanent;
}
# below are some other stuff
# ...
}
But when I visit example.com I got:
400 Bad Request A simple HTTP request was sent on the HTTPS port
Then I change nginx.conf after reading Redirect to nginx and set the error_page to 497:
upstream www {
server 127.0.0.1:4000;
}
server {
listen 80;
listen 443 ssl;
server_name localhost www example.com;
ssl on;
ssl_certificate /usr/local/etc/docs/example.crt;
ssl_certificate_key /usr/local/etc/docs/example.key;
error_page 497 https://$host$request_uri;
# below are some other stuff
# ...
}
Then it works, it's okay. But I just don't know why, and the error_page solution just seems insane. So after reading Working with nginx 400 "Simple HTTP request was sent to HTTPS port" error , I add the default and remove the ssl.
upstream www {
server 127.0.0.1:4000;
}
server {
listen 80;
listen 443 default ssl;
server_name localhost www example.com;
ssl on;
ssl_certificate /usr/local/etc/docs/example.crt;
ssl_certificate_key /usr/local/etc/docs/example.key;
if ($ssl_protocol = "") {
rewrite ^ https://$host$request_uri? permanent;
}
# below are some other stuff
# ...
}
Fine! It works again. But I'm not sure:
- Which solution is correct?
- If both are correct, which is more SEO friendly?
source to share
1st solution is indeed connected, from http://moz.com/learn/seo/redirection , might find persistent redirection to be more friendly.
server {
listen 80;
server_name www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 default ssl;
server_name www example.com;
ssl on;
ssl_certificate /usr/local/etc/docs/example.crt;
ssl_certificate_key /usr/local/etc/docs/example.key;
# below are some other stuff
# ...
}
source to share