beloubelou
Messages postés2Date d'inscriptionvendredi 23 janvier 2009StatutMembreDernière intervention16 septembre 2011
-
16 sept. 2011 à 11:41
Utilisateur anonyme -
16 sept. 2011 à 14:03
Bonjour,
Ce petit programme fonctionne comme un proxy.
Il utilise deux composants delphi: THttpserver de FPiette et TAlWinhttp de Alcinone.
Le premier prend les commandes GET et le second (multithread) fait le boulot d'aller chercher les données sur un proxy (S'occupe automatiquement des authentifications demandées NTLM, Negociate, ..).
J'ai un problème : un fois les données recueillies, au moment de répondre aux demandes des clients. La connexion s'interrompe : "Socket is not connected ..."
Quelqu'un a t-il une idée d'où peut provenir le problème ?
Code source :
unit uMain;
{$I OverbyteIcsDefs.inc}
{$IFNDEF DELPHI7_UP}
Bomb('This sample requires Delphi 7 or later');
{$ENDIF}
{$B-} { Enable partial boolean evaluation }
{$T-} { Untyped pointers }
{$X+} { Enable extended syntax }
{$I+} { Turn IO exceptions to on }
{$H+} { Use long strings }
{$J+} { Allow typed constant to be modified }
{$IFDEF COMPILER12_UP}
{ These are usefull for debugging !}
{$WARN IMPLICIT_STRING_CAST OFF}
{$WARN IMPLICIT_STRING_CAST_LOSS OFF}
{$WARN EXPLICIT_STRING_CAST OFF}
{$WARN EXPLICIT_STRING_CAST_LOSS OFF}
{$ENDIF}
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_LIBRARY OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{ 27 january 2001
Changed CloseDelayed to ShutDown(1) when a remote close. In some
circumstances there could be data not received by local socket when closed }
type
{ This component is used for client connection instead of default one. }
{ This enables adding any data we need to handle our application. }
{ As this data is located in client component, each connected client has }
{ his own private data. }
TMyHttpConnection = class(THttpConnection)
protected
FPostedRawData : PAnsiChar; { Will hold dynamically allocated buffer }
FPostedDataBuffer : PChar; { Contains either Unicode or Ansi data }
FPostedDataSize : Integer; { Databuffer size }
FDataLen : Integer; { Keep track of received byte count. }
FDataFile : TextFile; { Used for datafile display }
FFileIsUtf8 : Boolean;
FClientNum : integer;
public
WSessionCookie : String;
destructor Destroy; override;
end;
{**********************************************************}
procedure TMain.initWinHTTP(aHttpClient: TAlWinHttpClient);
Begin
With aHTTPClient do begin
UserName := EditUserName.Text;
Password := EditPassword.Text;
if AlIsInteger(EditConnectTimeout.Text) then ConnectTimeout := strtoint(EditConnectTimeout.Text);
if AlIsInteger(EditsendTimeout.Text) then SendTimeout := strtoint(EditSendTimeout.Text);
if AlIsInteger(EditReceiveTimeout.Text) then ReceiveTimeout := strtoint(EditReceiveTimeout.Text);
if RadioButtonProtocolVersion1_0.Checked then ProtocolVersion := HTTPpv_1_0
else ProtocolVersion := HTTPpv_1_1;
if AlIsInteger(EditBufferUploadSize.Text) then UploadBufferSize := strtoint(EditBufferUploadSize.Text);
if RadioButtonAccessType_NO_PROXY.Checked then AccessType := wHttpAt_NO_PROXY
else if RadioButtonAccessType_NAMED_PROXY.Checked then AccessType := wHttpAt_NAMED_PROXY
else if RadioButtonAccessType_DEFAULT_PROXY.Checked then AccessType := wHttpAt_DEFAULT_PROXY;
InternetOptions := [];
If CheckBoxInternetOption_BYPASS_PROXY_CACHE.checked then InternetOptions := InternetOptions + [wHttpIo_BYPASS_PROXY_CACHE];
If CheckBoxInternetOption_ESCAPE_DISABLE.checked then InternetOptions := InternetOptions + [wHttpIo_ESCAPE_DISABLE];
If CheckBoxInternetOption_ESCAPE_DISABLE_QUERY.checked then InternetOptions := InternetOptions + [wHttpIo_ESCAPE_DISABLE_QUERY];
If CheckBoxInternetOption_ESCAPE_PERCENT.checked then InternetOptions := InternetOptions + [wHttpIo_ESCAPE_PERCENT];
If CheckBoxInternetOption_NULL_CODEPAGE.checked then InternetOptions := InternetOptions + [wHttpIo_NULL_CODEPAGE];
If CheckBoxInternetOption_REFRESH.checked then InternetOptions := InternetOptions + [wHttpIo_REFRESH];
If CheckBoxInternetOption_SECURE.checked then InternetOptions := InternetOptions + [wHttpIo_SECURE];
If CheckBoxInternetOption_NO_COOKIES.checked then InternetOptions := InternetOptions + [wHttpIo_NO_COOKIES];
If CheckBoxInternetOption_KEEP_CONNECTION.checked then InternetOptions := InternetOptions + [wHttpIo_KEEP_CONNECTION];
If CheckBoxInternetOption_NO_AUTO_REDIRECT.checked then InternetOptions := InternetOptions + [wHttpIo_NO_AUTO_REDIRECT];
//------------------------------------------------------------------------------
procedure TMain.ListenBtnClick(Sender: TObject);
begin
if ListenBtn.Tag = 0 then
begin
//if not FInitialized then begin
HttpServer1.Options := HttpServer1.Options - [hoAllowDirList];
HttpServer1.Options := HttpServer1.Options - [hoAllowOutsideRoot];
HttpServer1.Port := Trim(LocalPoort.Text);
HttpServer1.KeepAliveTimeSec := StrToIntDef(KeepAliveTimeSecEdit.Text, 10);
HttpServer1.MaxRequestsKeepAlive := StrToIntDef(MaxRequestsKeepAliveEdit.Text, 100);
HttpServer1.ClientClass := TMyHttpConnection;
try
HttpServer1.Start;
except
on E: Exception do
begin
Display('**** Unable to start server ****','', 1);
if HttpServer1.WSocketServer.LastError = WSAEADDRINUSE then
begin
Display('**** Port ' + HttpServer1.Port +
' already used by another application ****', '', 1);
Exit;
end;
Display('**** ' + E.ClassName + ': ' + E.Message + ' ****','', 1);
end;
end;
FInitialized := true;
LocalPoort.Enabled := False;
EdProxyport.Enabled := False;
EdProxyserver.Enabled := False;
ListenBtn.Caption := 'Cancel';
ListenBtn.Tag := 1;
//end
end else
begin
HttpServer1.Stop;
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TMain.action(Sender: TObject; ClientCnx : TMyHttpConnection; var Flags : THttpGetFlag);
Var
aStressHttpThread: TStressHttpThread;
begin
ReqStartTime := GetTickCount;
ToTalBytesReceived := 0;
if NbreRequest <= NiceGrid1.RowCount then
NiceGrid1.AddRow;
Avant de poser ta question, as tu penser à lire la RFC du protocole HTTP
Dans cette RFC il y a marqué clairement :
Excepté pour des applications expérimentales, la pratique courante spécifie qu'une connexion doit être initiée par un client avant transmission de la requête, et refermée par le serveur après délivrance de la réponse. Les deux côtés, client et serveur, doivent être préparés à ce que la connexion soit coupée prématurément, suite à une action de l'utilisateur, une temporisation automatique, ou une faute logicielle, et doivent apporter une réponse prévisible à cette situation. Dans tous les cas, la fermeture d'une connexion qu'elle qu'en soit la raison est assimilable à la conclusion de la requête, quel que soit l'état.