title: How to handle 400 error in Nginx when redirect HTTP to HTTPS
body: <p>I own a website, like example.com by HTTP. Considering the secure stuff, now I want to change the HTTP to HTTPS. And I hope all the old customers could still be able to visit my website even they use example.com which will be redirect to https via Nginx.</p>
  
  <p>Of course, I googled a lot, then my solution is:</p>
  
  <pre><code>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
    # ...
  }
  </code></pre>
  
  <p>But when I visit example.com, I got:</p>
  
  <blockquote>
    <p>400 Bad Request The plain HTTP request was sent to HTTPS port</p>
  </blockquote>
  
  <p>Then I change the nginx.conf, after reading <a href="https://serverfault.com/questions/338700/redirect-http-mydomain-com12345-to-https-mydomain-com12345-in-nginx">Redirect in nginx</a> , and config the error_page by 497:</p>
  
  <pre><code>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
    # ...
  }
  </code></pre>
  
  <p>Then it works, everything is fine. But I just don't know why and the solution of error_page just seems werid. So 
  after reading <a href="https://stackoverflow.com/questions/8768946/dealing-with-nginx-400-the-plain-http-request-was-sent-to-https-port-error">Dealing with nginx 400 “The plain HTTP request was sent to HTTPS port” error</a>, I add the default and remove the ssl on.</p>
  
  <pre><code>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
    # ...
  }
  </code></pre>
  
  <p>Great! It works again. But I am not for sure:</p>
  
  <ul>
  <li><strong>Which solution is correct?</strong></li>
  <li><strong>If both correct, which is more friendly for SEO?</strong></li>
  </ul>