Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование для начинающих и не только


Информационный Канал Subscribe.Ru

По материалам сайта www.gigabyte.iatp.org.ua

©Gigabyte 2004

Proxy своими руками

Иногда у системных администраторов, пользователей Интернета и просто любознательных программеров возникают три извечных вопроса: "Что? Где? Когда?" т.е. Что они передают в Интернет, что Интернет передает им, Когда началась передача данных, когда она закончилась, какая скорость передачи....На большинство этих вопросов дает ответ Proxy-сервер.

Определения

Сначала определимся с терминами и задачами. Proxy-сервер - программа (аппаратными комплексами я пока не занимаюсь), которая вклинивается в цепочку: "Браузер - Сервер Интернет - Провайдера - "Большой - Интернет" между Браузером и Интернет провайдером и следить за передаваемой информацией, делая некоторые ститистические выводы и, возможно, влияя на передаваемую информацию. Естественно нет предела совершенству т.е. разработке новых функций прокси, но в этой статье мы рассмотрим самую безобидную из них - подсчет размера передаваемой информации.

Что?

Для начала откроем Delphi и воспользуемся уже знакомой нам палитрой IndyServers (рис.1). Оттуда перетащим на форму компонент idMappedPortTCP, который как раз и предназначен для создания прокси - сервера; для этого в нем определены три свойства:

  • DefaultPort:Integer - номер порта, на котором "висит" наш прокси и к которому должны обращаться клиенты
  • MappedPort:Integer - номер порта, на котором висит сервер (сервер провайдера или другой прокси - сервер на вашем компьютере).
  • MappedHost:String - название хоста, на котором находится другой сервер.
Назначим этим порта соответственно значения:
  • Active = True; (не забываем включить наш прокси, а то зачем же мы его делаем)
  • DefaultPort = 8080;
  • MappedPort = 800;
  • MappedHost = 'localhost';

Почему именно эти значения? Очень просто: 8080 - стандартный порт для HTTP-Proxy, а 800 и 'localhost' - стандартные параметры PLS(см. статью "Веб-сервер своими руками"). Теперь запустим PLS и наш прокси. Откроем браузер и попробуем набрать в нем адрес нашего локального сайта ("www.test.com"). Ну что, как видим - в окне браузера появился наш сайт. Только нам от этого копа никакого проку т.к. мы еще не решили поставленой задачи.

Теперь давайте рассмотрим поближе события вызываемые компонентом TidMappedPortTCP:
TBeforeClientConnectEvent=procedure(ASender:TComponent;AThread:TIdPeerThread; AClient:TIdTCPClient) of object;
OnBeforeClientConnect:TBeforeClientConnectEvent;
Это событие возникает перед тем, как клиент приконнектится к нашему серверу. Значения параметров:

  • ASender - ссылка на вызвавший компонент.
  • AThread - ссылка на поток, который будет обрабатывать подключение
  • AClient - идентификатор клиента, который связывается с нами.

TIdServerThreadEvent = procedure (AThread: TIdPeerThread) of object;

property OnConnect: TIdServerThreadEvent;
property OnDisconnect: TIdServerThreadEvent;
Первое событие возникает тогда, когда поток AThread соединяется с другим сервером, а второе - когда соединение закрывается. Вот этими событиями мы и воспользуемся. Но для начала заглянем в TidPeerThread (посредством технологии Delphi - CodeInsight) . Там мы обнаружим свойство Connection. Проделаем тоже самое и с ним. Результат - два очень полезных свойства: Intercept и InterceptEnabled , - первое указывает на класс - потомок TidConnectionIntercept, который, как видно из названия, перехватывает всю поступающую информацию, а второе - разрешение или запрет перехвата. Вот теперь, то мы добрались до изюминки нашего проекта. Как раз объект Intercept и будет заведовать подсчетом трафика. Присмотревшись, мы обнаружим, что этот объект не поддерживает технологию повторного использования кода. А это значит, что для реализации поставленной задачи нам потребуется писать свой класс - наследник TidConnectionIntercept, который и будет делать всю "грязную работу"(см. Листинг 1). Далее в секции реализации мы пишем следующее:

 procedure TForm1.MappedTCPConnect(AThread: TIdPeerThread);
  begin
   AThread.Connection.Intercept:=MyIntercept;
   AThread.Connection.InterceptEnabled:=True;
  end;

 procedure TForm1.MappedTCPDisconnect(AThread: TIdPeerThread);
  begin
   //BytesSent - count of bytes sent by Proxy form *Server* to *Client*
   ReceiveStatistics.Caption:=FormatBytes(MyIntercept.BytesSent);
   //BytesReceived - count of bytes received by Proxy from *Client*
   SentStatistics.Caption:=FormatBytes(MyIntercept.BytesReceived);
  end;
И не забываем при создании формы создать объект MyIntercept, а при удалении формы - удалить его:

 procedure TForm1.FormCreate(Sender:TObjet);
  begin
   MyIntercept:=TMyIntercept.Create(Self);
   MyIntercept.OnDataReceived:=DoWriteReceiveLog;
   MyIntercept.OnDataSent:=DoWriteSentLog;
  End;

 procedure TForm1.FormDestroy(Sender:TObject);
  begin
   MyIntercept.Free;
  end;
SentStatistics, ReceiveStatistics - объекта типа TPanel в которых выводится информация о размере передаваемой информации.

Где?

Бывалые интернетчики конечно же знают, как настроить браузер на работу с прокси, и всё же. Ну-у скажем "Вчера был новый год.... Я имени своего не помню, а не то, чтобы какой-то там прокси".

  • Для настройки ослика IE откройте "Сервис - Свойства обозревателя - Подключение - Настройка сети"(рис.2). Там в секции прокси сервер в поле "Адрес" пропишите "localhost" или другое название компьютера на котором стоит ваша прокся, а в поле "Порт" - 8080.
  • Для Mozilla: "Edit - Preferences - Advanced - Proxies". Поле HTTP-Proxy те же параметры.
  • Ну и для примы балерины т.е. Opera: Жмем "Alt - P; Далее Networks - Proxy Servers". И соответственно прописываем параметры в поля HTTP и Port.


Когда?

Теперь, когда мы настроили все параметры, мы смело можем запускать наш прокси в свободное плавание. Т.е. запускаем прокси и браузер и коннектимся(не буду напоминать, что для пользы дела можно интерфейс чуть-чуть приукрасить, добавить изменение параметров прокси и т.п. рис.6). Здесь, наверное, я сделаю предупреждение, что при отладке прокси т.е. при запуске приложения из Delphi могут возникать некоторые исключения. Но я их обошел следующим путем. Во первых окружил все приложение блоком try...except с выдачей результата через ShowMessage при возникновении исключения (см. Листинг 2). Откомпилировал приложение и тестировал его только как отдельное приложение (т.е. запускал не из Delphi). После этих манипуляций я провел на просторах Интернета больше часа и никаких ошибок не возникало.

Послесловие

Конечно подсчет размера передаваемых данных это не такая уж и большая фишка. Но как говорится "все в ваших руках". Т.е. вы теперь можете спокойно добавить в CustomIntercept.pas свои обработчики чтения и записи, в которых спокойно можете реализовать возможность ведения лога(именно это и сделано в строках: "MyIntercept.OnDataReceived:=DoWriteReceiveLog; MyIntercept.OnDataSent:=DoWriteSentLog;"); вычисления скорости передачи данных, времени ответа сервера, фильтрации контента по заданным условиям и т.д. Или воспользоваться исходным кодом приложения выставленного на моем сайте, или присоединится к его дальнейшей разработке...все в ваших руках


http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.programmershelp
Отписаться

В избранное