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

Вниз

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

 
Graf   (2004-05-28 07:21) [0]

Уважаемые товарищи!
Приспичило мне тут написать небольшой прокси-сервер без кэширования и прочих наворотов. Но ничего так и не смог найти. Может посоветуете пару статей. А за исходники вообще спасибо!


 
SammIk ©   (2004-05-28 08:57) [1]

А можт за тебя еще и написать?
Есть такие rfc, вот в них все и написано. Ищи


 
Reindeer Moss Eater ©   (2004-05-28 09:03) [2]

Псевдокод простейшего HTTP прокси:

procedure TidTCPServer.OnExecute(AThread : TIdPeerThread);
begin
repeat
 сStr := Readln;
 UserRequest.Add(cStr);
until cStr = "";
ClientGetString := Найти_строку_GET_запроса_в_хедере_клиента(UserRequest);
with TidHTTP.Create(nil) do
 try
  cStr := Get(ClientGetString);
 finally
  Free;
 end;
AThread.Connection.WriteString(cStr);
end;


 
Digitman ©   (2004-05-28 09:03) [3]


> Приспичило мне тут написать небольшой прокси-сервер


какова же его основная задача, такого вот сервера ?


 
Graf   (2004-05-28 09:59) [4]

Задача следующая - надо объединить запросы с нескольких компов из локалки. Я поюзал несколько прог, но они меня не устраивают по ряду различных причин. А надо работать с портами SMTP, POP3, HTTP, FTP и парой специализированных портов (типа 500). Все по TCP. Ну про HTTP я узнал, а как вот работать с SMTP и POP3?


 
Reindeer Moss Eater ©   (2004-05-28 10:04) [5]

Все твои потребности удовлетворит любой из целого ряда широко распространенных прокси серверов в режиме Socks


 
Reindeer Moss Eater ©   (2004-05-28 10:05) [6]

В том числе бесплатных


 
Стас   (2004-05-28 10:23) [7]

А не проще ли перейти под Линух?


 
Graf   (2004-05-28 10:47) [8]

Нууу... Давайте все перейдем на Фришник и вернемся в годам моей молодости, когда деревья были большими, а программы - консольными ;-)
У меня половина софта только под ХР идет, сервера баз данных Yafill и прочее. Никак. А вот интернет-кафе из трех компов на диал-ап, причем на одном телефонном номере - это уже вешалка. Я тут попробовал WinProxy, но что-то он мне не показался. Вот и решил свой написать.


 
Stoyan   (2004-05-28 17:54) [9]

Попробуй 3proxy с http://www.security.nnov.ru/soft/.
Весит хрен да ни хрена, по хр работает (проверено),
по-крайней мере 2 компа по диал-апу тянет.


 
Senti   (2004-05-28 22:01) [10]

Используй проги Eserv в связке с UserGate. Лучшей альтернативы нет.
Eserv хорошо работает с кешем. UserGate как распределение и контроль траффика.

Т.е. первый прокси будет Eserv, UserGate тянет все данные через него. А пользователи коннектится к ЮзерГейту.

У нас стоит корпоративная сеть на 50 машин... Работает все на ура....

Для обрезания банеров и рекламы юзай еще Outpost Firewall...

Максимальная экономия траффика обеспечена....

А если хочешь еще организовать почтовый сервер... Используй Kerio Mail Server. Это самый лучший, который я видел. Очень удобный и функциональный. Огромное кол-во возможностей.


 
atruhin ©   (2004-05-29 10:33) [11]

Вот пример, непомню где брал. Только колличество потоков обработки порта нужно увеличить (50-100).

{*******************************************************}
{                                                       }
{                  HTTP Proxy Server                    }
{                                                       }
{         Copyright (c) 2002 Sergey Polevikov           }
{                                                       }
{*******************************************************}

program proxy;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows, Winsock, Classes;

type
TCompletionPort=class
public
FHandle:THandle;
constructor Create(dwNumberOfConcurentThreads:DWORD);
destructor Destroy;override;
function AssociateDevice(hDevice:THandle;dwCompKey:DWORD):boolean;
end;

TAcceptThread=class(TThread)
private
FListenSocket:TSocket;
FListenPort:Word;
FClientList:TList;
procedure GarbageCollect;
protected
procedure Execute;override;
public
constructor Create(AListenPort:Word);reintroduce;
destructor Destroy;override;
end;

type
TClientThread=class(TThread)
public
procedure Execute;override;
end;

type
TClient=class
private
FSocket:TSocket;
FEvent:THandle;
ov:POVERLAPPED;
Buffer:Pointer;
BufSize:Cardinal;
procedure Write(Buf:Pointer;Size:Cardinal);
public
FOppositeClient:TClient;
FLastActivity:double;
constructor Create;
destructor Destroy;override;
procedure Connect(ARequest:string);
procedure Disconnect;
procedure Complete(dwNumBytes:Cardinal);virtual;abstract;
end;

TInternalClient=class(TClient)
public
procedure Complete(dwNumBytes:Cardinal);override;
end;

TExternalClient=class(TClient)
public
procedure Complete(dwNumBytes:Cardinal);override;
end;

//-------------------------------implementation-------------------------------

var
FCompPort:TCompletionPort;

{ TCompletionPort }

constructor TCompletionPort.Create(dwNumberOfConcurentThreads: DWORD);
begin
FHandle:=CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,dwNumberOfConcurentThreads);
end;

function TCompletionPort.AssociateDevice(hDevice: THandle;
 dwCompKey: DWORD): boolean;
begin
result:=CreateIoCompletionPort(hDevice,FHandle,dwCompKey,0)=FHandle;
end;

destructor TCompletionPort.Destroy;
begin
CloseHandle(FHandle);
inherited;
end;

{ TAcceptThread }

constructor TAcceptThread.Create(AListenPort: Word);
begin
inherited Create(false);
FListenPort:=AListenPort;
FClientList:=TList.Create;
end;

destructor TAcceptThread.Destroy;
begin
FClientList.Free;
inherited;
end;

procedure TAcceptThread.GarbageCollect;
var
AClient:TClient;
i:integer;
begin
for i:=0 to FClientList.Count-1 do
begin
AClient:=TClient(FClientList[i]);
if Assigned(AClient) then
if (AClient.FSocket=INVALID_SOCKET) and ((now-AClient.FLastActivity)>7E-4) then
begin
FClientList[i]:=nil;
if Assigned(AClient.FOppositeClient) then AClient.FOppositeClient.Free;
AClient.Free;
end;
end;
FClientList.Pack;
FClientList.Capacity:=FClientList.Count;
end;

procedure TAcceptThread.Execute;
var
FAddr: TSockAddrIn;
Len: Integer;
ClientSocket:TSocket;
InternalClient:TClient;
begin
FListenSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
FAddr.sin_family := PF_INET;
FAddr.sin_addr.s_addr := INADDR_ANY;
FAddr.sin_port := htons(FListenPort);
bind(FListenSocket, FAddr, SizeOf(FAddr));
listen(FListenSocket, SOMAXCONN);

try
while not Terminated do
begin
   Len:=sizeof(FAddr);
   ClientSocket:=accept(FListenSocket, @FAddr, @Len);
   try
   GarbageCollect;
   if ClientSocket<>INVALID_SOCKET then
   begin
   InternalClient:=TInternalClient.Create;
   InternalClient.FSocket:=ClientSocket;
   FClientList.Add(InternalClient);
   FCompPort.AssociateDevice(InternalClient.FSocket,Cardinal(InternalClient));
   InternalClient.Complete(0);
   end;
   except
   end;
end;
finally
shutdown(FListenSocket,2);
closesocket(FListenSocket);
end;
end;


 
atruhin ©   (2004-05-29 10:34) [12]

......... Продолжение.
{ TClientThread }

procedure TClientThread.Execute;
var
CompKey,dwNumBytes:Cardinal;
ov:POVERLAPPED;
begin
try
while not Terminated do
begin
if GetQueuedCompletionStatus(FCompPort.FHandle,dwNumBytes,CompKey,ov,INFINITE) and (dwNumBytes>0) then
begin
if TClient(CompKey).FSocket<>INVALID_SOCKET then
begin
TClient(CompKey).Complete(dwNumBytes);
TClient(CompKey).FLastActivity:=now;
end;
end
else
TClient(CompKey).Disconnect;
end;
except
TClientThread.Create(false);
end;
end;

{ TClient }

constructor TClient.Create;
begin
FSocket:=INVALID_SOCKET;
BufSize:=8192;
GetMem(Buffer,BufSize);
new(ov);
ov.Internal:=0;
ov.InternalHigh:=0;
ov.Offset:=0;
ov.OffsetHigh:=0;
ov.hEvent:=0;
FEvent:=CreateEvent(nil,true,false,nil);
FLastActivity:=now;
end;

destructor TClient.Destroy;
begin
Disconnect;
CloseHandle(FEvent);
FreeMem(Buffer);
Dispose(ov);
inherited;
end;

procedure TClient.Connect(ARequest: string);
var
f,t:integer;
ARemoteAddress:string;
ARemotePort:string;
he:PHostEnt;
FAddr:TSockAddrIn;
begin
f:=Pos("/",ARequest)+2;
t:=Pos("HTTP",ARequest)-1;
ARemoteAddress:=Copy(ARequest,f,t-f);
t:=Pos("/",ARemoteAddress);
if t<>0 then ARemoteAddress:=Copy(ARemoteAddress,0,t-1);
t:=Pos(":",ARemoteAddress);
if t<>0 then
begin
ARemotePort:=Copy(ARemoteAddress,t+1,Length(ARemoteAddress)-t);
ARemoteAddress:=Copy(ARemoteAddress,0,t-1);
end
else
ARemotePort:="80";

he:=GetHostByName(PChar(ARemoteAddress));
if not Assigned(he) then exit;
ARemoteAddress:=inet_ntoa(PInAddr(he.h_addr_list^)^);

FSocket:=socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
FAddr.sin_family:=PF_INET;
FAddr.sin_addr.s_addr :=inet_addr(PChar(ARemoteAddress));
try
FAddr.sin_port := htons(StrToInt(ARemotePort));
if WinSock.connect(FSocket, FAddr, SizeOf(FAddr))=SOCKET_ERROR then FSocket:=INVALID_SOCKET;
except
end;
end;

procedure TClient.Disconnect;
begin
if FSocket<>INVALID_SOCKET then
begin
shutdown(FSocket,2);
closesocket(FSocket);
FSocket:=INVALID_SOCKET;
if Assigned(FOppositeClient) then FOppositeClient.Disconnect;
end;
end;

procedure TClient.Write(Buf: Pointer; Size: Cardinal);
var
BytesWrite:Cardinal;
begin
ov.hEvent:=FEvent or 1;
WriteFile(FSocket,Buf^,Size,BytesWrite,ov);
ov.hEvent:=0;
end;

{ TInternalClient }

procedure TInternalClient.Complete(dwNumBytes: Cardinal);
var
BytesRead:Cardinal;
begin
if dwNumBytes>0 then
begin
if not Assigned(FOppositeClient) then
begin
FOppositeClient:=TExternalClient.Create;
FOppositeClient.FOppositeClient:=self;
FOppositeClient.Connect(PChar(Buffer));
if FOppositeClient.FSocket=INVALID_SOCKET then
begin
Disconnect;
exit;
end;
FCompPort.AssociateDevice(FOppositeClient.FSocket,Cardinal(FOppositeClient));
FOppositeClient.Complete(0);
end;
FOppositeClient.Write(Buffer,dwNumBytes);
end;
ReadFile(FSocket,Buffer^,BufSize,BytesRead,ov);
end;

{ TExternalClient }

procedure TExternalClient.Complete(dwNumBytes: Cardinal);
var
BytesRead:Cardinal;
begin
if dwNumBytes>0 then FOppositeClient.Write(Buffer,dwNumBytes);
ReadFile(FSocket,Buffer^,BufSize,BytesRead,ov);
end;

const
ClientThreadCount:integer=8;
ListenPort:Dword=8080;

var
WSAData:TWSAData;
Cnt:Cardinal;
i:integer;
begin
FCompPort:=TCompletionPort.Create(ClientThreadCount);
if FCompPort.FHandle<>0 then
begin
WSAStartup($0101, WSAData);
for i:=0 to ClientThreadCount-1 do TClientThread.Create(false);
TAcceptThread.Create(ListenPort);
ReadConsole(GetStdHandle(STD_INPUT_HANDLE),nil,0,Cnt,nil);
WSACleanup;
end;
end.


 
SergP ©   (2004-05-29 12:36) [13]

Если без кеширования, да еще и разные протоколы, то лучше ставить не прокси а что-то типа роутера с преобразованием адресов.

Думаю Kerio WinRoute тебе поможет. Только новые версии не ставь - они глючат. ИМХО самое оптимальное что-то типа 4.2.2


 
Polevi ©   (2004-05-29 15:06) [14]

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



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

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

Наверх




Память: 0.51 MB
Время: 0.046 c
14-1088723413
Defen
2004-07-02 03:10
2004.07.25
глубиные ошибки


10-1023374714
Алексей Черменов
2002-06-06 18:45
2004.07.25
Построение КИС на основе технологии EJB


1-1089603479
Vitalik
2004-07-12 07:37
2004.07.25
TChart


1-1089705911
half_litre
2004-07-13 12:05
2004.07.25
Hint в формах из dll


4-1086041485
Chlavik
2004-06-01 02:11
2004.07.25
WaitCommEvent