Подтвердить что ты не робот

Почему Request [ "host" ] == "dev.testhost.com:1234", тогда как Request.Url.Host == "localhost"

Привет всем, я, кажется, обнаружил несоответствие при локальном тестировании приложений ASP.NET на встроенном веб-сервере с Visual Studio 2008 (Cassini).

Я установил хост на локальном компьютере, связывающем dev.testhost.com с 127.0.0.1, так как у меня есть приложение, которое должно изменить его внешний вид в зависимости от заголовка хоста, используемого для его вызова.

Однако, когда я запрашиваю свое тестовое приложение с помощью http://dev.testhost.com:1234/index.aspx, значение Request.Url.Host всегда "localhost". В то время как значение Request.Headers["host"] равно "dev.testhost.com:1234" (как и я ожидал, что оба они будут).

Я НЕ обеспокоен тем, что второе значение включает номер порта,, но я могу смущен тем, что ИМЯ ХОЗЯЙСТВА совершенно разные! Кто-нибудь знает, является ли это известной проблемой или по дизайну? Или я идиот?!

Я бы предпочел использовать Request.Url.Host, так как это позволяет избежать выделения номера порта при тестировании... - Удалено из-за возможной путаницы! - Сэм

4b9b3361

Ответ 1

Request.Headers["host"] - это значение, полученное от приложения, которое подключается к серверу, а другое значение - тот, который получает сервер, когда он пытается получить доменное имя.

Браузер использует в запросе имя домена, введенное, поскольку оно используется в случае виртуальных доменов. Сервер сообщает о том, что задано в настройках сервера, или о первом найденном.

РЕДАКТИРОВАТЬ: Глядя на код Cassini, чтобы узнать, использует ли он какие-то определенные настройки, я заметил следующий код:

public string RootUrl {
  get {
    if (_port != 80) {
      return "http://localhost:" + _port + _virtualPath;
    }
    else {
      return "http://localhost" + _virtualPath;
    }
  }
}

//
// Socket listening
//

public void Start() {
  try {
    _socket = CreateSocketBindAndListen(AddressFamily.InterNetwork, IPAddress.Loopback, _port);
  }
  catch {
    _socket = CreateSocketBindAndListen(AddressFamily.InterNetworkV6, IPAddress.IPv6Loopback, _port);
  }
  // …
}

Объяснение похоже, что Cassini делает явную ссылку на localhost и не пытается сделать обратный поиск DNS. Иными словами, он не будет использовать return "http://localhost" + _virtualPath;.

Ответ 2

Request.Headers["host"] - это хост, указанный в заголовке http из браузера. (например, это то, что вы увидите, если бы вы исследовали трафик с помощью Fiddler или HttpWatch)

Однако ASP.NET обрабатывает эту (и другую информацию запроса) в экземпляр System.Uri, который анализирует строку запроса на ее составные части. В этом случае "Хост" означает буквально часть главной машины исходного запроса (например, с портом tcp, находящимся в порте).

Этот класс System.Uri - очень полезный вспомогательный класс, который отнимает всю боль от разделения вашего запроса на его части, тогда как "Host:" (и, самое главное, "GET" ) из HTTP-заголовка просто необработанные данные запроса.

Хотя оба они имеют одно и то же имя, они не должны быть одинаковыми.

Ответ 3

Это вопрос о том, что спецификации w3 говорят о том, что Microsoft Uri.Host должно содержать. Именование не подразумевает попытки MS предоставить идентичную функциональность. Функция, которая включает номера портов, Uri.Authority.

С обновлением, которое вы опубликовали, вы все еще сталкиваетесь с одной и той же проблемой, просто исследуя другой аспект этого. свойство Uri.Host не является явно выраженной или подразумеваемой для выполнения той же функции, что и заголовки, определенные в спецификациях w3. В длинной форме, вот некоторые цитаты из страницы UDN.Host:

Свойство Uri.Host
Получает компонент хоста этого экземпляра.

Значение свойства

Тип: System.String

Строка, содержащая имя хоста. Обычно это имя хоста DNS или IP-адрес сервера.

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