Link to home
Start Free TrialLog in
Avatar of Imbeginner
Imbeginner

asked on

View Web Server Responses ( Real And Source of Returned Html Pages From Web Server )

Hi Experts,
I used ClientSocket Component and unBlocking Mode For Connecting To A Site  Such As
Http://www.google.com/ 
I Used This Codes After Connecting To WWW.google.com
-------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
Var BytesSent:integer;
begin
BytesSent:=Clientsocket1.Socket.SendText('GET /index.htm ');
Sleep(200);
Edit1.Text:=inttostr(BytesSent);
end;
---------------------------------------------------------
unBlocking Mode  Reason For Client:
I plan To write A Simlple proxy server. I Use This Section For My Client Section of A proxy Server For Receiving Html Pages From Web Servers And Return Back  Html pages To Real Clients.

At First :I don’t Know With Which Event I Can  Inform From Server Responses In unBlocking Mode ?
Second : I Cant  View Html Pages and source of Responses.
Do you Have A Simple Coding For This Issue?
Call A URL And See  Returned Html Pages Plus Html  Sources in Your  Application?
Please Don’t write Your Coding Without Delphi Components.  Important
Thanks in Advance For Your Help.


Best Regards
Imbeginner
Avatar of 2266180
2266180
Flag of United States of America image

why not use indy or ICS or something like that (even delphi's tcp)?

or even this code:

uses ExtActns;

function getit(aurl:string);
begin
    with TDownLoadURL.Create(NIL) do
    begin
        URL:=aurl;
        FileName:=destination file;
        OnDownloadProgress:=your event for progress
        ExecuteTarget(NIL);
    end;
end;

(since you are writeing a proxy app, you might want to implement caching as well ;) )

see this for some examples for indy: http://groups.google.com/groups?q=delphi+indy+download+file&hl=en&lr=&sa=N&tab=gg&oi=groupst&q=delphi+indy+download+file
>>I plan To write A Simlple proxy server

Proxy servers are never simple.

First a proxy server will listen on a particular port for incomming requests and forward them somewhere else.

The first question is how to handle incomming requests? If you use the ICS components from Francois Piette you'll need to manage events on a per socket basis and this gets VERY messy. This is the so-call unblocking method and no beginner should attempt to use it.

If you create a thread and use Indy components or just raw Winsock calls the multiple request management is a lot simpler. You could of course start a new process to handle an incomming request (spawning) but threads are just as easy.

You should pool your threads (which requires backing up the accepts) since after around 60 odd threads the OS will creek under the strain. But that is a matter for later.

The thread should be simply given the accepted socket and then run. You will need to decide if your proxy handles HTTP proxy or is a simple socket proxy (see RFC1945 et seq for HTTP) or the SOCKS4 RFC (whose number I have forgotten).
Avatar of Imbeginner
Imbeginner

ASKER

>>Proxy servers are never simple.

at Now,For Doing A simple Work i Begin To Start with Csblocking Mode.
I think the work be Some simple From Previous and
user could be 1 Request. For Html pages.


>>The thread should be simply given the accepted socket and then run. You will need to decide if your proxy handles HTTP proxy or is a simple socket proxy (see RFC1945 et seq for HTTP) or the SOCKS4 RFC (whose number I have forgotten)<<
I want to do my proxy Server play only as Http Server.


I need A Exmaple.With Only Delphi Components.
That How Proxy Server(in which Event) Give From User Browsers thos Desired
Web page.
I need A Exmaple With Only Delphi Components That How Proxy Server(in which Event) Give From A User Browser its Desired Web page and Connect To a
Remote web server and return Results.
>> I need an example.

The best thing you can do is to download the Indy components and start by looking at the Socks4 component, which is implements the SOCKS protocol which is generally used as a proxy connection. Alternatively look at the HTML component.

You should search the web for TinyProxy, which is an example of a proxy server, written in C however, which will show you the complexity invloved in writing the simplest program.

Sorry but I don't have the source code for a server in Delphi. It would of course be sellable :)
You Can Tell Me what a web Browser Send To my Program when
a client  calls a link below
http://localhost:41200/
>>Sorry but I don't have the source code for a server in Delphi. It would of course be sellable :) <<
No , I Find the Best link About it .
http://www.felix-colibri.com/papers/web/simple_web_server/simple_web_server.html
I need A Simple Exmaple With Only Delphi Components That How Proxy Server(in which Event) Give From A User Browser its Desired Web page and Connect To a
Remote web server and return Results To it.

Simple situation:
one client  ----->Request web link--> proxy Server Forward  Request-->Web server
                <----- Return Web page <-- back ward response <---        
The link you have posted is for a web server not a proxy server.

>>You Can Tell Me what a web Browser Send To my Program when
a client  calls a link below http://localhost:41200/

If the Browser calls an HTTP proxy server then :-

    GET //localhost:41200/ HTTP/1.0<CR/LF>
    <various http headers each ending with CR/LF>
    <CR/LF>

To forward this request the GET line has to be taken apart and a simple GET sent :-
      GET / HTTP/1.0<CR/LF>
      <various headers each ending in CR/LF>
      <CR/LF>

the headers ought to be adjusted to include a via-proxy header, although that is not absolutely necessary. TinyProxy does most of these changes, so see that.

Of course the GET may be HEAD or POST and the POST has a body which you must send on. All this is documented, for HTTP 1.0, in RFC1945 which you can find at www.ietf.org.

Proxying https is much more difficult because it uses a CONNECT method first, ie: it proxies https as a sort of modified http to the proxy and then over secure socket to the web server.

Of course writing a SOCKS proxy is easier, since you get a header with the I/P address and port and only need to copy the incomming data outward, and the reply data back again.

May I ask why you want to write a proxy server?

it not so hard.

Procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
Var
   Buffer : array [0..4095] of char;
   Str:String;
   BytesReceived:integer;
   MemoryStream:TmemoryStream;
begin
Str:=Socket.RemoteHost;
  Try
      MemoryStream:=TMemoryStream.Create;
      Sleep(500);
   while True do
      begin
       BytesReceived:=Socket.ReceiveBuf(Buffer,SizeOf(Buffer));
        if (BytesReceived <= 0)  then
          Break
        else
        begin
          MemoryStream.Write(Buffer,BytesReceived);
        end;
      end;
      MemoryStream.Position := 0;
      bllog.Lines.LoadFromStream(MemoryStream);
    finally
      MemoryStream.Free;
   end;
end;

And Memo Content is :

GET / HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/x-shockwave-flash, application/vnd.ms-powerpoint, application/vnd.ms-excel, */*
Accept-Language: us,zh-cn;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; FunWebProducts)
Host: 127.0.0.1:40142
Connection: Keep-Alive

--------------------------------------------------------------------------------------
>>I ask why you want to write a proxy server?
I cant tell this.

>>The link you have posted is for a web server not a proxy server.
A Web Server similar To a Simple proxy server.
But Thos Coding is a complete Socket programming.

>>And Memo Content is :

GET / HTTP/1.1

Yes, because you've pointer the address bar in IE to your program which is listening on localhost and port 41200. That's not proxying.

Now change IE to use a proxy server (in Setup / Connections) and rerun the test by entering http://www.google.com in the address bar of the restarted IE.
Step to  Step Near To that Approach(Simple Proxy).

Reading the HTTP header must be performed line-at-a-time and not with a Stream read. You must find the header each time, and then locate any Content-Length header as well. For POST requests this content header determines the number of bytes AFTER the blank line at the end of the request.

When IE actually proxies, it sends requests one after another on the socket for potentially DIFFERENT hosts. IE normally makes two connections, one for the main form, the other for embedded data like pictures (it actually depends on how the queues are managed internally)
I solved many of my problems  From below link:
 http://www.pcdog.com/p/html/20041211/111220044017_1.htm
 It have Some Problems. But I think it give us a good idea about Implementing
 NonBlcking Condition For ServerSocket.

But I Cant know how can I Collect Information From Remote Server
To a Special Client. On TForm1.ClientSocket1Read.

It is my Coding :
if I trace My program it work Properly.
but i dont know it wasnt work when run from Exe File.

--------------------------------------------------------

unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, ScktComp, Menus, StdCtrls;
type
     session_record=record
     Used: boolean;          {The availability of the oral record }
     SS_Handle: integer;     { Proxy server sleeve joint words and expressions handle }
     CSocket: TClientSocket; { Uses in to connect long-distance sleeve joint character }
     Lookingup: boolean;     { Whether is searching server }
     LookupTime: integer;    { Search server time }
     Request: boolean;       { Whether has request }
     request_str: string;     { Request block data }
     client_connected: boolean; { Client on-line symbol }
     remote_connected: boolean; { Long-distance server connection symbol }
  end;


type
  TForm1 = class (TForm)

  ServerSocket1: TServerSocket;

  Timer1: TTimer;
  Timer2: TTimer;

  PopupMenu1: TPopupMenu;
  N11: TMenuItem;
  N21: TMenuItem;
  N01: TMenuItem;

  Label1: TLabel;

  Edit1: TEdit;
    memo1: TMemo;
    Memo2: TMemo;


Procedure FormCreate (Sender: TObject);
Procedure FormClose (Sender: TObject; var Action: TCloseAction);

Procedure ServerSocket1listen (Sender: TObject;Socket: TCustomWinSocket);
Procedure ServerSocket1ClientConnect (Sender: TObject;Socket: TCustomWinSocket);
Procedure ServerSocket1ClientDisconnect (Sender: TObject;Socket: TCustomWinSocket);

//procedure ServerSocket1ClientWrite(Sender: TObject;Socket: TCustomWinSocket);
procedure ServerSocket1ClientError (Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;var ErrorCode: Integer);

procedure ClientSocket1Connect(Sender: TObject;Socket: TCustomWinSocket);
//procedure ClientSocket1disconnect(Sender: TObject;Socket: TCustomWinSocket);
//procedure ClientSocket1write (Sender: TObject;Socket: TCustomWinSocket);
procedure ClientSocket1read (Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocket1error (Sender: TObject; Socket: TCustomWinSocket;ErrorEvent: TErrorEvent; var ErrorCode: Integer);


procedure Timer2timer (Sender: TObject);
procedure Timer1timer (Sender: TObject);

procedure N11Click(Sender: TObject);
procedure N21Click (Sender: TObject);
procedure N01Click (Sender: TObject);

procedure AppException (Sender: TObject; E: Exception);


 private
  { Private declarations }
 public
   Service_Enabled:boolean;          { Proxy serves whether opens }
   Session: Array of session_record; { Conversation array }
   Sessions:integer;                 { Conversation number }
   LookUpTimeOut: integer;           { Connection overtime value }
   InvalidRequests: integer;         { Invalid request number }
 end;

var
Form1: TForm1;


implementation

{$R *.dfm}

// system initiation timer, after the start window demonstrated completes, reduces to System Tray
procedure TForm1.Timer2timer (Sender: TObject);
begin
   Timer2.Enabled:=false;    { Closes timer }
   sessions:=0;              { Conversation counts=0 }
   Application.OnException:= AppException; { In order to shield proxy server appears exceptionally }
   invalidRequests:=0;      { 0 is wrong }
   LookUpTimeOut:=60000;    { Overtime-value=1 minute }
   Timer1.Enabled:=true;    { Turns on timer }
   n11.Enabled:=false;      { Opens service vegetable single item expires }
   n21.Enabled:=true;       { Closure service vegetable single items is effective }
   serversocket1.Port:=988; { Proxy server port =988 }
   serversocket1.Active:=true; { Opens service }
// form1.hide; { Hideaway contact surface, reduces to System Tray on }
end;


//opens the service ...
procedure TForm1.N11Click(Sender: TObject);
begin
  serversocket1.Active:=true; { Opens service }
end;

// Stops the service ...
procedure TForm1.N21Click (Sender: TObject);
begin
  serversocket1.Active:=false; { Stops serving }
  N11.Enabled:=True;
  N21.Enabled:=False;
  Service_Enabled:=false; { Symbolizes clear zero }
end;


// host window establishment...
procedure TForm1.FormCreate (Sender: TObject);
begin
Service_Enabled:=False;
Timer2.Enabled:=true; { When window establishment, turns on timer }
end;


// window close
procedure TForm1.FormClose (Sender: TObject; var Action: TCloseAction);
begin
Timer1.Enabled:=False; { Closes timer }
if Service_Enabled then
   Serversocket1.Active:=false; { When withdrawal procedure closes service }
end;

// withdrawal procedure button
procedure TForm1.N01Click (Sender: TObject);
begin
   Form1.Close; { Withdrawal procedure }
end;

//opens the proxy to serve...
procedure TForm1.ServerSocket1listen (Sender: TObject;
Socket: TCustomWinSocket);
  begin
    Service_Enabled:=true; { Sets is serving symbol }
    N11.Enabled:=false;
    N21.Enabled:=true;
  end;

// acts the end connection after the proxy server, establishes a conversation, and ties up with the sleeve joint character decides...
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i, j: integer;
begin
j:=-1;

   for i:=1 to sessions do        { searches whether has blank item }
      if not session[i-1].Used and not session[i-1].CSocket.active then
        begin
          j:=i-1;                 { Has, assigns it }
          session[j].Used:=true; { Sets for is using }
          break;
        end
     else
       if not session[i-1].Used and session[i-1].CSocket.active then
          session[i-1].CSocket.active:=false;

if j=-1 then
begin { does not have, increases one }
  j:=sessions;
  inc(sessions);
  setlength(session, sessions);
  session[j].Used:=true; { Sets for is using }
  session[j].CSocket:=TClientSocket.Create(nil);
  session[j].Lookingup:=False;
  session[j].CSocket.OnConnect:=ClientSocket1Connect;
 // session[j].CSocket.OnDisconnect:=ClientSocket1disconnect;
 // session[j].CSocket.ClientType:=ctBlocking;
  session[j].CSocket.OnError:=ClientSocket1error;
  session[j].CSocket.OnRead:=ClientSocket1read;
 // session[j].CSocket.OnWrite:=ClientSocket1write;
  session[j].request_str:=Socket.ReceiveText;
  memo1.lines.add(session[j].request_str);

end;



With Session[j] do
  begin
    SS_Handle:=Socket.socketHandle;
    Request:=true;
    CSocket.Host:='www.google.com';
    CSocket.Port:=80;
    //LookUpTimeOut:=0;
    remote_connected:=false;
    client_connected:=true;
    Lookingup:=True;
    Session[j].CSocket.Open;
  end;

edit1.text:=inttostr(sessions);


end;


// acts carries time the separation...

procedure TForm1.ServerSocket1ClientDisconnect (Sender: TObject;
Socket: TCustomWinSocket);
var
i, j, k: integer;
begin
for i:=1 to sessions do
   if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then
       begin
         session[i-1].client_connected:=False;   { Client not connects }
         if session[i-1].remote_connected then
             session[i-1].CSocket.active:=False  { if long-distance still connected, separated it }
         else
            session [i-1].Used:=false; { If two all separates, then sets at release resources symbol }
            break;
      end;

 j:=sessions;
 k:=0;

 for i:=1 to j do                               { statistical conversation array rear part has several not expenditures }
    begin
        if session[j-i ].Used then
           break;
           inc(k);
    end;

 if (k>0)and (not(session[i-1].remote_connected))  then                   { revision conversation array, release rear part not expenditures }
   begin
       sessions:=sessions-k;
       setlength(session, sessions);
   end;

edit1.text:=inttostr (sessions);

end;

// corresponds wrongly appears time...

procedure TForm1.ServerSocket1ClientError (Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
  var
      i, j, k: integer;
begin
  for i:=1 to sessions do
    if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then
      begin
     
      session[i-1].client_connected:=false; { Client not connects }
      if session[i-1].remote_connected then
         session[i-1].CSocket.active:=false { if long-distance still connected, separated it }
      else
         session[i-1].Used:=false; { If two all separates, then sets at release resources symbol }
      break;
     end;

j:=sessions;
k:=0;

for i:=1 to j do
   begin
      if session[j-i].Used then
       break;
       inc(k);
   end;

if k>0 then
  begin
     Sessions:=sessions-k;
     Setlength(session,sessions);
  end;

edit1.text:=inttostr(sessions);
errorcode:=0;

end;




// when connects the long-distance main engine to succeed...
procedure TForm1.ClientSocket1Connect(Sender: TObject;Socket: TCustomWinSocket);
var
   i,j: integer;
//    MemoryStream:TmemoryStream;
   Tmp:string;
   Line:string;
   rec_bytes,BytesReceived:integer;
   Buffer: array[0..4096] of char;

begin



   for i:=1 to sessions do
     if (session[i-1].CSocket.socket.sockethandle=socket.SocketHandle) and session[i-1].Used then
      begin
        session[i-1].CSocket.tag:=socket.SocketHandle;
        session[i-1].remote_connected:=true;  {Sets at long-distance main engine to connect symbol}
        Tmp:='';
        Tmp:=session[i-1].request_str;
        j:=pos('Host:',tmp);

        if j>0 then
        delete(tmp,j-2,21);

        J:=pos(char(13)+char(10)+char(13)+char(10),tmp);
        if j>0 then
        Delete(tmp,j,2);
        J:=Pos('Connection: Keep-Alive',tmp);
        if j>0 then
         Delete(tmp,j-2,24);

        Tmp:=Tmp+'Host: www.google.com'+char(13)+char(10)+'Connection: Keep-Alive'+ char(13)+char(10)+char(13)+char(10);

        session[i-1].request_str:='';
        session[i-1].request_str:=Tmp;
        memo1.text:=Tmp;
        Session[i-1].Csocket.Socket.SendText(Session[i-1].request_str);
        session[i-1].Lookingup:=false;
        {Clear symbol}
   end;

end;



// when has the mistake with the long-distance main engine correspondence...

procedure TForm1.ClientSocket1Error(Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;var ErrorCode: Integer);
var
i,j,k: integer;
begin

  for i:=1 to sessions do
       if (session[i-1].CSocket.tag=socket.SocketHandle) and session[i-1].Used then
         begin
          socket.close;
          session[i-1].remote_connected:=false;  {Sets for connection}
          if not session[i-1].client_connected then
              session[i-1].Used:=false           {if client has separated, then sets at release resources symbol}
          else
              for k:=1 to serversocket1.Socket.ActiveConnections do
                if (serversocket1.Socket.Connections[k-1].SocketHandle=session[i-1].SS_Handle) and session[i-1].used then
                  begin
                    serversocket1.Socket.Connections[k-1].Close;
                    break;
                  end;
          break;
        end;

 j:=sessions;
 k:=0;

  for i:=1 to j do
    begin
       if session[j-i].Used then
         break;
         inc(k);
    end;

errorcode:=0;

 if k>0 then         {revision conversation array}
    begin
      sessions:=sessions-k;
      setlength(session,sessions);
    end;

edit1.text:=inttostr(sessions);

end;


procedure TForm1.ClientSocket1Read(Sender: TObject;Socket: TCustomWinSocket);
var
i,j: integer;
rec_bytes: integer;
rec_Buffer: array[0..4096] of char;
begin
   J:=1;
   for i:=1 to sessions do
      if (session[i-1].CSocket.tag=socket.SocketHandle) and session[i-1].Used then
         begin
            Sleep(200);
            rec_bytes:=socket.ReceiveBuf(rec_buffer,2048);
          for j:=1 to serversocket1.Socket.ActiveConnections do
               if Serversocket1.Socket.Connections[j-1].SocketHandle=session[i-1].SS_Handle then
                  begin
                     serversocket1.Socket.Connections[j-1].SendBuf(rec_buffer,rec_bytes);  {????}
                     break;
                  end;
            break;
         end;

end;


//"the page cannot find" and so on the error message appears time...

procedure TForm1.AppException(Sender: TObject; E: Exception);
begin
   inc(invalidrequests);
end;

//  searches the long-distance main engine fixed time...

procedure TForm1.Timer1Timer(Sender: TObject);
  var
    i,j: integer;
 begin
   for i:=1 to sessions do
     if session[i-1].Used and session[i-1].Lookingup then {if is connecting}
       begin
         inc(session[i-1].LookupTime);
     if session[i-1].LookupTime >lookuptimeout then        {if overtime}
       begin
         session[i-1].Lookingup:=false;
         session[i-1].CSocket.active:=false;              {Stops searching}
         for j:=1 to serversocket1.Socket.ActiveConnections do
     if serversocket1.Socket.Connections[j-1].SocketHandle=session[i-1].SS_Handle then
       begin
        serversocket1.Socket.Connections[j-1].Close;        {Separates client}
        break;
       end;
       end;
       end;
end;


end.


--------------------------------
with adding some sleep function my program worked properly.

The Worked Program is :

----------------------------------------unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, ScktComp, Menus, StdCtrls;
type
     session_record=record
     Used: boolean;          {The availability of the oral record }
     SS_Handle: integer;     { Proxy server sleeve joint words and expressions handle }
     CSocket: TClientSocket; { Uses in to connect long-distance sleeve joint character }
     Lookingup: boolean;     { Whether is searching server }
     LookupTime: integer;    { Search server time }
     Request: boolean;       { Whether has request }
     request_str: string;     { Request block data }
     client_connected: boolean; { Client on-line symbol }
     remote_connected: boolean; { Long-distance server connection symbol }
  end;


type
  TForm1 = class (TForm)

  ServerSocket1: TServerSocket;

  Timer1: TTimer;
  Timer2: TTimer;

  PopupMenu1: TPopupMenu;
  N11: TMenuItem;
  N21: TMenuItem;
  N01: TMenuItem;

  Edit1: TEdit;
    memo1: TMemo;
    Memo2: TMemo;
    Label1: TLabel;
    Label2: TLabel;


Procedure FormCreate (Sender: TObject);
Procedure FormClose (Sender: TObject; var Action: TCloseAction);

Procedure ServerSocket1listen (Sender: TObject;Socket: TCustomWinSocket);
Procedure ServerSocket1ClientConnect (Sender: TObject;Socket: TCustomWinSocket);
Procedure ServerSocket1ClientDisconnect (Sender: TObject;Socket: TCustomWinSocket);

//procedure ServerSocket1ClientWrite(Sender: TObject;Socket: TCustomWinSocket);
procedure ServerSocket1ClientError (Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;var ErrorCode: Integer);

procedure ClientSocket1Connect(Sender: TObject;Socket: TCustomWinSocket);
//procedure ClientSocket1disconnect(Sender: TObject;Socket: TCustomWinSocket);
//procedure ClientSocket1write (Sender: TObject;Socket: TCustomWinSocket);
procedure ClientSocket1read (Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocket1error (Sender: TObject; Socket: TCustomWinSocket;ErrorEvent: TErrorEvent; var ErrorCode: Integer);


procedure Timer2timer (Sender: TObject);
procedure Timer1timer (Sender: TObject);

procedure N11Click(Sender: TObject);
procedure N21Click (Sender: TObject);
procedure N01Click (Sender: TObject);

procedure AppException (Sender: TObject; E: Exception);


 private
  { Private declarations }
 public
   Service_Enabled:boolean;          { Proxy serves whether opens }
   Session: Array of session_record; { Conversation array }
   Sessions:integer;                 { Conversation number }
   LookUpTimeOut: integer;           { Connection overtime value }
   InvalidRequests: integer;         { Invalid request number }
 end;

var
Form1: TForm1;


implementation

{$R *.dfm}

// system initiation timer, after the start window demonstrated completes, reduces to System Tray
procedure TForm1.Timer2timer (Sender: TObject);
begin
   Timer2.Enabled:=false;    { Closes timer }
   sessions:=0;              { Conversation counts=0 }
   Application.OnException:= AppException; { In order to shield proxy server appears exceptionally }
   invalidRequests:=0;      { 0 is wrong }
   LookUpTimeOut:=60000;    { Overtime-value=1 minute }
   Timer1.Enabled:=true;    { Turns on timer }
   n11.Enabled:=false;      { Opens service vegetable single item expires }
   n21.Enabled:=true;       { Closure service vegetable single items is effective }
   serversocket1.Port:=Strtoint(Paramstr(1)); { Proxy server port =988 }
   serversocket1.Active:=true; { Opens service }
 //  form1.hide; { Hideaway contact surface, reduces to System Tray on }
end;

//opens the service ...
procedure TForm1.N11Click(Sender: TObject);
begin
  serversocket1.Active:=true; { Opens service }
end;

// Stops the service ...
procedure TForm1.N21Click (Sender: TObject);
begin
  serversocket1.Active:=false; { Stops serving }
  N11.Enabled:=True;
  N21.Enabled:=False;
  Service_Enabled:=false; { Symbolizes clear zero }
end;


// host window establishment...
procedure TForm1.FormCreate (Sender: TObject);
begin
Service_Enabled:=False;
Timer2.Enabled:=true; { When window establishment, turns on timer }
end;


// window close
procedure TForm1.FormClose (Sender: TObject; var Action: TCloseAction);
begin
Timer1.Enabled:=False; { Closes timer }
if Service_Enabled then
   Serversocket1.Active:=false; { When withdrawal procedure closes service }
end;

// withdrawal procedure button
procedure TForm1.N01Click (Sender: TObject);
begin
   Form1.Close; { Withdrawal procedure }
end;

//opens the proxy to serve...
procedure TForm1.ServerSocket1listen (Sender: TObject;
Socket: TCustomWinSocket);
  begin
    Service_Enabled:=true; { Sets is serving symbol }
    N11.Enabled:=false;
    N21.Enabled:=true;
   
  end;

// acts the end connection after the proxy server, establishes a conversation, and ties up with the sleeve joint character decides...
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i, j: integer;
begin
j:=-1;
   sleep(100);
   for i:=1 to sessions do        { searches whether has blank item }
      if not session[i-1].Used and not session[i-1].CSocket.active then
        begin
          j:=i-1;                 { Has, assigns it }
          session[j].Used:=true; { Sets for is using }
          break;
        end
     else
       if not session[i-1].Used and session[i-1].CSocket.active then
          session[i-1].CSocket.active:=false;

if j=-1 then
begin { does not have, increases one }
  j:=sessions;
  inc(sessions);
  setlength(session, sessions);
  session[j].Used:=true; { Sets for is using }
  session[j].CSocket:=TClientSocket.Create(Form1);
  session[j].Lookingup:=False;
  session[j].CSocket.OnConnect:=ClientSocket1Connect;
  session[j].CSocket.OnError:=ClientSocket1error;
  session[j].CSocket.OnRead:=ClientSocket1read;
  session[j].request_str:=Socket.ReceiveText;
  memo1.lines.add(session[j].request_str);

end;

Sleep(50);
With Session[j] do
  begin
    SS_Handle:=Socket.socketHandle;
    Request:=true;
    CSocket.Host:=Paramstr(2);
    CSocket.Port:=80;
    //LookUpTimeOut:=0;
    remote_connected:=false;
    client_connected:=true;
    Lookingup:=True;
    LookupTime:=0;
    Session[j].CSocket.Open;
    Sleep(200);
  end;

edit1.text:=inttostr(sessions);


end;


// acts carries time the separation...

procedure TForm1.ServerSocket1ClientDisconnect (Sender: TObject;
Socket: TCustomWinSocket);
var
i, j, k: integer;
begin
for i:=1 to sessions do
   if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then
       begin
         session[i-1].client_connected:=False;   { Client not connects }
         if session[i-1].remote_connected then
             session[i-1].CSocket.active:=False  { if long-distance still connected, separated it }
         else
            session [i-1].Used:=false; { If two all separates, then sets at release resources symbol }
            break;
      end;

 j:=sessions;
 k:=0;

 for i:=1 to j do                               { statistical conversation array rear part has several not expenditures }
    begin
        if session[j-i ].Used then
           break;
           inc(k);
    end;

 if (k>0)and (not(session[i-1].remote_connected))  then                   { revision conversation array, release rear part not expenditures }
   begin
       sessions:=sessions-k;
       setlength(session, sessions);
   end;

edit1.text:=inttostr (sessions);

end;

// corresponds wrongly appears time...

procedure TForm1.ServerSocket1ClientError (Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
  var
      i, j, k: integer;
begin
  for i:=1 to sessions do
    if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then
      begin
      session[i-1].client_connected:=false; { Client not connects }
      if session[i-1].remote_connected then
         session[i-1].CSocket.active:=false { if long-distance still connected, separated it }
      else
         session[i-1].Used:=false; { If two all separates, then sets at release resources symbol }
      break;
     end;

j:=sessions;
k:=0;

for i:=1 to j do
   begin
      if session[j-i].Used then
       break;
       inc(k);
   end;

if k>0 then
  begin
     Sessions:=sessions-k;
     Setlength(session,sessions);
  end;

edit1.text:=inttostr(sessions);
errorcode:=0;

end;

// when connects the long-distance main engine to succeed...
procedure TForm1.ClientSocket1Connect(Sender: TObject;Socket: TCustomWinSocket);
var
   i,j: integer;
   Tmp:string;
   Line:string;
   rec_bytes,BytesReceived:integer;
   Buffer: array[0..4096] of char;
   MemoryStream:TmemoryStream;
begin


 //  Sleep(50);
   for i:=1 to sessions do
     if (session[i-1].CSocket.socket.sockethandle=socket.SocketHandle) and session[i-1].Used then
      begin
        session[i-1].CSocket.tag:=socket.SocketHandle;
        session[i-1].remote_connected:=true;  {Sets at long-distance main engine to connect symbol}
        Tmp:='';
        Tmp:=session[i-1].request_str;
        j:=pos('Host:',tmp);
        if j>0 then
         Begin
           while tmp[j]<>char(13) do
              delete(tmp,j,1);
           Delete(tmp,j,2);
         End;
        J:=pos(char(13)+char(10)+char(13)+char(10),tmp);
        if j>0 then
        Delete(tmp,j,2);
        J:=Pos('Connection: Keep-Alive',tmp);
        if j>0 then
         Delete(tmp,j-2,24);

        Tmp:=Tmp+'Host: '+Paramstr(2)+char(13)+char(10)+'Connection: Keep-Alive'+ char(13)+char(10)+char(13)+char(10);

        session[i-1].request_str:='';
        session[i-1].request_str:=Tmp;
        memo1.text:=Tmp;
        Session[i-1].Csocket.Socket.SendText(Session[i-1].request_str);
        session[i-1].Lookingup:=false;
        {Clear symbol}

      end;
end;

// when has the mistake with the long-distance main engine correspondence...

procedure TForm1.ClientSocket1Error(Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;var ErrorCode: Integer);
var
i,j,k: integer;
begin

  for i:=1 to sessions do
       if (session[i-1].CSocket.tag=socket.SocketHandle) and session[i-1].Used then
         begin
          socket.close;
          session[i-1].remote_connected:=false;  {Sets for connection}
          if not session[i-1].client_connected then
              session[i-1].Used:=false           {if client has separated, then sets at release resources symbol}
          else
              for k:=1 to serversocket1.Socket.ActiveConnections do
                if (serversocket1.Socket.Connections[k-1].SocketHandle=session[i-1].SS_Handle) and session[i-1].used then
                  begin
                    serversocket1.Socket.Connections[k-1].Close;
                    break;
                  end;
          break;
        end;

 j:=sessions;
 k:=0;

  for i:=1 to j do
    begin
       if session[j-i].Used then
         break;
         inc(k);
    end;

 if (k>0) and (not(session[i-1].remote_connected))  then         {revision conversation array}
    begin
      sessions:=sessions-k;
      setlength(session,sessions);
    end;
errorcode:=0;
edit1.text:=inttostr(sessions);

end;

procedure TForm1.ClientSocket1Read(Sender: TObject;Socket: TCustomWinSocket);
var
i,j: integer;
rec_bytes: integer;
rec_Buffer: array[0..4096] of char;
begin
   J:=1;
   Sleep(100);
   for i:=1 to sessions do
      if (session[i-1].CSocket.tag=socket.SocketHandle) and session[i-1].Used then
         begin
            rec_bytes:=socket.ReceiveBuf(rec_buffer,Sizeof(rec_Buffer));
          for j:=1 to serversocket1.Socket.ActiveConnections do
               if Serversocket1.Socket.Connections[j-1].SocketHandle=session[i-1].SS_Handle then
                  begin
                     serversocket1.Socket.Connections[j-1].SendBuf(rec_buffer,rec_bytes);
                     break;
                  end;
            break;
         end;


end;


//"the page cannot find" and so on the error message appears time...

procedure TForm1.AppException(Sender: TObject; E: Exception);
begin
   inc(invalidrequests);
end;

//  searches the long-distance main engine fixed time...

procedure TForm1.Timer1Timer(Sender: TObject);
  var
    i,j: integer;
 begin
   for i:=1 to sessions do
     if session[i-1].Used and session[i-1].Lookingup then {if is connecting}
       begin
         inc(session[i-1].LookupTime);
     if session[i-1].LookupTime >lookuptimeout then        {if overtime}
       begin
         session[i-1].Lookingup:=false;
         session[i-1].CSocket.active:=false;              {Stops searching}
         for j:=1 to serversocket1.Socket.ActiveConnections do
     if serversocket1.Socket.Connections[j-1].SocketHandle=session[i-1].SS_Handle then
       begin
        serversocket1.Socket.Connections[j-1].Close;        {Separates client}
        break;
       end;
       end;
       end;
end;

end.
----------------------------------------------------------


I want to Refund My points.


 Regards


in this case, post a question in the community support asking this
ASKER CERTIFIED SOLUTION
Avatar of DarthMod
DarthMod
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial