Esta é a maneira correta e mais eficiente se você quiser manter tudo em um bloco de servidor:
server {
listen 80;
listen [::]:80;
listen 443 default_server ssl;
server_name www.example.com;
ssl_certificate /path/to/my/cert;
ssl_certificate_key /path/to/my/key;
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
}
Tudo o mais acima, usando "reescrever" ou "se ssl_protocol", etc. é mais lento e pior.
Aqui está o mesmo, mas ainda mais eficiente, apenas executando a reescrita no protocolo http, evita ter que verificar a variável $ scheme em cada requisição. Mas, falando sério, é uma coisa tão pequena que você não precisa separá-los.
server {
listen 80;
listen [::]:80;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 default_server ssl;
server_name www.example.com;
ssl_certificate /path/to/my/cert;
ssl_certificate_key /path/to/my/key;
}