Форум: "Сети";
Текущий архив: 2004.09.26;
Скачать: [xml.tar.bz2];
ВнизПрокси Найти похожие ветки
← →
тихий вовочка © (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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.036 c