Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.037 c
1-1089281407
P@vel
2004-07-08 14:10
2004.07.25
Thread


14-1088759001
Piter
2004-07-02 13:03
2004.07.25
Ура. Я свободен! Словно птица в небесах... :)


14-1088803935
saNat
2004-07-03 01:32
2004.07.25
Книга по 3D MAX


3-1088862357
GanibalLector
2004-07-03 17:45
2004.07.25
ГЕНЕРАТОР


14-1089096002
pavel_guzhanov
2004-07-06 10:40
2004.07.25
Получение исходников





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский