В чем разница между HTTP_HOST и SERVER_NAME в PHP?

В моем случае проблема была связана с окончанием строки (вероятно, какой-то редактор изменил мой файл с DOS на Unix).

Я собрал эти аппартивные обертки:

function unserialize_fetchError($original, &$unserialized, &$errorMsg) {
    $unserialized = @unserialize($original);
    $errorMsg = error_get_last()['message'];
    return ( $unserialized !== false || $original == 'b:0;' );  // "$original == serialize(false)" is a good serialization even if deserialization actually returns false
}

function unserialize_checkAllLineEndings($original, &$unserialized, &$errorMsg, &$lineEndings) {
    if ( unserialize_fetchError($original, $unserialized, $errorMsg) ) {
        $lineEndings = 'unchanged';
        return true;
    } elseif ( unserialize_fetchError(str_replace("\n", "\n\r", $original), $unserialized, $errorMsg) ) {
        $lineEndings = '\n to \n\r';
        return true;
    } elseif ( unserialize_fetchError(str_replace("\n\r", "\n", $original), $unserialized, $errorMsg) ) {
        $lineEndings = '\n\r to \n';
        return true;
    } elseif ( unserialize_fetchError(str_replace("\r\n", "\n", $original), $unserialized, $errorMsg) ) {
        $lineEndings = '\r\n to \n';
        return true;
    } //else
    return false;
}
515
задан Matt Komarnicki 21 September 2017 в 08:35
поделиться

4 ответа

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        for (String part : getParts("foobarspam", 3)) {
            System.out.println(part);
        }
    }
    private static List<String> getParts(String string, int partitionSize) {
        List<String> parts = new ArrayList<String>();
        int len = string.length();
        for (int i=0; i<len; i+=partitionSize)
        {
            parts.add(string.substring(i, Math.min(len, i + partitionSize)));
        }
        return parts;
    }
}
-121--902310-

HTTP _ HOST получен из заголовка HTTP просить , и это то, что клиент фактически использовал в качестве «целевого хоста» запроса. Параметр SERVER _ NAME определен в конфигурации сервера. Какой использовать, зависит от того, для чего это нужно. Однако теперь следует понимать, что одно значение является значением, управляемым клиентом, которое, таким образом, может не быть надежным для использования в бизнес-логике, а другое является значением, управляемым сервером, которое является более надежным. Однако необходимо убедиться, что на рассматриваемом веб-сервере правильно настроен SERVER _ NAME . Возьмем в качестве примера Apache HTTPD, вот выписка из его документации :

Если ServerName не указан, то сервер пытается вывести имя хоста, выполнив обратный поиск по IP-адресу. Если в ServerName не указан порт, сервер будет использовать порт из входящего запроса. Для обеспечения оптимальной надежности и предсказуемости необходимо указать явное имя хоста и порт с помощью директивы ServerName .


Обновить : после проверки ответа Pekka на ваш вопрос , который содержит ссылку на ответ bobince , что PHP всегда возвращает значение HTTP _ HOST для SERVER _ NAME , что противоречит моей собственной PHP 4 .x + Apache HTTPD 1,2. (Apache HTTPD 2,2,1 с PHP 5,2,8), запустил его, создал страницу PHP, которая печатает оба значения, создал тестовое приложение Java, используя URLConnection для изменения заголовка Host , и тесты показали мне, что это действительно (неправильно) случай.

После того, как я впервые заподозрил PHP и покопался в некоторых отчетах об ошибках PHP относительно темы, я узнал, что корень проблемы находится в используемом веб-сервере, что он неправильно вернул заголовок HTTP Host , когда был запрошен SERVER _ NAME . Поэтому я покопался в Apache HTTPD bug reports , используя различные ключевые слова относительно темы, и я наконец нашел связанную ошибку . Это поведение было введено, так как около Apache HTTPD 1.3. Необходимо установить для директивы UseCanonicalName значение для в записи < VirtureHost > параметра ServerName в httpd.conf (также проверьте предупреждение в нижней части документа !).

<VirtualHost *>
    ServerName example.com
    UseCanonicalName on
</VirtualHost> 

Это сработало для меня.

Суммировано, что SERVER _ NAME является более надежным, но вы зависите от конфигурации сервера!

766
ответ дан 22 November 2019 в 22:29
поделиться

HTTP_HOST - это целевой хост, отправленный клиентом. Пользователь может свободно манипулировать им. Не проблема послать запрос на ваш сайт, запрашивая HTTP_HOST со значением www.stackoverflow.com.

SERVER_NAME исходит из определения VirtualHost сервера и поэтому считается более надежным. Однако им также можно манипулировать извне при определенных условиях, связанных с тем, как настроен ваш веб-сервер: См. этот вопрос SO , в котором рассматриваются аспекты безопасности обеих вариаций.

Не стоит полагаться на то, что ни один из них не является безопасным. Тем не менее, выбор варианта зависит от того, что вы хотите сделать. Если вы хотите определить, на каком домене запущен ваш скрипт, вы можете смело использовать HTTP_HOST, пока недействительные значения, приходящие от злонамеренного пользователя, не смогут ничего сломать.

65
ответ дан 22 November 2019 в 22:29
поделиться

Зависит от того, что я хочу узнать. SERVER_NAME - имя хоста сервера, а HTTP_HOST - виртуальный хост, к которому подключился клиент.

5
ответ дан 22 November 2019 в 22:29
поделиться

, если вы хотите проверить через server.php или как бы то ни было, вы хотите называть его следующим образом:

<?php

phpinfo(INFO_VARIABLES);

?>

или

<?php

header("Content-type: text/plain");

print_r($_SERVER);

?>

Затем откройте его со всеми действующими URL-адресами вашего сайта и проверьте разницу.

6
ответ дан 22 November 2019 в 22:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: