2014-10-26 4 views
1

Я пытаюсь изменить заголовок Host перед отправкой запроса на веб-сайт. Я делаю это, используя этот код:Indy HTTP: не удается изменить заголовок узла

IdHTTP1.Request.HOST := 'example.com'; 
memo1.Text := IdHTTP1.Get('http://stackoverflow.com'); 
showmessage(IdHTTP1.Request.Host); // Expected to be example.com but it's stackoverflow.com 

У меня здесь большая проблема. Несмотря на то, что я меняю заголовок Host, прежде чем получать URL-адрес, заголовок Host изменится на stackoverflow.com. Что я делаю не так? Я хочу изменить заголовок запроса на example.com.

Благодаря

+0

Это поле заполняется методом 'TIdCustomHTTP.PrepareRequest'. Во всяком случае, почему вы хотите идти против стандарта RFC 2616, говорящего о поле хоста * «Поле заголовка запроса хоста указывает номер хоста и номера интернет-ресурса запрашиваемого ресурса, полученные из исходного URI, предоставленного пользователем, или ссылки ресурс "* (это именно то, что делает Indy при подготовке запроса)? – TLama

+0

@TLama Итак, есть anyways, чтобы остановить 'TIdCustomHTTP.PrepareRequest' от изменения поля' Host'? Я хочу получить доступ к общему IP-адресу. Поэтому мне нужно указать 'Host'. Мне нужен пользовательский хост, потому что хост не зарегистрирован. – Sky

+0

Если хост не зарегистрирован DNS, вы можете напрямую использовать IP-адрес: 'http: // w.x.y.z /' ... – mjn

ответ

4

К сожалению, нет никакой возможности, чтобы указать пользовательский Host заголовок, который указывает другое имя хоста, чем указано в URL. URL имеет приоритет. Любое имя хоста, указанное вами в Request.Host, или даже Request.CustomHeaders, перезаписывается именем хоста в URL-адресе.

Если имя хоста в URL не зарегистрирован DNS, вы не сможете достичь его с любой веб-браузер, или большинство библиотек HTTP, включая TIdHTTP. Хотя сам протокол HTTP определяет, как работает заголовок Host, в настоящее время технология веб-браузера использует имя хоста из URL-адреса, а также TIdHTTP. Поэтому нет смысла иметь веб-сайт, который использует имя хоста, которое не было зарегистрировано в DNS, в первую очередь, поскольку большинство современных клиентских систем не смогут его восстановить. DNS требуется для преобразования имени хоста URL-адреса в IP-адрес, а затем одно и то же имя хоста помещается в заголовок Host.

0

Как сказал Реми Лебо, кажется, что нет способа указать пользовательский заголовок Host. Поэтому я решил немного изменить коды IdHTTP.

Сначала я скопировал IdHTTP.pas (C:\Program Files (x86)\Embarcadero\Studio\XX.0\source\Indy10\Protocols\IdHTTP.pas) в мой каталог проектов и добавил его в свой проект. Тогда в TIdCustomHTTP.PrepareRequest методе (линия 1792) Я изменил код так:

if (TextIsSame(FURI.Protocol, 'http') and (FURI.Port = IntToStr(IdPORT_HTTP))) or {do not localize} 
     (TextIsSame(FURI.Protocol, 'https') and (FURI.Port = IntToStr(IdPORT_https))) then {do not localize} 
    begin 
     if FURI.Host = 'stackoverflow.com' then 
     ARequest.Host := 'example.com' 
     else 
     ARequest.Host := FURI.Host; 
    end else begin 
     if FURI.Host = 'stackoverflow.com' then 
     ARequest.Host := 'example.com' + ':' + FURI.Port {do not localize} 
     else 
     ARequest.Host := FURI.Host + ':' + FURI.Port; {do not localize} 
    end; 

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

Так что, если я меняю примеры выше, stackoverflow.com к myblog.wordpress.com и example.com к anotherblog.wordpress.com, К IdHTTP1.Get('http://myblog.wordpress.com') мы получим anotherblog.wordpress.com содержание.

+0

Вы можете запустить какое-то событие «OnRequestPrepared», передав подготовленный объект «ARequest», например. прямо перед выводом 'TIdCustomHTTP.PrepareRequest'. В своем приложении вы затем напишите обработчик для такого события и дополнительно измените объект запроса. Я имею в виду [что-то вроде этого] (http://pastebin.com/US4ZuNdB). – TLama

 Смежные вопросы

  • Нет связанных вопросов^_^