com o nginx tendo o URL base reescrito para https

com o nginx tendo o URL base reescrito para https

Gostaria que apenas meu domínio base www.domain.com fosse reescrito parahttps://www.domínio.com Por padrão, em meu bloco https, ele é redirecionado para http:// se não for ~uri = "/" (domínio base) ou conteúdo estático.

server {
  listen              443;
  set $ssltoggle 2;
  if ($uri ~ ^/(img|js|css|static)/) {
      set $ssltoggle 1;
  }
  if ($uri = '/') {
      set $ssltoggle 1;
  }
  if ($ssltoggle != 1) {
      rewrite ^(.*)$ http://$server_name$1 permanent;
  }
}

Então, no meu bloco http, preciso reescrever se for https:

server {
  listen              80;
  if ($uri = '/') {
      set $ssltoggle 1;
  }
  if ($ssltoggle = 1) {
      rewrite ^(.*)$ https://$server_name$1 permanent;
  }
}

Se eu não tiver a instrução if $uri = '/' no bloco http, então https funcionará bem se eu for diretamente para ele, mas não serei redirecionado se for para o http normal, o que é esperado. Se eu colocar essa instrução no bloco http, tudo parará de funcionar em minutos. Pode funcionar para algumas solicitações, mas sempre parará em cerca de um minuto. Nos navegadores, recebo apenas uma página em branco para todas as solicitações. Se eu reiniciar o nginx, ele continuará a não funcionar até que eu remova os dois blocos de instrução if nos blocos https e http e reinicie o nginx. Quando olho nos logs de erros, não vejo nada registrado. Quando olho no log de acesso, vejo esta mensagem:

"-" 400 0 "-" "-"

o que presumo significa um erro 400. Não entendo por que isso não funciona para mim. Meu objetivo final é fazer com que o domínio base seja somente https, enquanto todas as outras páginas são http como padrão. Como posso conseguir isso?

Responder1

Acabei mudando $uri para $request_uri para que os argumentos possam ser manipulados sem loops de redirecionamento.

server {
  listen              443;
  set $ssltoggle 2;
  if ($uri ~ ^/(img|js|css|static)/) {
      set $ssltoggle 1;
  }
  if ($request_uri = '/') {
      set $ssltoggle 1;
  }
  if ($ssltoggle != 1) {
      rewrite ^(.*)$ http://$server_name$1 permanent;
  }
}

Então mudei o bloco http para fazer uma reescrita imediata se o local fosse =/

server {
  listen              80;
  location = / {
      rewrite ^(.*)$ https://$server_name$1 permanent;
  }
  if ($ssltoggle = 1) {
      rewrite ^(.*)$ https://$server_name$1 permanent;
  }
}

Eu ainda tenho as instruções IF para lidar com outras reescritas e então toda a veiculação específica é feita abaixo delas. Provavelmente é apenas minha configuração específica que resulta em loops de redirecionamento e erros quando tento lidar com tudo como Christopher sugeriu ou como apresentei originalmente em minha pergunta.

Responder2

Você não precisa de todas as instruções if. Você deve trabalhar com declarações de localização.

server {
    listen              80;
    #rewrite base (/) to ssl
    location = / {
        rewrite ^(.*)$ https://$server_name$1 permanent;
    }

    #serve anything else
    location / {
        [serve non-ssl page ...]
    }
}

server {
    listen              443;

    #serve base url
    location = / {
        [serve ssl page ...]
    }

    #serve assets
    location ~ ^/(img|js|css|static)/ {
        [serve ssl assets ...]
    }

    #rewrite anything else
    location / {
        rewrite ^(.*)$ https://$server_name$1 permanent;
    }
}

Isso não foi testado e pode conter erros, mas deve funcionar

informação relacionada