Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.26;
Скачать: CL | DM;

Вниз

Прокси   Найти похожие ветки 

 
тихий вовочка ©   (2004-07-18 14:57) [0]

Попробовал сделать примитивнейший прокси на Indy. Но у меня ничего не получается. Не могу нормально состыковать IndyHTTPServer и IndyHTTPClient. То есть логика проста - браузер передает запрос моему серверу, то посылает своего клиента за нужной страничкой или рисунком(рисунки у меня только принудительно грузяться вообще), а потом переправляет это все браузеру. Без кеширования, анализа и прочего. Просто взял - отдал. Что я делаю нерпавильно?

procedure TForm1.IdHTTPServer1CommandGet(AThread: TIdPeerThread;
 ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var

url : string;

buf : TMemoryStream;
begin

buf := TMemoryStream.Create;
buf.Clear;
buf.Position := 0;

url := "http://" + ARequestInfo.Host + ARequestInfo.Document;

if ARequestInfo.Command = "GET" then
 begin
   ListBox1.Items.Add("GET");
   IdHTTP1.Get(url, buf);

 end
else
 if ARequestInfo.Command = "POST" then
   begin
     ListBox1.Items.Add("POST");
   end
else
 if ARequestInfo.Command = "PUT" then
   begin
     ListBox1.Items.Add("PUT");
   end
else
 if ARequestInfo.Command = "HEAD" then
   begin
     ListBox1.Items.Add("HEAD");
   end;

if AResponseInfo.ContentStream = nil then
 begin
   ListBox1.Items.Add("nil");
 end;

AResponseInfo.ContentStream := TMemoryStream.Create;

buf.Position := 0;

AResponseInfo.ContentStream.CopyFrom(buf,buf.Size);

buf.Free;

AResponseInfo.WriteContent;

AResponseInfo.CloseConnection := true;

AResponseInfo.ContentStream.Free;

end;


 
Hogo   (2004-07-19 08:13) [1]

Есть компоненты
TIdTunnelMaster
TIdTunnelSlave

и самый простой вариант
IdMappedPortTCP


 
Reindeer Moss Eater ©   (2004-07-19 08:25) [2]

то посылает своего клиента за нужной страничкой или рисунком

И где это в приведенном коде можно увидеь?


 
тихий вовочка ©   (2004-07-19 12:35) [3]

И где это в приведенном коде можно увидеь?

url := "http://" + ARequestInfo.Host + ARequestInfo.Document;
Это получает сервер от браузера

IdHTTP1.Get(url, buf);
Это запускается клиент для скачивания требуемого

AResponseInfo.ContentStream.CopyFrom(buf,buf.Size);
Это сервер передает браузеру то, что скачал клиент


 
Reindeer Moss Eater ©   (2004-07-19 12:39) [4]

Я бы не был так уверен насчет этого:

url := "http://" + ARequestInfo.Host + ARequestInfo.Document;
Это получает сервер от браузера


 
Reindeer Moss Eater ©   (2004-07-19 12:44) [5]

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


 
Reindeer Moss Eater ©   (2004-07-19 12:51) [6]

А если у клиента в запросе необходимые ему куки есть например?
Или параметры для авторизации?


 
nikkie ©   (2004-07-19 15:30) [7]

>[1] Hogo   (19.07.04 08:13)
>Есть компоненты
>TIdTunnelMaster
>TIdTunnelSlave
ну и причем тут они?

>и самый простой вариант
>IdMappedPortTCP
для "прочтейшего прокси" вполне, но автор делает на самом деле http-прокси.


 
Reindeer Moss Eater ©   (2004-07-19 15:32) [8]

И причем неправильно делает.


 
nikkie ©   (2004-07-19 16:06) [9]

не знаю, насколько удачная идея использовать idHTTPServer для прокси.
мне так помниться, что он разбирает request в поля RequestInfo, потом придется самому собирать их обратно.
я делал прокси на основе TIdMappedPortTCP.

 THTTPProxy = class (TIdMappedPortTCP)
 protected
   procedure DoConnect(AThread: TIdPeerThread); override;
 end;

function ChrPos(S: String; Ch: Char; Start: Integer = 1): Integer;
var
 Len: Integer;
begin
 Result := 0;
 Len := Length(S);
 while Start <= Len do begin
   if S[Start] = Ch then begin
     Result := Start;
     break;
   end;
   Inc(Start);
 end;
end;

function ChrPosR(S: String; Ch: Char; Start: Integer = -1): Integer;
begin
 Result := 0;
 if Start = -1 then Start := Length(S);
 while Start >= 1 do begin
   if S[Start] = Ch then begin
     Result := Start;
     break;
   end;
   Dec(Start);
 end;
end;

procedure THTTPProxy.DoConnect(AThread: TIdPeerThread);
var
 Request: TStringList;
 Command, Protocol, Url, Host, Port, Path, Dir, FileName: String;
 idx1, idx2, idx: integer;
begin
 Request := TStringList.Create;
 try
   repeat
     Command := AThread.Connection.ReadLn("");
     Request.Add(Command);
   until Command = "";

   Command := Request[0];
   idx1 := ChrPos(PChar(Command), " ");
   idx2 := ChrPosR(PChar(Command), " ");
   if idx1 = idx2 then begin // 0 or 1 space
     AThread.Connection.WriteLn("HTTP/1.1 400 Bad Request");
     abort;
   end;

   Protocol := Copy(Command, idx2 + 1, Length(Command) - idx2);
   Url := Copy(Command, idx1 + 1, idx2 - idx1 - 1);
   Command := Copy(Command, 1, idx1 - 1);
   Port := "";

   if AnsiStartsText("http:", Url) then begin
     Delete(Url, 1, Length("http:"));
     Port := "80";
   end;
   if AnsiStartsText("https:", Url) then begin
     Delete(Url, 1, Length("https:"));
     Port := "443";
   end;
   if AnsiStartsText("//", Url) then begin
     Delete(Url, 1, Length("//"));
   end;
   idx := ChrPos(Url, "/");
   if idx > 0 then begin
     Host := Copy(Url, 1, idx - 1);
     Path := Copy(Url, idx, Length(Url) - idx + 1);
   end else begin
     Host := Url;
     Path := "/";
   end;
   idx := ChrPos(Host, ":");
   if idx > 0 then begin
     Port := Copy(Url, idx + 1, Length(Url) - idx);
     Host := Copy(Host, 1, idx - 1);
   end;
   if Length(Path) = 0 then Path := "/";

   idx := ChrPosR(Path, "/");
   Assert(idx > 0);
   FileName := Copy(Path, idx + 1, Length(Path) - idx);
   if Length(FileName) > 0 then begin
      // здесь у меня весьма урезанная логика кеширования:

   end;

   Request[0] := Command + " " + Path + " " + Protocol;

   MappedHost := Host;
   MappedPort := StrToIntDef(Port, 80);

   inherited;

   if not AnsiSameText(Command, "CONNECT") then begin
     TIdMappedPortTCPData(AThread.Data).OutboundClient.Write(Request.Text);
   end;
   if AThread.Connection.CurrentReadBufferSize > 0 then begin
     TIdMappedPortTCPData(AThread.Data).OutboundClient.Write(
       AThread.Connection.ExtractXBytesFromBuffer(AThread.Connection.CurrentReadBufferSize));
   end;
 finally
   Request.Free;
 end;
end;


 
nikkie ©   (2004-07-19 16:10) [10]

блин, отправилось чуть недописанным...
после комментария
// здесь у меня весьма урезанная логика кеширования:
код такой:
     Dir := "какой-то путь";
     FileName := Dir + FileName;
     if FileExists(FileName) then begin
       AThread.Connection.WriteLn("HTTP/1.1 200 OK");
       AThread.Connection.WriteLn("Connection: close");
       AThread.Connection.WriteLn;
       AThread.Connection.WriteFile(FileName);
       abort;
     end;
то есть при запросе файла, который есть в локальной директории, прокси отдает его, не обращаясь к сетевому ресурсу.


 
Reindeer Moss Eater ©   (2004-07-19 16:13) [11]

Берем TCPServer.
Организуем цикл readln чтения клиента пока не прочитаем пустую строку.
Request клиента у нас в кармане.
Остается найти в нем host/port.

После чего соединяемся TCPClient"ом c host/port и пишем туда весь заголовок как есть.


 
www_Vlad   (2004-07-19 22:17) [12]

Народ, делаю клиент/серверную софтину, подскажите как сделать, чтобы она могла работать через прокси?


 
VID ©   (2004-07-19 22:49) [13]

Проще всего строить на Indy там свойства Proxy, ProxyPort уже есть в рамках самого компонента (Клиента).


 
тихий вовочка ©   (2004-07-19 23:03) [14]

Берем TCPServer.
Организуем цикл readln чтения клиента пока не прочитаем пустую строку.
Request клиента у нас в кармане.
Остается найти в нем host/port.

Так можно у того же IndyHTTPServer брать RawHTTPString или что-то в этом духе(Делфи нет под рукой)


 
www_Vlad   (2004-07-20 00:50) [15]

Ну насчет tcp-сервера я так понимаю, для него ничего не меняется, сам прокси-сервер мнене нужен, я не его делаю, а вот насчет клиента не совсем понятно, я шлю пакеты на прокси, но как дать понять прокси, куда их затем пересылать?
С инди я посмотрел, спасибо, как их использовать ясно, но мне не совсем идея ясна, объясните плиз. Что нужно послать в порт прокси-серверу, чтобы он перенаправил пакет на другой сервер (если не пользовать компоненты)?



Страницы: 1 вся ветка

Текущий архив: 2004.09.26;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.071 c
6-1090190924
Лев Ландау
2004-07-19 02:48
2004.09.26
Как сгенерить html-страницу и поместить ее в TWebBrowser?


3-1093627265
riko
2004-08-27 21:21
2004.09.26
Sybase - c чего начать?


14-1094637449
Ega23
2004-09-08 13:57
2004.09.26
Только что приятель прислал :о)


3-1093926955
HanIP
2004-08-31 08:35
2004.09.26
функция, которая выбирает товары


14-1089883872
Igor_thief
2004-07-15 13:31
2004.09.26
TRAY