« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга


ПнВтСрЧтПтСбВс
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
    Популярное
Файлы конфигурации в asp.net

Необычное применение CSS - реализация эффекта rollover

Динамическое формирование объектов

Абстрактная фабрика. Abstract Factory.

Windows CGI интерфейс

Функция AccessResource

Пишем программу для пересылки файлов через сокеты

Анализ посещаемости сайта рефералами

Определение класса атрибута

ГЛАВА 1. Встроенные типы данных, операции над ними




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 94
Пользователей: 0

Статьи:: Delphi :: Интернет и Сети :: Основы HTTP на примере Delphi



отправить ссылку другу версия для печати  Обсудить на форуме

Основы HTTP на примере Delphi



Автор: Lem0nti, специально для http://www.realcoding.net

О, инет… Как много в этом звуке. А прикинь как в нём много того, о чём ты вообще не в курсах? Нет, я совсем не имею ввиду туеву хучу сайтов, на которых ты не был, я имею ввиду то, что скрыто от тебя… То как твой браузер общается с сервером – ПРОТОКОЛ. Конечно же, полное описание протокола со всеми тонкостями не уместить в одну статью, но примерно раскидав по полочкам некоторые его основы в этой статье, я думаю, потом ты сможешь смело продолжать копать в данном направлении и в конце концов сможешь написать даже свой собственный браузер не на основе компонента TWebBrowser. Для этого нам потребуется совсем немного – установленная Дельфи (я юзаю 6-ю) и немного терпения, чтобы дочитать сей материалец. Дабы не утруждаться всякими тонкостями сокетов, будем юзать TidTCPConnection. Итак начнём с самого начала доверительных отношений сервера и клиента – соединение. Для начала нам надо разделить запрашиваемую страницу и домен, на котором эта страница расположена. Нижеследующий код, собственно, это и производит.

  procedure ParseUrl(RequestString: string);
  var
    Addr: string;
  begin

    Addr:= RequestString;
    if pos('http://',Addr)>0 then
      delete(Addr,1,7);
    if pos('/',Addr)>0 then
    begin

      FHost:=copy(Addr,1,pos('/',Addr)-1);
      FPath:=copy(Addr,pos('/',Addr),length(Addr)-pos('/',Addr)+1);
    end
    else
    begin

      FHost:=Addr;
      FPath:='';
    end;
  end
;

        Переменные FHost и FPath объявлены на уровне модуля. Затем я создал у себя такую функцию –

  function Connect(Host: string): boolean;

        Объявляем на уровне функции переменную phe: PHostEnt; - это структура, в которую будет загоняться инфа о сервере, к которому мы захочем приджойниться, а делается это так –

  phe:=gethostbyname(PChar(Host));

        Далее следует проверить эту структуру на целостность, ведь если по каким-то причинам информация о хосте не была получена, то и джойниться к нему мы не можем.

  if assigned(phe) then
  begin
  end
;

        Теперь из этой структуры необходимо вытащить ИП-адрес, потому что соединяться всё-равно надо не по имени сайта, а по его ИП-шнику. Для этого объявим ещё две переменных - pa: PChar; - в эту переменную мы вытащим ИП-шник в закодированном виде и соответственно будем его декодировать; FIP: string; - в этой переменной мы будем хранить ИП-адрес. Итого код, который мы вставляем в блок if –

  pa:=phe^.h_addr_list^;
  FIP:=inttostr(ord(pa[0]))+'.'+inttostr(ord(pa[1]))+'.'+inttostr(ord(pa[2]))+'.'+inttostr(ord(pa[3]));

        Главное – не забыть объявить на уровне модуля переменную типа TIdTCPConnection, я у себя назвал её Connection. Также добавим в конце файла ещё такой код перед финальным end’ом –

  initialization
    Connection:=TIdTCPConnection.Create(nil);

  finalization
    FreeAndNil(Connection);

        Теперь подготовительный этап закончен, переходим непосредственно к соединению, для чего допишем такой код в нашу функцию -

  with Connection do
  begin

    //соединяемся
    if not Binding.HandleAllocated then
    begin

      Binding.AllocateSocket;
      Binding.SetPeer(FIP,80);
      CRes:=Binding.Connect;
      if CRes=-1 then //ошибка соединения
        exit;
      result:=true;
    end;
  end
;

        Не стоит забывать, что этот код также должен быть внутри блока if . Тут кстати требуется ещё кой-чего в этой функции – дело в том, что после закрытия соединения, его надо ещё и сбросить, для чего надо выполнить метод ResetConnection у нашего соединения, но загвоздочка в том, что этот метод объявлен как protected. Поэтому нам необходимо написать ещё такую штуку в секцию interface –

  type
    TKRTCPConnection = class(TIdTCPConnection);

        И теперь, в нашей функции перед строкой if not Binding.HandleAllocated then добавляем такой код –

  if ClosedGracefully then
    TKRTCPConnection(Connection).ResetConnection;

        Итого, код функции, которая будет осуществлять соединение, таков –

  function Connect(Host: string): boolean;
  var
    phe: PHostEnt;
    pa: PChar;
    FIP: string;
    CRes: integer;
  begin
    result:=false;
    //получаем ИП-шник
    phe:=gethostbyname(PChar(AHost));
    if assigned(phe) then
    begin

      pa:=phe^.h_addr_list^;
      FIP:=inttostr(ord(pa[0]))+'.'+inttostr(ord(pa[1]))+'.'+inttostr(ord(pa[2]))+'.'+inttostr(ord(pa[3]));
      with Connection do
      begin
        if
ClosedGracefully then
          TKRTCPConnection(Connection).ResetConnection;
        //соединяемся
        if not Binding.HandleAllocated then
        begin

          Binding.AllocateSocket;
          Binding.SetPeer(FIP,APort);
          CRes:=Binding.Connect;
          if CRes=-1 then
          exit;
          result:=true;
        end;
      end;
    end;
  end
;

        Замечательно – коннект есть, но пока что ещё нет страницы. Что-ж пойдём попросим у сервера нужную нам страницу. Для этих целей, я сделал ещё одну функцию –

  function GetHttpOkStatus(RequestString: string): boolean;

        В этой функции сервер должен дать мне разрешение на определённую нужную мне страницу. На уровне функции я объявил переменную RespText: string; в эту переменную я собираюсь сохранять пересылаемые сигналы серверу и ответы от него. Вот тут-то и начинается собственно самое интересное. Начнём чатиться... Ничего смешного в этом нет, мы будем именно чатиться с сервером. Для нас он будет как бы чат-бот. Это конечно смотря с какой стороны посмотреть, но я воспринимаю данный процесс именно так. Итак – просим у сервера нужную нам страницу –

  with Connection do
  begin

    RespText:='GET '+RequestString+' HTTP/1.1'+#13#10;
    WriteBuffer(RespText[1],length(RespText));
  end;

        Тут пара маленьких ремарок. Во-первых, весь последующий код относящийся к этой функции я подразумеваю размещённым внутри блока with. А во-вторых, отвечаю на вполне логично возникший вопрос – «А чего-й то за фигня, почему RespText[1], а не RespText?». Всё очень просто – дело в том что надо передать как бы PChar, а у меня string, а у string первый байт является идентификатором её длины, поэтому я даю указатель на первый байт полезной информации, думаю тут вполне возможны какие-либо дополнительные вопросы, но о них в другой раз. Итак, возвращаясь к теме – страницу мы попросили, но теперь мы должны указать домен под которым находится данная страница, потому что, как известно (надеюсь всем читающим), на одном компьютере легко размещаются сотни сайтов, так что шлём ещё такую строку –

  RespText:='Host: '+ FHost +#13#10;
  WriteBuffer(RespText[1],length(RespText));

        С тем что нам надо определились, теперь надо серваку указать то КАК мы это хотим получить, для чего и придумана система заголовков. Сейчас настало их время. В идеале, заголовков очень много и отвечают они за разные параметры, ниже приведён далеко не полный список заголовков –

  • Accept:
  • Accept-Charset:
  • Accept-Encoding:
  • Accept-Language:
  • From:
  • Referer:
  • User-Agent:
  • Connection:
  • Content-Version:
  • Content-Encoding:
  • Content-Language:
  • Content-Type:
  • Content-Length:
  • Range: bytes=
  • Authorization: Basic
  • Proxy-Authorization: Basic

            Смысл заголовков, как я и указал выше, состоит в том, чтобы дать понять серверу в каком виде мы перед ним предстаём для конкретной вызываемой нами страницы и в каком виде она должна быть для нас. В самом простом варианте можно обойтись и без них, но в-принципе без них никак. В конкретном нашем случае, предлагаю использовать только заголовок, который обозначает агента, который используется–

      RespText:=' User-Agent: Samy Krutoy Browser‘+#13#10;
      WriteBuffer(RespText[1],length(RespText));

            Более подробно познакомиться с заголовками можно из соответствующих RFC (1945, 2068). Ну а теперь нам осталось просигналить что мы закончили и ждём теперь соответствующих результатов –

      RespText:= #13#10;
      WriteBuffer(RespText[1],length(RespText));
      RespText := ReadLn;
      result:=pos('200',RespText)>0;

            Ключевой момент у нас заключается в последней строке. Дело в том, что всё в порядке у нас при ответе - HTTP/1.1 200 OK или HTTP/1.0 200 OK, ну и понятно почему я ищу собственно цифру 200 – это код состояния дальнейшего общения между клиентом и сервером. Первая цифра кода состояния определяет класс ответа. Последние две цифры не имеют определенной роли в классификации. Имеется 5 значений первой цифры:
  • 1xx: Информационные коды - запрос получен, продолжается обработка
  • 2xx: Успешные коды - действие было успешно получено, понято и обработано
  • 3xx: Коды перенаправления - для выполнения запроса должны быть предприняты дальнейшие действия
  • 4xx: Коды ошибок клиента - запрос имеет плохой синтаксис или не может быть выполнен
  • 5xx: Коды ошибок сервера - сервер не в состоянии выполнить допустимый запрос.

            Полный список состояний приводить здесь не имеет смысла, все они описаны в RFC 2068. В итоге, функция GetHttpOkStatus выглядит у нас так –

      function GetHttpOkStatus(RequestString: string): boolean;
      var
        RespText: string;
      begin
        with
    Connection do
        begin

          RespText:='GET '+RequestString+' HTTP/1.1'+#13#10;
          WriteBuffer(RespText[1],length(RespText));
          RespText:='Host: '+ FHost +#13#10;
          WriteBuffer(RespText[1],length(RespText));
          RespText:='User-Agent: Samy Krutoy Browser '+#13#10;
          WriteBuffer(RespText[1],length(RespText));
          RespText:=#13#10;
          WriteBuffer(RespText[1],length(RespText));
          RespText := ReadLn;
          result:=pos('200',RespText)>0;
        end;
      end;


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

      function GetFromInet(const fileURL, FileName: string): boolean;
      var
        RespText: String;
        memst: TStringStream;
        SL: TStringList;
      begin
        result:=false;
        if Connection.Connected then
          Connection.Disconnect;
        ParseUrl(fileURL);
        if Connect(FHost) then
          try
            if
    GetHttpOkStatus(FPath) then
              with
    Connection do
              begin

                memst:=TStringStream.Create('');
                try
                  SL:=TStringList.Create;
                  try
                    ReadStream(memst,-1,true);
                    memst.Position:=0;
                    SL.Add(memst.DataString);
                    SL.SaveToFile(FileName);
                    result:=true;
                  finally
                    FreeAndNil(SL);
                  end;
                finally

                  FreeAndNil(memst);
                end;
              end;
          finally
            if
    Connection.Connected then
              Connection.Disconnect;
          end;
      end
    ;

            Стоит дополнительно отметить, что данная функция далека от совершенства, ведь есть ещё такие вещи как прокси, авторизация, в конце-концов, обработка и отсечение полученных заголовков, но я смело делаю вывод что направление как таковое указано, а разобраться дальше что делать в тех или иных случаях несложно. Для чего и существует RFC, Delphi help, а также сорцы компонентов. В-общем чувствую что моя совесть чиста и предлагаю вам самим развиваться дальше в данном направлении.







  • HTML 5: пять вещей вызывающих особый интер....

    Html

    HTML 5 — это грядущее обновление гипертекстового языка разметки, основного способа создания контента для размещения его во всемирной паутине. Разработка HTML остановилась в 1999 году, на версии HTML 4.01 и с тех пор web-содержимое изменилось так, что текущие спецификации HTML перестали соответствовать сегодняшним требованиям. HTML 5 нацелен на то, чтобы увеличить функциональную совместимость HTML и соответствовать растущим требованиям разнообразного и смешанного web-контента. HTML 5 так же нацелен на устранение недостатков четвертой версии. В этой статье мы взглянем на 5 новых интересных вещей в HTML 5.


    Подробнее... | Рубрика: Html | Добавлено: 22.12.2008

    asp.net: ListView с разных сторон.

    .NET компоненты

    Элемент управления ListView был представлен в .Net Framework 3.5 как замена устаревшему GridView. Новый элемент имеет более расширенный функционал, чем его предшественник, но в тоже время лишен некоторых внутренних механизмов, что впрочем целиком следствие из расширенной универсальности ListView. Среди отличий ListView и GridView можно назвать и гибкую настройку разметки, что позволяет выводить данные не только в табличном виде, но и вообще в любом каком пожелает программист. Благодаря шаблонам ItemTemplate, EditItemTemplate, InsertItemTeplate можно настроить внешний вид при любом из состояний ListView: редактировании или выборе элемента.


    Подробнее... | Рубрика: .NET компоненты | Добавлено: 22.12.2008

    Создание кросс-таб отчета в Stimulsoft Rep....

    .NET компоненты

    Компания Стимулсофт предоставляет для разработчиков мощный набор инструментов для создания отчетов для Microsoft Visual Studio .Net 2005 и 2008; эти инструменты доступны как для Windows Forms, так и для Web Forms. Это генератор отчетов Stimulsoft Reports.Net. Генератор отчетов Stimulsoft Reports.Net имеет ряд особенностей: простая работа с дизайнером отчетов, полная поддержка экспорта в PDF, Word, Excel и многие другие форматы. Crystal Report и Microsoft Reporting Service – очень хорошие программные продукты для повседневной работы, но, если Вам необходимо создать отчеты с поддержкой кросс-табов, drill down, Ajax, штрих-кодов и возможностью подключения одновременно более одного источника данных, то Stimulsoft Reports.Net поможет Вам сэкономить массу времени. Также, данный генератор отчетов позволяет пользователям создавать свои собственные отчеты любой сложности. И все эти особенности делают Stimulsoft Reports.Net хорошим выбором в сфере программных продуктов для Business Intelligence.


    Подробнее... | Рубрика: .NET компоненты | Добавлено: 22.12.2008

    Остальные статьи:

    VivaMP - инструмент для OpenMP
    Создаем контекстно-зависимое WPF-приложени...
    Windows Vista SP2: что внутри и что важно?
    Вышел MySQL 5.1.30, первый стабильный рели...
    Тестирование параллельных программ
    Архитектура AMD64 (EM64T)
    Платформа 2009. Определяя будущее
    Windows Vista Bridge Sample Library - упра...
    Оптимизация 64-битных программ
    Подгрузка через AJAX HTML-кода, содержащег...
    Обзор нового релиза самой мощной Ajax библ...
    Firebug 1.3 и 1.4 alpha — что нового и инт...
    Релиз Microsoft Silverlight 2.0. Что новог...
    XML документация в C#
    Курсоры в MySQL 5
    Microsoft опубликовала подробности о сесси...
    Microsoft делится подробностями о том, что...
    Тестируем новый javascript от нового брауз...
    MySQL Query Cache
    Использование провайдеров компиляции в As...


    Цитата дня (все,добавить):

    Портал фрилансеров

    работа на дому


        Рубрикатор

    Программирование

    C/С++
    Обучение
    Windows API
    XAML
    Моделирование
    Паттерны
    Visual Basic 7 .NET
    WxWidgets
    Функции WinApi
    Функции С++
    Разработка под Mac OS
    Eiffel
    Visual Studio 2008
    UI дизайн
    Алгоритмы
    Конкурсные статьи
    Turbo Pascal
    Visual Studio
    CASE-средства
    Visual Studio 2005
    Без VCL
    Delphi
    Тех. документация
    Тестирование
    Software Testing
    ООП
    TCP/IP
    Google Android
    Windows Installer
    .NET Framework
    Драйвера
    C# C Sharp
    Справка
    Проектирование
    Информ. системы
    Visual Basic
    Assembler
    Оптимизация кода
    Gtk+
    Компоненты
    Реинжиниринг
    Управление проектами
    Extreeme programming
    Lotus Notes
    Алгебраическое проектирование


    Интернет технологии

    PHP
    Perl
    ASP
    WAP
    Cookies
    SSI
    CGI
    Web Servers
    VB Script
    DNS
    CSS
    XML
    Html
    Java Script
    Java2ME
    Firewall
    Flash
    .htaccess
    Apache
    VRML
    Протоколы
    Поисковые системы
    Технология JAVA
    Учебник по PHP
    Учебник по JavaScript
    Учебник по XML
    Java Q&A
    AJAX
    DHTML
    XHTML
    Dreamweaver
    Web 2.0
    Python
    Вебмастеру
    Cisco
    Ruby on Rails
    Silverlight

    Базы данных

    Access
    InterBase
    MySQL
    Oracle
    ADO .NET
    Основы SQL
    Учебник по Access 2002
    MS
    Microsoft FoxPro
    Доступ к данным
    XML в MS SQL Server 2000
    ODBC и MyODBC
    Обучение
    Caché
    DB2
    PostgresSQL
    Sybase
    Теория
    Хранилища данных
    Безопасность
    Реляционные данные
    MySQL и mSQL

    Остальное:

    Разное
    Обзоры книг
    Безопасность
    Графика и дизайн
    Юмор
    Linux
    Фракталы
    Microsoft Axapta
    Многоядерность
    Сети
    Microsoft Office
    Работа
    MS-DOS
    Криптография
    Графика и игроделание
    Новости SDK
    Системы защиты
    Учебник по AutoCad
    CVS
    Windows XP
    Windows Server 2003
    Windows Vista
    Windows 7
    Мероприятия