с nginx, имеющим базовый URL-адрес, переписанный на https

с nginx, имеющим базовый URL-адрес, переписанный на https

Я бы хотел, чтобы только мой базовый домен www.domain.com был переписан наhttps://www.domain.com По умолчанию в моем блоке https я перенаправляю его на http://, если это не ~uri = "/" (базовый домен) или статический контент.

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;
  }
}

Поэтому в моем блоке http мне нужно сделать перезапись, если он должен быть на https:

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

Если у меня нет оператора if $uri = '/' в блоке http, то https работает нормально, если я перехожу к нему напрямую, но я не буду перенаправлен, если я перейду к обычному http, что ожидается. Если я помещу этот оператор in в блок http, то все перестанет работать в течение нескольких минут. Это может работать для нескольких запросов, но всегда останавливается в течение минуты или около того. В браузерах я просто получаю пустую страницу для всех запросов. Если я перезапускаю nginx, он продолжает не работать, пока я не удалю оба блока if-statement в блоках https и http и не перезапущу nginx. Когда я просматриваю журналы ошибок, я не вижу ничего записанного. Когда я просматриваю журнал доступа, я вижу это сообщение:

"-" 400 0 "-" "-"

что, как я предполагаю, означает ошибку 400. Я не понимаю, почему это не работает для меня. Моя конечная цель — сделать базовый домен https-only, а все остальные страницы по умолчанию использовать http. Как мне этого добиться?

решение1

В итоге я изменил $uri на $request_uri, чтобы аргументы можно было обрабатывать без циклов перенаправления.

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;
  }
}

Затем я изменил блок http, чтобы выполнить немедленную перезапись, если местоположение было = /

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

У меня есть операторы IF, которые все еще обрабатывают другие перезаписи, а затем все конкретное обслуживание выполняется ниже них. Вероятно, это просто моя конкретная конфигурация, которая приводит к циклам перенаправления и ошибкам, когда я пытаюсь обработать все так, как предложил Кристофер или как я изначально представил в своем вопросе.

решение2

Вам не нужны все эти операторы if. Вам следует работать с операторами location.

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;
    }
}

Это не проверено и может содержать ошибки, но должно работать.

Связанный контент