Конференция "Сети" » Дайте пример HTTP прокси на WinSock!! Без VCL/
 
  • ratatui (21.10.09 22:49) [0]
    Подскажите где можно скачать или дайте листинг!
    Спасибо!
  • Сергей М. © (22.10.09 08:59) [1]
    Чем же VCL не угодила ?
  • koha! (22.10.09 22:18) [2]
    Тем и не у годила, чтословно слон в посудной лавке, грамоздкая однако...
  • Anatoly Podgoretsky © (23.10.09 11:52) [3]
    А на написание прокси с нуля могут уйти годы, нормального конечно прокси.
  • Сергей М. © (23.10.09 12:03) [4]

    > на написание прокси с нуля могут уйти годы, нормального
    > конечно прокси


    Желающим "фраернуться перед кентами" годы не проблема)
  • CrytoGen (23.10.09 14:26) [5]
    а им не нужен нормальный прокси, им нужен не громоздкий :)
  • Palladin © (24.10.09 14:10) [6]
    Интересно, а что такое громоздкий прокси...
  • clickmaker © (26.10.09 11:09) [7]
    > что такое громоздкий прокси

    ну как... тот, который на VCL
  • SergP © (27.10.09 12:30) [8]

    > Подскажите где можно скачать или дайте листинг!


    У меня где-то валяется диск от одной книги Фленова. Там есть исходники простейшего http-прокси...
  • SergP © (27.10.09 12:36) [9]
    Щас Скопипащу это все сюда:
    main.pas

    unit MainUnit;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls, winsock;

    type
     THTTPProxyForm = class(TForm)
       bnStart: TButton;
       Label1: TLabel;
       edPort: TEdit;
       Label2: TLabel;
       edExtProxyAddr: TEdit;
       Label3: TLabel;
       edExtProxyPort: TEdit;
       procedure bnStartClick(Sender: TObject);
       procedure FormCreate(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

    var
     HTTPProxyForm: THTTPProxyForm;

    implementation

    uses ServerThreadUnit;

    {$R *.dfm}

    procedure THTTPProxyForm.bnStartClick(Sender: TObject);
    var
    st:TServerThread;
    begin
    st:=TServerThread.Create(true);
    st.iLocalPort:=StrToIntDef(edPort.Text, 8088);
    st.iExtProxyPort:=StrToIntDef(edExtProxyPort.Text, 8080);
    st.sExtProxyAddr:=edExtProxyAddr.Text;
    st.Resume;
    end;

    procedure THTTPProxyForm.FormCreate(Sender: TObject);
    var
    wData : WSADATA;
    begin
    // Загрузка WinSock
    if WSAStartup(MAKEWORD(1,1), wData) <> 0 then
    begin
      MessageBox(0, 'Не могу загрузить WinSock', 'Ошибка', 0);
      exit;
    end;
    end;

    end.

  • SergP © (27.10.09 12:36) [10]
    ServerThreadUnit.pas

    unit ServerThreadUnit;

    interface

    uses
     Classes, winsock, windows;

    type
     TServerThread = class(TThread)
     private
       { Private declarations }
     protected
       procedure Execute; override;
     public
      iLocalPort, iExtProxyPort:Integer;
      sExtProxyAddr:String;
     end;

    implementation

    uses ClientThreadUnit;

    procedure TestWinSockError(S:String);
    var
    iErr:Integer;
    sFullErr:String;
    begin
    sFullErr:='Неизвестная ошибка';
    iErr:=WSAGetLastError();

    case iErr of
     WSANOTINITIALISED: sFullErr:='Нужно сначала вызвать функцию WSASturtup, а потом создавать сокет';
    WSAENETDOWN: sFullErr:='Cвязь нарушена, возможные причины - отошёл кабель или отключились от Интернета';
    WSAEADDRINUSE: sFullErr:='Указанный адрес уже используется';
    WSAEFAULT: sFullErr:='Параметры name и namelen не соответствуют выбранной адресации. Параметр namelen может быть меньше необходимого значения, а name содержать некорректные данные';
    WSAEINPROGRESS: sFullErr:='Выполняется операция в блокирующем режиме. Вы уже запустили на выполнение какую-то функцию и нужно дождаться завершения её работы';
    WSAEINVAL: sFullErr:='Сокет уже связан с адресом';
    WSAENOBUFS: sFullErr:='Недостаточно буферов, слишком много соединений';
    WSAENOTSOCK: sFullErr:='Неверный дескриптор сокета';
     WSAEISCONN: sFullErr:='Сокет уже подключён';
     WSAEMFILE: sFullErr:='Нет больше доступных дескрипторов';
    end;

    MessageBox(0, PChar('Ошибка в функции '+S+' - '+sFullErr), 'Ошибка', 0);
    end;

    function TestFuncError(iErr:Integer; FuncName:String):Boolean;
    begin
    Result:=false;
    if iErr = SOCKET_ERROR then
     begin
      TestWinSockError(FuncName);
      Result:=true;
     end;
    end;

    procedure TServerThread.Execute;
    var
    sServerListen, stClientSocket : TSOCKET;
    localaddr : sockaddr_in;
    ct : TClientThread;
    begin
    // Создание сокета
    sServerListen := socket(AF_INET, SOCK_STREAM, 0);
    if sServerListen = INVALID_SOCKET then
     begin
      MessageBox(0, 'Ошибка создания сокета', 'Ошибка', 0);
      exit;
     end;

    // Запонение структуры адреса
    localaddr.sin_addr.s_addr := htonl(INADDR_ANY);
    localaddr.sin_family := AF_INET;
    localaddr.sin_port := htons(iLocalPort);

    // Связывание сокета с локальным адресом
    if TestFuncError(bind(sServerListen, localaddr, sizeof(localaddr)), 'bind') then
     exit;

    if TestFuncError(listen(sServerListen, 4), 'Listen') then
     exit;

    while true do
     begin
      stClientSocket := accept(sServerListen, nil, nil);
      if stClientSocket=INVALID_SOCKET then
       continue;

      ct:=TClientThread.Create(true);
      ct.stClient := stClientSocket;
      ct.iExtProxyPort := iExtProxyPort;
      ct.sExtProxyAddr := sExtProxyAddr;
      ct.Resume;
     end;
    end;

    end.

  • SergP © (27.10.09 12:37) [11]
    ClientThreadUnit.pas

    unit ClientThreadUnit;

    interface

    uses
     Classes, winsock, sysutils, windows;

    type
     TClientThread = class(TThread)
     private
       { Private declarations }
     protected
       procedure Execute; override;
     public
       iExtProxyPort:Integer;
       sExtProxyAddr:String;
       stClient:TSocket;
     end;

    implementation

    { TClientThread }

    function LookupName(name:String): TInAddr;
    var
    HostEnt: PHostEnt;
    InAddr: TInAddr;
    begin
    if name[4]='.' then
     InAddr.s_addr := inet_addr(PChar(name))
    else
     begin
     HostEnt := gethostbyname(PChar(name));
     FillChar(InAddr, SizeOf(InAddr), 0);
     if HostEnt <> nil then
      begin
       with InAddr, HostEnt^ do
        begin
         S_un_b.s_b1 := h_addr^[0];
         S_un_b.s_b2 := h_addr^[1];
         S_un_b.s_b3 := h_addr^[2];
         S_un_b.s_b4 := h_addr^[3];
        end;
      end
     end;
     Result := InAddr;
    end;

    procedure SendStr(s:TSocket; str:String);
    var
    sRecvBuff : array [0..255] of char;
    TempStr : AnsiString;
    begin
    TempStr:=str+#13+#10;
    CopyMemory(@sRecvBuff, PChar(TempStr), Length(TempStr));
    send(s, sRecvBuff, Length(TempStr), 0);
    end;

    procedure TClientThread.Execute;
    var
    Buff: array [0..1024] of char;
    iPort: Integer;
    sRequest, sHost:String;
    server_addr : sockaddr_in;
    sock_server : TSocket;
    iMode, iSize : Integer;
    rfds : TFDSET;
    begin
    ////////////////////////////
    //Считывание заголовка
    Recv(stClient, Buff, 1024, 0);

    sRequest:=String(Buff);

    // Нет заголовка
    if sRequest='' then
     begin
      CloseSocket(stClient);
      exit;
     end;

    ////////////////////////////
    // Выдераем адрес сервера и порт
    sHost:=Copy(sRequest, Pos('Host: ', sRequest), 255);
    Delete(sHost, Pos(#13, sHost), 255);
    Delete(sHost, 1, 6);
    iPort:=StrToIntDef(Copy(sHost, Pos(':', sHost)+1, 255), 80);
    Delete(sHost, Pos(':', sHost), 255);

    // Если не найден host то ошибка
    if sHost='' then
     begin
      SendStr(stClient, 'HTTP/1.0 400 Invalid header received from browser');
      CloseSocket(stClient);
      exit;
     end;

    // Если есть внешний проксик, то перенаправляем на него
    if sExtProxyAddr<>'' then
     begin
       iPort := iExtProxyPort;
       sHost := sExtProxyAddr;
     end;

    sock_server := socket(AF_INET, SOCK_STREAM, 0);

    // Ищем сервер/проксик
    server_addr.sin_addr.s_addr := htonl(INADDR_ANY);
    server_addr.sin_family := AF_INET;
    server_addr.sin_port := htons(iPort);
    server_addr.sin_addr := LookupName(sHost);

    //Соединение с сервером
    if connect(sock_server, server_addr, sizeof(server_addr))=SOCKET_ERROR then
     begin
      SendStr(stClient, '404 Host Not Found');
      exit;
     end;

    iMode:=1;
    setsockopt(sock_server, IPPROTO_TCP, TCP_NODELAY, @iMode, sizeof (integer));

    // Перенаправляем запрос серверу или другому проксику
    send(sock_server, buff, strlen(buff),0);

    // Теперь работаем посредником между клиентом и сервером
    // передавая запрошенные данные
    while true do
     begin
      // Добавляем сокеты в набор для ожидания
      FD_ZERO(rfds);
      FD_SET(stClient, rfds);
      FD_SET(sock_server, rfds);

      if (select(0, @rfds, nil, nil, nil) < 0) then
       exit;

      // Если пришел запрос от клиента
      // то перенаправляем серверу
      if(FD_ISSET(stClient, rfds)) then
     begin
      iSize := recv(stClient, buff, sizeof(buff), 0);

         if iSize=-1 then break;

      Send(sock_server, buff, iSize, 0);
      continue;
     end;

      // Если пришли данные от сервера
      // то перенаправляем клиенту
      if(FD_ISSET(sock_server, rfds)) then
     begin
      iSize := recv(sock_server, buff, sizeof(buff), 0);

         // Сервер уже всё выслал
         if iSize=0 then
          exit;

      Send(stClient, buff, iSize, 0);
      continue;
     end;
     end;
    CloseSocket(stClient);
    CloseSocket(sock_server);
    end;

    end.


  • SergP © (27.10.09 12:40) [12]

    > main.pas


    MainUnit.pas

    Ну и если понадобиться, то:

    MainUnit.dfm
    object HTTPProxyForm: THTTPProxyForm
     Left = 260
     Top = 107
     BorderStyle = bsSingle
     Caption = 'Proxy'
     ClientHeight = 145
     ClientWidth = 314
     Color = clBtnFace
     Font.Charset = DEFAULT_CHARSET
     Font.Color = clWindowText
     Font.Height = -11
     Font.Name = 'MS Sans Serif'
     Font.Style = []
     OldCreateOrder = False
     OnCreate = FormCreate
     PixelsPerInch = 96
     TextHeight = 13
     object Label1: TLabel
       Left = 8
       Top = 16
       Width = 25
       Height = 13
       Caption = #1055#1086#1088#1090
     end
     object Label2: TLabel
       Left = 8
       Top = 80
       Width = 105
       Height = 13
       Caption = #1040#1076#1088'. '#1074#1085#1077#1096'. '#1087#1088#1086#1082#1089#1080#1082#1072
     end
     object Label3: TLabel
       Left = 8
       Top = 48
       Width = 108
       Height = 13
       Caption = #1055#1086#1088#1090' '#1074#1085#1077#1096'. '#1087#1088#1086#1082#1089#1080#1082#1072
     end
     object bnStart: TButton
       Left = 120
       Top = 112
       Width = 75
       Height = 25
       Caption = #1047#1072#1087#1091#1089#1082
       TabOrder = 0
       OnClick = bnStartClick
     end
     object edPort: TEdit
       Left = 128
       Top = 16
       Width = 177
       Height = 21
       TabOrder = 1
       Text = '8080'
     end
     object edExtProxyAddr: TEdit
       Left = 128
       Top = 80
       Width = 177
       Height = 21
       TabOrder = 3
       Text = '192.168.8.88'
     end
     object edExtProxyPort: TEdit
       Left = 128
       Top = 48
       Width = 177
       Height = 21
       TabOrder = 2
       Text = '8080'
     end
    end

  • Сергей М. © (27.10.09 14:38) [13]

    > //Считывание заголовка
    > Recv(stClient, Buff, 1024, 0);
    >
    > sRequest:=String(Buff);


    Не надо учить людей плохому.
  • SergP © (27.10.09 15:20) [14]

    > Не надо учить людей плохому.


    ну я человеку только скопипастил Фленова.... Без отсебятины...

    А вообще ИМХО иногда лучше научить плохому, чем вообще не научить ничему...
  • Сергей М. © (27.10.09 15:50) [15]

    > я только скопипастил

    .. и оказал тем самым медвежью услугу
  • Anatoly Podgoretsky © (27.10.09 16:08) [16]

    > ну я человеку только скопипастил Фленова

    Нала дура чем хвастаться
    (с) известный анекдот
  • Dennis I. Komarov © (27.10.09 17:51) [17]

    > иногда лучше научить плохому, чем вообще не научить ничему.
    > ..

    Глупость несусветная...
  • Anatoly Podgoretsky © (28.10.09 10:32) [18]
    > Dennis I. Komarov  (27.10.2009 17:51:17)  [17]

    Да он в соучастники и в сокамерники напрашивается.
  • SergP © (28.10.09 19:58) [19]

    > Нала дура чем хвастаться
    > (с) известный анекдот


    > Глупость несусветная...


    > Да он в соучастники и в сокамерники напрашивается.


    О. Какие содержательные ответы.


    > Сергей М. ©   (27.10.09 15:50) [15]
    >
    >
    > > я только скопипастил
    >
    > .. и оказал тем самым медвежью услугу


    А почему сразу медвежью услугу?
    Человек просил листинг, и я ему его дал...
    По крайней мере для начала это уже кое что...
    А то, что у г-на Фленова имеются некоторые ошибки, так это даже хорошо...
    Человеку будет над чем подумать: как это исправить чтобы работало.
    А что касается этого:

    > > //Считывание заголовка
    > > Recv(stClient, Buff, 1024, 0);
    > >
    > > sRequest:=String(Buff);
    >


    то думаю что вопрошающий сам увидит что:
    1. Не факт, что 1 кбайта хватит для хранения заголовка, ибо заголовок может быть длинее (особенно когда куки большие), и тогда значение поля "Host" может и не попасть в sRequest.
    2.  Не факт, что весь запрос будет >= 1 кбайту. (в таком случае в конце sRequest будет всякий мусор, который мы отправим на сервер).
    3. Не факт что при вызове Recv мы успели получить необходимую часть заголовка. Т.е. нужно ждать пока гарантированно не получим нужную часть заголовка.
    Не знаю конечно почему Фленов опубликовал свой код в таком виде... Может у него при тестировании браузер выдавал корректные с точки зрения его прокси-сервера запросы, или еще что-нить.
    Но тем не менее у топикстартера уже будет хоть что-то для начала и далее он будет пытаться уже сам исправить это, или задавать уже конкретные вопросы.
    Заодно обнаружит и исправит и прочие ошибки, которые там имеются...

    ну а если уважаемый АП считает, что такой метод помощи в корне неверен, у него имеется полное право удалить мои сообщения.
  • Dennis I. Komarov © (29.10.09 09:09) [20]

    > Anatoly Podgoretsky ©   (28.10.09 10:32) [18]

    Не, он посадить хочет, а там пускай думает :)


    > А то, что у г-на Фленова имеются некоторые ошибки, так это
    > даже хорошо...
    > Человеку будет над чем подумать: как это исправить чтобы
    > работало.
  • Anatoly Podgoretsky © (29.10.09 11:39) [21]
    > SergP  (28.10.2009 19:58:19)  [19]

    > ну а если уважаемый АП считает, что такой метод помощи в корне неверен, у него имеется полное право удалить мои сообщения.

    Зачем мне это нужно?
    Пока нет нарушения правил, имеешь право писать, но и другие тоже!!!
  • Anatoly Podgoretsky © (29.10.09 11:40) [22]
    > Dennis I. Komarov  (29.10.2009 09:09:20)  [20]

    Ты думаешь, что он сможет остаться в стороне, да я бы на месте автора все свалил на него!
  • Dennis I. Komarov © (29.10.09 12:40) [23]

    > Anatoly Podgoretsky ©   (29.10.09 11:40) [22]

    Тогда в итоге Фленову отдуваться за все его тяжкие... :)
  • Демо © (29.10.09 14:03) [24]
    program proxy;

    {$APPTYPE CONSOLE}

    {%TogetherDiagram 'ModelSupport_proxy\default.txaPackage'}

    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,dwNumberOfConcurentThre ads);
    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;

    { 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=10;
    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.

  • Демо © (29.10.09 14:05) [25]
    Забыл автора добавить:

    {*******************************************************}
    {                                                       }
    {                  HTTP Proxy Server                    }
    {                                                       }
    {         Copyright © 2002 Sergey Polevikov           }
    {                                                       }
    {*******************************************************}
  • Сергей М. © (29.10.09 14:54) [26]
    Еще один Фленов объявился)
  • Демо © (29.10.09 15:05) [27]

    > Еще один Фленов объявился)


    Э-э... В смысле?
  • Сергей М. © (29.10.09 15:19) [28]
    Да в том же самом)
    См. выше)
  • Демо © (29.10.09 15:27) [29]

    > Сергей М. ©   (29.10.09 15:19) [28]
    > Да в том же самом)См. выше)


    Это далеко не флёновский код-)

    И автор местный;)

    А код очень полезный, если в нём разобраться, хоть и подготовка для этого не начального уровня нужна...
  • Сергей М. © (29.10.09 15:37) [30]

    > Это далеко не флёновский код


    Но зато вполне фленовский подход)

    И автор мне достаточно известен)


    > код очень полезный, если в нём разобраться


    Так я и говорю - ты сейчас пропагандируешь тот же самый "фленовский подход" к получению знаний)
  • Демо © (29.10.09 16:04) [31]

    > Так я и говорю - ты сейчас пропагандируешь тот же самый
    > "фленовский подход" к получению знаний)


    Иногда ведь полезнее изучить чужой код, чтобы понять принципы, нежели изобретать велосипед.
  • Dennis I. Komarov © (29.10.09 16:25) [32]

    > Иногда ведь полезнее изучить чужой код, чтобы понять принципы,
    >  нежели изобретать велосипед.

    Действительно в это веришь? Всмысле, что его будут изучать?
  • Демо © (29.10.09 16:32) [33]

    > Действительно в это веришь? Всмысле, что его будут изучать?


    А почему нет?.
    Для меня, когда я этот код первый раз увидел, необходимо было его изучить и понять, чтобы написать своё.

    Да даже чтобы изменить.

    Ну а если пригодится в таком виде - да ради бога, - на здоровье.
    Ничего страшного в копипасте нет.
  • Anatoly Podgoretsky © (29.10.09 16:34) [34]
    > Демо  (29.10.2009 16:04:31)  [31]

    Полезно изучать, именно изучать, хороший, профессиональный код. При том желательно, что бы это были примеры демонстрирующие принципы, а не готовый код. Я всегда, при освоении нового, особенно технологий, смотрю примеры, а готовый рабочий код мне неинтересен, от него толку не много.
  • Демо © (29.10.09 16:39) [35]

    > Anatoly Podgoretsky ©   (29.10.09 16:34) [34]
    > > Демо  (29.10.2009 16:04:31)  [31]Полезно изучать, именно
    > изучать, хороший, профессиональный код. При том желательно,
    >  что бы это были примеры демонстрирующие принципы, а не
    > готовый код. Я всегда, при освоении нового, особенно технологий,
    >  смотрю примеры, а готовый рабочий код мне неинтересен,
    > от него толку не много.


    Иногда для своей задачи необходим промежуточный компонент.
    Например, для получения всех запросов от браузера нужно либо снифер изучать, либо пустить запросы через прокси.

    Для чего мне в данном случае изучать внутренность прокси, если мне оно не нужно, а нужен результат?
  • Сергей М. © (29.10.09 16:44) [36]

    > Демо ©   (29.10.09 16:32) [33]
    > А почему нет?.


    Потому что топикстарт изрядно отдает курсачем или даже лабой)
  • Anatoly Podgoretsky © (29.10.09 16:51) [37]
    > Демо  (29.10.2009 16:39:35)  [35]

    В этом случае прокси не нужен, а нужен форвард портов со шпионом. Например шпион есть в Инди
  • Dennis I. Komarov © (29.10.09 16:52) [38]

    > В этом случае прокси не нужен, а нужен форвард портов со
    > шпионом. Например шпион есть в Инди

    В этом случае вообще писать ничего не надо...
  • Демо © (29.10.09 18:13) [39]

    > В этом случае прокси не нужен, а нужен форвард портов со
    > шпионом. Например шпион есть в Инди


    Что, ещё и файрволл ставить для этого?


    > Dennis I. Komarov ©   (29.10.09 16:52) [38]
    > > В этом случае прокси не нужен, а нужен форвард портов
    > со > шпионом. Например шпион есть в ИндиВ этом случае вообще
    > писать ничего не надо...


    Ну-ка, ну-ка, поподробнее...
  • Дмитрий Белькевич (29.10.09 18:41) [40]
    Господа студенты, не учитесь, пожалуйста! Старайтесь как можно больше получить на халяву! Чем меньше вы знаете по окончании института, тем более ценен я как специалист и тем большую зарплату я могу потребовать за свои услуги!

    Так что, господа студенты, почаще обращайтесь на форумы и, форумчане, почаще отдавайте готовые решения.
  • Демо © (29.10.09 18:46) [41]

    > Дмитрий Белькевич   (29.10.09 18:41) [40]


    Так про то, что писать ничего не надо, можно немного рассказать?
  • Демо © (29.10.09 21:32) [42]

    > Дмитрий Белькевич   (29.10.09 18:41) [40]
    > Господа студенты, не учитесь, пожалуйста! Старайтесь как
    > можно больше получить на халяву! Чем меньше вы знаете по
    > окончании института, тем более ценен я как специалист и
    > тем большую зарплату я могу потребовать за свои услуги!Так
    > что, господа студенты, почаще обращайтесь на форумы и, форумчане,
    >  почаще отдавайте готовые решения.


    И почему меня, например, это не волнует?
  • Сергей М. © (29.10.09 21:37) [43]
    Вероятно потому что ты  - господин студент ?)
  • Демо © (29.10.09 22:26) [44]

    > Сергей М. ©   (29.10.09 21:37) [43]
    > Вероятно потому что ты  - господин студент ?)


    Да нет.
    Скорее я не воюю с ветряными мельницами.
    Каждый выбирает сам.
    Кто-то воюет с ветряными мельницами (в том числе и здесь), полагая, что от него что-то зависит в деле воспитания, а кто-то принимает жизнь такой какая она есть.
    И если я вижу вопрос, то я не выискиваю подтекстов и причин, по которым нужно отказать в помощи.
    Если меня не затруднит - дам код и объясню. Затруднит объяснять - дам код и ничего не буду объяснять.

    А учиться или не учиться - ЛИЧНОЕ дело каждого.
  • Dennis I. Komarov (htc) (29.10.09 23:02) [45]
    и это помощь?
  • Демо © (29.10.09 23:06) [46]

    > Dennis I. Komarov (htc)   (29.10.09 23:02) [45]
    > и это помощь?


    Да. Это помощь.
    А что тебя в этой помощи не устраивает?
  • SergP © (29.10.09 23:15) [47]
    2 Сергей М.
    Вы местный Дин Кихот?
  • Сергей М. © (29.10.09 23:23) [48]

    > Демо ©   (29.10.09 22:26) [44]


    > не воюю с ветряными мельницами


    Тоже мне Недон-Некихот)
    Чем попусту трындеть про мельницы, лучше бы порассуждал вслух, чем чревато беспардонное игнорирование результатов вызовов API-функций)
  • SergP © (29.10.09 23:24) [49]

    > Dennis I. Komarov (htc)


    > и это помощь?


    А Вы, как я понял Санчо Пансе?
  • Сергей М. © (29.10.09 23:25) [50]

    > SergP ©   (29.10.09 23:15) [47]


    Тебя это насколько заботит ?)
  • Демо © (29.10.09 23:25) [51]

    > Сергей М. ©   (29.10.09 23:23) [48]
    > > Демо ©   (29.10.09 22:26) [44]> не воюю с ветряными мельницамиТоже
    > мне Недон-Некихот)Чем попусту трындеть про мельницы, лучше
    > бы порассуждал вслух, чем чревато беспардонное игнорирование
    > результатов вызовов API-функций)


    Конечно же неработоспособностью программы при малейшей проблеме.
    Что ту размышлять-то?-)
  • Демо © (29.10.09 23:27) [52]

    > Сергей М. ©   (29.10.09 23:23) [48]


    Вот тут-то автор пусть и напрягается, если ему это действительно нужно.
  • Сергей М. © (29.10.09 23:28) [53]

    > Что ту размышлять-то?


    А зачем тут постить код, неработоспособный при малейшей проблеме ?
  • Демо © (29.10.09 23:30) [54]

    > Сергей М. ©   (29.10.09 23:28) [53]
    > > Что ту размышлять-то?А зачем тут постить код, неработоспособный
    > при малейшей проблеме ?


    Он работоспособен. Но не всегда.
    ПОлностью реализована схема.
    Если автору нужна 99%-надежная программа - пусть дорабатывает.

    С чего-то надо начинать?
    Если же не нужна - вольному воля, пусть использует в таком виде.
  • Сергей М. © (29.10.09 23:30) [55]

    > Демо ©   (29.10.09 23:27) [52]


    Полагаю - ему это нахрен не нужно)
  • Дмитрий Белькевич (29.10.09 23:32) [56]
    >А учиться или не учиться - ЛИЧНОЕ дело каждого.

    Угу, http://lurkmore.ru/%D0%92%D1%81%D0%B5%D0%BC_%D0%BF%D0%BE%D1%85%D1%83%D0%B9
  • Демо © (29.10.09 23:32) [57]

    > Дмитрий Белькевич   (29.10.09 23:32) [56]
    > >А учиться или не учиться - ЛИЧНОЕ дело каждого.Угу, http:
    > //lurkmore.ru/%D0%92%D1%81%D0%B5%D0%BC_%D0%BF%D0%BE%D1%85%D1%83%D0%B9


    Вот только этого барахла (как и ссылок на него) не надо бы.
  • Сергей М. © (29.10.09 23:32) [58]

    > С чего-то надо начинать?


    Надо.
    Но не с требования "дайте !"
    )
  • Демо © (29.10.09 23:33) [59]

    > Сергей М. ©   (29.10.09 23:30) [55]
    > > Демо ©   (29.10.09 23:27) [52]Полагаю - ему это нахрен
    > не нужно)


    Ну не нужно так не нужно.
    А если возникли бы вопросы - можно и ответить.
    Мало ли, может кто-то другой захочет довести до ума код.
  • Демо © (29.10.09 23:35) [60]
    Сергей, согласись, что вся дискуссия - это всего лишь личное отношение каждого к этому вопросу.
    А личное мнение не должно быть категоричным правилом.
  • Сергей М. © (29.10.09 23:36) [61]

    > Ну не нужно так не нужно


    А чего тогда буквами по Тырнету зазря сорить ?)
    Вот как будет действительно нужно - вот тогда и ..
    )
  • SergP © (29.10.09 23:36) [62]

    > Тебя это насколько заботит ?)


    Скажем так: Думаю, что Вы неправы... К сожалению я сейчас не совсем в состоянии объяснить почему, но позже приведу свои доводы.
  • Дмитрий Белькевич (29.10.09 23:41) [63]
    >Вот только этого барахла (как и ссылок на него) не надо бы.

    Зря ты это считаешь барахлом. Увы, но это более, чем серьёзно.
  • Сергей М. © (29.10.09 23:42) [64]

    > Вы неправы


    Вот приедет барин ratatui - барин нас рассудит)
    Что тут вхолостую языком молотить ?)
  • Демо © (29.10.09 23:44) [65]

    > Дмитрий Белькевич   (29.10.09 23:41) [63]
    > >Вот только этого барахла (как и ссылок на него) не надо
    > бы.Зря ты это считаешь барахлом. Увы, но это более, чем
    > серьёзно.


    Лукоморье - это бред больного.
  • Демо © (29.10.09 23:45) [66]
    Лучше выскажите мысли по поводу - есть ли смысл использовать WSARecv и WSASend вместо ReadFile и WriteFile при использовании перекрытого ввода/вывода с IOCP?
  • Дмитрий Белькевич (29.10.09 23:48) [67]
    >Лукоморье - это бред больного.

    Своё зерно истины на нём есть. Одна, небольшая, крупица - как раз по ссылке. Она наиболее точно выражает отношение 95-99% людей ко всему происходящему.
  • Сергей М. © (29.10.09 23:50) [68]

    > Демо ©   (29.10.09 23:45) [66]


    Заводи свой топик - подскажем лучше.
    А сюда трындеть не по теме нет резона)
  • Polevi © (30.10.09 12:15) [69]
    это-же надо, всплыло :)
  • Сергей М. © (30.10.09 12:21) [70]

    > Polevi ©   (30.10.09 12:15) [69]


    Гордись)

    Не пропадет твой скорбный труд - его "as is" в курсач упрут)
  • Polevi © (30.10.09 12:30) [71]
  • Сергей М. © (30.10.09 12:38) [72]

    > да уж


    Ох и ушлый же этот народец - студни)

    Можно смело сказать:
    Не пропадет твой скорбный труд - его "as is" в троян упрут
    )
  • Демо © (30.10.09 12:47) [73]

    > Polevi ©   (30.10.09 12:15) [69]
    > это-же надо, всплыло :)


    Ну а почему не всплыть. Чудный пример использования IOCP и SOcket IO Overlapped.
  • SergP © (30.10.09 20:20) [74]

    > Вот приедет барин ratatui - барин нас рассудит)


    Барин похоже где-то застрял.. не появляется... )
  • Гость! (09.10.10 03:29) [75]
    Удалено модератором
  • Гость! (09.10.10 03:31) [76]
    Удалено модератором
  • Гость! (09.10.10 03:36) [77]
    Удалено модератором
  • Гость! (09.10.10 03:37) [78]
    Удалено модератором
  • grisme © (09.10.10 16:17) [79]
    у Кейта, помнится, был вполнетакойгодный HTTP-прокси, консольный. DarkEye, вроде, не? деревянный, конечно, немного был. но работал (:
  • Ref (09.10.10 19:59) [80]
    гугли.
     LWrite('Prepare to work:',FOREGROUND_GREEN or FOREGROUND_INTENSITY,0);
     Writeln('');
     LWrite('=======================',FOREGROUND_GREEN or FOREGROUND_INTENSITY,0);
     Writeln('');
     LWrite('Create main socket:',FOREGROUND_RED or FOREGROUND_INTENSITY,0);
     FCompPort:=TCompletionPort.Create(ClientThreadCount);
     LWrite(' Ok',FOREGROUND_RED or FOREGROUND_INTENSITY,0);
     Writeln('');
     if FCompPort.FHandle<>0 then begin
       LWrite('Initialise:',FOREGROUND_RED or FOREGROUND_INTENSITY,0);
       WSAStartup($0101, WSAData);
       LWrite(' Ok',FOREGROUND_RED or FOREGROUND_INTENSITY,0);
       Writeln('');
       LWrite('Create main threads:',FOREGROUND_RED or FOREGROUND_INTENSITY,0);
       for i:=0 to ClientThreadCount-1 do TClientThread.Create(false);
       TAcceptThread.Create(ListenPort);
       LWrite(' Ok',FOREGROUND_RED or FOREGROUND_INTENSITY,0);
       Writeln('');
       LWrite('=======================',FOREGROUND_GREEN or FOREGROUND_INTENSITY,0);
       Writeln('');
       LWrite('Proxy activate',FOREGROUND_GREEN or FOREGROUND_INTENSITY,0);
       Writeln('');
       LWrite('=======================',FOREGROUND_GREEN or FOREGROUND_INTENSITY,0);
       Writeln('');
       repeat
         ReadConsole(GetStdHandle(STD_INPUT_HANDLE),@Buff,10,Cnt,nil);
         ConsoleText := String(Buff);
       until UpperCase(Copy(ConsoleText,1,4)) = 'EXIT';
       WSACleanup;
     end;

  • Dangeres (25.02.13 23:59) [81]
    помогите что делает эта функция TestFuncError  ????
 
Конференция "Сети" » Дайте пример HTTP прокси на WinSock!! Без VCL/
Есть новые Нет новых   [118639   +35][b:0.001][p:0.012]