Сайт Романа ПарпалакаБлог20240617

Можно ли надежно определить, по какому адресу открыли сайт?

17 июня 2024 года, 22:37

Я уже писал о том, что в PHP нет надежного способа определить текущий домен. Сейчас столкнулся с похожей трудностью с определением порта. Ко мне обратились за помощью с ошибкой в форуме PunBB при входе пользователей.

Напомню, что на своей первой работе в 2008 году я входил в команду разработки этого форума. С тех времен он не сильно развивался, и информацию обо мне до сих пор не удалили со страницы в вики. Видимо, оттуда на меня и вышли.

Проблема у собеседника проявлялась в том, что после отправки формы с логином и паролем редирект происходил на адрес типа https://example.com:80/some_forum_url. Ответ не приходил, потому что на порту 80 никто не обрабатывал https-запросы, так как веб-сервер ожидал их на стандартном порту 443.

PunBB устроен так, что в момент установки URL форума записывается в специальную переменную в файле настройки. Сама эта переменная была установлена правильно, порта в ней не было: https://example.com/. Но именно после входа неверный порт откуда-то появлялся.

Я поискал по коду форума «80» и нашел такую строчку:

$port = (isset($_SERVER['SERVER_PORT'])
   && (
      ($_SERVER['SERVER_PORT'] != '80' && $protocol == 'http://')
      || ($_SERVER['SERVER_PORT'] != '443' && $protocol == 'https://')
   ) && strpos($_SERVER['HTTP_HOST'], ':') === false)
   ? ':'.$_SERVER['SERVER_PORT']
   : '';

Здесь код пытается понять по значению серверной переменной $_SERVER['SERVER_PORT'], запущен ли он на нестандартном порту. Я предложил заменить строку на $port = ''. Проблема исчезла.

Оказалось, что на хостинге значение переменной $_SERVER['SERVER_PORT'] было установлено неверно. Оно равнялось 80, хотя сам сайт открывается по стандартному для https порту 443.

Надо сказать, что у меня нет понимания, нужно ли вообще обрабатывать значение $_SERVER['SERVER_PORT']. С одной стороны, если не обработать, то движок получается менее универсальным, он не может определить, что запущен на нестандартном порту. С другой стороны, если обрабатывать, можно столкнуться с некорректной настройкой веб-сервера и ошибками на ровном месте, как в этом случае. Описание похожей проблемы есть на стековерфлоу, так что это не какой-то экзотический случай.

Чтобы не пытаться определять адрес сайта во время выполнения, авторы PunBB сделали это определение только во время установки для формирования «умной догадки», которую можно подправить. Но какой-то разработчик в этом вопросе разобрался не до конца и использовал этот код еще и для определения адреса редиректа, что и повлекло саму ошибку.

Поделиться

Глюки подключения модема и ошибки мышления Ctrl Применение конечных автоматов в программировании

Читайте также


Миниатюры на PHP
В ходе разработки и обслуживания сайтов часто возникает необходимость в создании миниатюр — уменьшенных копий изображений. В тексте страницы вместо большой картинки можно поместить такую копию, являющуюся ссылкой на исходный файл.
2007
Прокси-сервер через ssh
Полезная вещь в современных условиях — прокси-сервер через ssh. Если у вас есть доступ к какому-нибудь серверу по ssh, и вы хотите пропускать через него свой трафик, запустите в консоли команду
2022
Http-прокси на PHP
Обычно в постах о программировании я пишу об успешных подходах и находках. В этот раз расскажу об идее, которая на практике не заработала.
2023
Как определить домен из PHP
Илья Бирман написал про баг в Эгее, когда сайт доступен по разным доменам, и RSS кешируется то с одним доменом, то с другим.
2017

Комментарии

#1. 18 июня 2024 года, 07:56. Евгений Степанищев пишет:
Вероятно впереди какой-то прокси стоит, возможно для более быстрой отдачи статики. Хостеры так часто nginx перед Apache ставят. Прокси с веб-сервером соединяется по HTTP, отсюда и ошибка.
#2. 18 июня 2024 года, 11:15. пишет:
Хорошее предположение. Я думал, что при установке из поля с адресом форума стерли порт, а вместо этого могли поменять протокол с http на https.

Наверно, при установке лучше всего определять текущий адрес из JS, взяв его из window.location.

Оставьте свой комментарий


Формулы на латехе: $$f(x) = x^2-\sqrt{x}$$ превратится в $$f(x) = x^2-\sqrt{x}$$.
Выделение текста: [i]курсивом[/i] или [b]жирным[/b].
Цитату оформляйте так: [q = имя автора]цитата[/q] или [q]еще цитата[/q].
Других команд или HTML-тегов здесь нет.

Записи