Почему Apache Permanent Redirect удаляет косую черту между доменом и контуром?

Я использую Apache 2.4, и я создал два виртуальных каталога. Один требует SSL, а другой перенаправляет его.

Если пользователь пытается посетить https://www.derp.com/derp без /derp existing, они правильно получают 404. Но когда пользователь посещает http://www.derp.com/derp, Apache неправильно перенаправляет пользователя на https://www.derp.comderp, удаляя косую черту между контуром и доменное имя.

Я не знаю, что бы это вызвало.

Ниже приведена настройка моего виртуального хоста.

<VirtualHost *:443>
    ServerAdmin [email protected]
    ServerName www.derp.com
    ServerAlias derp.com
    DocumentRoot "C:\Users\derp\Documents\Web Projects\derp"
    SSLEngine on
    SSLCertificateFile "C:\Apache24\certs\cert.cer"
    SSLCertificateKeyFile "C:\Apache24\certs\key.key"
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName www.derp.com
    ServerAlias derp.com
    Redirect permanent / https://www.derp.com/
</VirtualHost>

<Directory "C:\Users\derp\Documents\Web Projects\derp">
    Options Indexes FollowSymLinks Includes ExecCGI
    AllowOverride All
    Require all granted
    SSLRequireSSL
</Directory>

Почему Apache будет вести себя таким образом?

Бонусный вопрос: нужно ли переадресацию обрабатывать в моем определении виртуального хоста, или нужно ли его обрабатывать в файле .htaccess в физическом каталоге веб-сайта?


Edit:

Я начинаю проект Laravel, и по умолчанию общая папка содержит файл .htaccess, поэтому вот этот парень:

<IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

Изменить два:

Я пробовал:

  • добавление косой черты в конце пути DirectoryRoot
  • замена обратных косых черт косой чертой в пути DirectoryRoot
  • заменить обратную косую черту двойными обратными косыми чертами в пути DirectoryRoot.

Я также полностью удалил файл .htaccess из каталога.

Он перенаправляет правильно, когда вы переходите от http://www.derp.com до https://www.derp.com. Это просто, когда вы укажете путь и попробуйте https, чтобы он удалял косую черту между доменом и контуром.


Изменить три:

Я также попытался сделать следующее предложение:

Redirect permanent / https://www.derp.com/

Try

RedirectMatch permanent /(.*) https://www.derp.com/$1

or

RedirectMatch permanent (.*) https://www.derp.com/$1

... и вместо перенаправления на https://www.derp.comderp он вместо этого не перенаправляет, пытается и дает 404 для http://www.derp.com/derp, но используя Apache 404 вместо того, чтобы выбрасывать исключение Not Found, поскольку Laravel не имеет конфигурации.


Изменить четыре:

Я также пробовал:

<IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

В файле .htaccess и поведение не изменилось вообще.

Ответ 1

Я понял.

Проблема не связана с переписыванием вообще, это была директива SSLRequireSSL в соответствии с моим определением Directory, которое вызывало проблему.

Я просто удалил эту директиву, обновил кеш во всех моих браузерах, и сайт продолжал работать правильно. Это было обнаружено в процессе устранения.

Примечания к документации:

Эта директива запрещает доступ, если только HTTP через SSL (т.е. HTTPS) включен для текущего соединения. Это очень удобно внутри виртуального хоста или каталогов с поддержкой SSL для защиты от ошибок конфигурации, которые выставляют материал, который должен быть защищен. Когда эта директива присутствует, все запросы отклоняются, которые не используют SSL.

Акцент мой. SSLRequireSSL может иметь Apache только возвращать 403 или 404, если HTTP over SSL не включен, что мешает правилу перезаписи. Правило перезаписи, например, в этом ответе на Ошибка сервера, может быть лучшей альтернативой в зависимости от вашего варианта использования:

RewriteEngine On
RewriteCond %{SERVER_PORT} !443
RewriteRule ^(/(.*))?$ https://%{HTTP_HOST}/$1 [R=301,L]

Ответ 2

Моя проблема была связана с кэшированием браузера.

Я попробовал это в другом браузере, и это работало, и затем попыталось снова в частной сессии в первом браузере, и это также работало.