unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, WinSock;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
Edit1: TEdit;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
THttpHead= record
Host: string;
Patch: string;
Method: string;
Port: integer;
Http_ver: string;
Refer: string;
end;
TMyThread = class(TThread)
public
CSock: TSocket;
Caddr: TSockAddrIn;
procedure stop();
protected
procedure Execute; override;
end;
TNitThread = class(TThread)
nomer: integer;
HttpHead: THttpHead;
ssock,csock: TSocket;
saddr, caddr: TSockAddrIn;
len, i: integer;
buff: array[1..2048] of char;
noerr: boolean;
SL: TStringList;
protected
procedure Execute; override;
public
procedure ReadHttpHead();
procedure WriteHttpHead();
end;
const
max_user=5;
var
Form1: TForm1;
myt: TMyThread;
niti: array [0..max_user] of TNitThread;
used: array [0..max_user] of boolean;
users: integer;
implementation
{$R *.dfm}
procedure TMyThread.Execute();
var
ServSock: TSocket;
WSAData: TWSAData;
locaddr: TSockAddrIn;
len: integer;
i: integer;
begin
WSAStartUp(257, WSAData);
ServSock:=socket(AF_INET, SOCK_STREAM,0);
if ServSock<0 then Form1.Memo1.Lines.Add('Bad socket');
locaddr.sin_family:=AF_INET;
locaddr.sin_port:=htons(8080);
locaddr.sin_addr.S_addr:=0;
bind(ServSock, locaddr, sizeof(locaddr));
listen(ServSock, 1);
len:=sizeof(caddr);
while true do
if users<=max_user then
begin
for i:=0 to max_user do
if used=false then
begin
CSock:=accept(ServSock, @caddr, @len);
niti:=TNitThread.Create(true);
niti.nomer:=i;
niti.Resume;
Inc(users);
Form1.Label1.Caption:=IntToStr(users);
end;
end;
end;
procedure TMyThread.stop();
begin
WSACleanup();
end;
procedure TNitThread.ReadHttpHead();
var
p: integer;
s: string;
i:integer;
begin
len:=recv(ssock,buff[1], 2048,0);
if len=SOCKET_ERROR then
begin
closesocket(ssock);
closesocket(csock);
noerr:=false;
end;
SetLength(s, len-1);
for i:=1 to len do s:=buff;
SL.Text:= s;
//====opredel9em metod===============
if Copy(SL[0],1,3)='GET' Then HttpHead.Method:='GET';
if Copy(SL[0],1,4)='POST' Then HttpHead.Method:='POST';
if Copy(SL[0],1,7)='CONNECT' Then HttpHead.Method:='CONNECT';
//====opredel9em port================
p:=pos(':',SL[0]);
if (p<=0) or (p=9) Then HttpHead.Port:=80; //http:
//====opredel9em versiu protokola====
HttpHead.Http_ver:=Copy(SL[0], Length(SL[0])-8, 9);
s:=SL[0];
p:=pos('http://', s);
Delete(s, p, 7);
i:=pos('/', s);
p:=p;
HttpHead.Host:=Copy(s, p, i-p);
p:=pos(HttpHead.Host, SL[0])+Length(HttpHead.Host);
i:=pos(HttpHead.Http_ver, SL[0]);
HttpHead.Patch:=CoPy(SL[0], p, i-p);
//if HttpHead.Patch='/' then HttpHead.Patch:='*';
{ for i:= 0 to SL.Count-2 do
begin
p:=pos('Proxy-', SL.Strings);
if p>0 then
begin
Delete(sl.strings,p,6);
end;
end;
end;
procedure TNitThread.WriteHttpHead();
var
s: string;
i: integer;
begin
Sl.Delete(0);
Sl.Insert(0, HttpHead.Method+' '+HttpHead.Patch+' '+HttpHead.Http_ver);
Sl.Add('Host:'+HttpHead.Host);
Sl.Add('');
Form1.Memo1.Text:=Form1.Memo1.Text+Sl.Text;
s:=SL.Text;
for i:=1 to Length(s) do buff:=s;
len:=i-1;
len:=send(csock, buff[1], len, 0);
if len<=0 then
begin
closesocket(ssock);
closesocket(csock);
noerr:=false;
end;
end;
procedure TNitThread.Execute();
var
WFds, RFds : TFDset;
tv: TTimeVal;
Host: PHostEnt;
pa: PChar;
begin
SL:=TStringList.Create();
ssock:=myt.CSock;
saddr:=myt.Caddr;
ReadHttpHead();
csock:=socket(AF_INET, SOCK_STREAM,0);
caddr.sin_port:=htons(HttpHead.Port);
caddr.sin_family:=AF_INET;
Host:=GetHostByName(PansiChar('http://'+HttpHead.Host));
pa := Host^.h_addr_list^;
caddr.sin_addr.S_un_b.s_b1:=pa[0];
caddr.sin_addr.S_un_b.s_b2:=pa[1];
caddr.sin_addr.S_un_b.s_b3:=pa[2];
caddr.sin_addr.S_un_b.s_b4:=pa[3];
connect(csock, caddr, sizeof(caddr));
Form1.Memo1.Lines.Add('Client connected');
Form1.Memo1.Lines.Add('==========='+inttostr(nomer)+'=========');
noerr:=true;
WriteHttpHead();
while noerr do
begin
FD_ZERO(WFds);
FD_ZERO(RFds);
tv.tv_sec:=1;
tv.tv_usec:=0;
FD_SET(ssock, WFds);
FD_SET(ssock, RFds);
FD_SET(csock, WFds);
FD_SET(csock, RFds);
select(0,@RFds,@WFds,nil,@tv);
if FD_ISSET(ssock, RFds) and FD_ISSET(csock, WFds) then
begin
Form1.Memo1.Lines.Add('ssock>csock');
len:=recv(ssock,buff[1], 2048,0);
if len=SOCKET_ERROR then
begin
closesocket(ssock);
closesocket(csock);
noerr:=false;
end;
len:=send(csock, buff[1], len, 0);
if len<=0 then
begin
closesocket(ssock);
closesocket(csock);
noerr:=false;
end;
end;
if FD_ISSET(ssock, WFds) and FD_ISSET(csock, RFds) then
begin
Form1.Memo1.Lines.Add('csock>ssock');
len:=recv(csock,buff[1], 2048,0);
if len=SOCKET_ERROR then
begin
closesocket(ssock);
closesocket(csock);
noerr:=false;
end;
len:=send(ssock, buff[1], len, 0);
if len<=0then
begin
closesocket(ssock);
closesocket(csock);
noerr:=false;
end;
end;
end;
SL.Free;
used[nomer]:=false;
Dec(users);
Form1.Label1.Caption:=IntToStr(users);
Terminate;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
myt:=TMyThread.Create(false);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
myt.stop();
myt.Terminate;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
users:=0;
used[0]:=True;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i: integer;
begin
for i:=1 to max_user do
if used then niti.Terminate;
WSACleanup();
end;
end.
Проблемы с загрузкой страниц
Пишу свой прокси сервер. Вроде все делаю правельно, но почему то когда пытаюсь загрузить страницу получаю ошибку 404.