为啥这个检查代理有效性的代码会崩溃?

Posted

技术标签:

【中文标题】为啥这个检查代理有效性的代码会崩溃?【英文标题】:Why does this code for checking proxy validity crash?为什么这个检查代理有效性的代码会崩溃? 【发布时间】:2011-01-06 05:07:16 【问题描述】:

我的程序中有以下代码。当我尝试检查代理是否是有效代理时,它会使我的程序崩溃。任何想法如何解决这一问题?我正在使用 indy 10。

if checkproxy('http://www.google.com') label1.text:='Good' else label1.text:='bad';

如果我在请求 checkproxy 后尝试调用另一个 idHTTP 连接,则会导致程序崩溃。

这是实际的代码......返回错误......


function TregForm.webSession(sURL : ansistring) : ansistring;
  var  sstream : Tstringstream;
       httpcon : TIdHTTP;
       antifreeze : TIdAntiFreeze;
begin
  result := '';
  sstream := tstringstream.Create('');
  try
    if length(SettingsForm.edtProxyServer.text) >= 7 then  // 0.0.0.0 
    if checkproxy('@987654321@') then
    begin
      antifreeze := TIdAntiFreeze.Create(nil);
      httpcon := TIdHTTP.create;
      httpcon.ProxyParams.BasicAuthentication:=true;
      httpcon.ProxyParams.ProxyPassword:=SettingsForm.edtProxyPass.Text;
      httpcon.ProxyParams.ProxyPort:=strtoint(SettingsForm.edtProxyPort.Text);
      httpcon.ProxyParams.ProxyServer:=SettingsForm.edtProxyServer.Text;
      httpcon.ProxyParams.ProxyUsername:=SettingsForm.edtProxyUserName.Text;
    end
    else
    begin
      showmessage('Proxy Server Not Working..  Attempting to bypass the Proxy');
      antifreeze := TIdAntiFreeze.Create(nil);
      httpcon := TIdHTTP.create;
      //httpcon.Request.ProxyConnection:='';
      //httpcon.ProxyParams.BasicAuthentication:=false;
      //httpcon.ProxyParams.ProxyPassword:='';
      //httpcon.ProxyParams.ProxyPort:=0;
      //httpcon.ProxyParams.ProxyServer:='';
      //httpcon.ProxyParams.ProxyUsername:='';
    end;
    httpcon.HandleRedirects := true;
    antifreeze.Active := true;
    HttpCon.Get(sURL,sstream);
    result := utf8towidestring(sstream.DataString);
  except
    httpcon.Disconnect;
  end;
  antifreeze.Active := false;
  freeandnil(httpcon);
  freeandnil(antifreeze);
  freeandnil(sstream);
end;

function TregForm.checkproxy(sURL : ansistring) : boolean; var //sstream : Tstringstream; httpcon : TIdHTTP; antifreeze : TIdAntiFreeze; begin result := true; try antifreeze := TIdAntiFreeze.Create(nil); httpcon := TIdHTTP.create; //sstream := tstringstream.Create(''); httpcon.ProxyParams.BasicAuthentication:=true; httpcon.ProxyParams.ProxyPassword:=SettingsForm.edtProxyPass.Text; httpcon.ProxyParams.ProxyPort:=strtoint(SettingsForm.edtProxyPort.Text); httpcon.ProxyParams.ProxyServer:=SettingsForm.edtProxyServer.Text; httpcon.ProxyParams.ProxyUsername:=SettingsForm.edtProxyUserName.Text;

httpcon.HandleRedirects := true;
antifreeze.Active := true;
HttpCon.Request.ProxyConnection:=SettingsForm.edtProxyServer.Text;
HttpCon.head(sURL);
httpCon.Disconnect;

except on E: EIdException do begin result:=false; end; On E:exception do begin //showmessage('External error:' + #13#10 + E.Message); showmessage('Proxy Settings Error'); result:=false; end; end; antifreeze.Active := false; freeandnil(httpcon); freeandnil(antifreeze); //freeandnil(sstream); end;

错误消息:模块 key.exe 中的异常 AccessViolation 在 E001B844A。 模块“key.exe”中地址 005B844A 的访问冲突。读取地址 00000000。

【问题讨论】:

你说“它崩溃了”是什么意思? 我得到一个运行时错误,程序崩溃了,想把崩溃数据发送给微软。 我剪切/粘贴了实际代码...当我在关闭调试器的情况下运行程序时,它会立即弹出“请告诉微软有关此问题的消息”。然后按照说明给出错误消息。当我使用调试器运行时,它会给我一个中断通知,但不会中断导致问题的代码行。 【参考方案1】:

在您上面的代码中,如果“SettingsForm.edtProxyServer.text”少于 7 个字符,您将遇到在没有先创建 AntiFreeze 和 HttpCon 的情况下使用它们的情况。

我对您的代码进行了一些实验,并在我的 WinXP SP3(D2010,Indy v10.5.5)上进行了测试。这应该是工作代码...

procedure TForm1.Button1Click(Sender: TObject);
Var
   Resp : String;
begin
     Resp := webSession('http://www.celarius.com');
     if Length(Resp)>0 then
        MessageDlg('Got the body ok',mtInformation,[mbOk],0);
end;

function TForm1.webSession(sURL : ansistring) : ansistring;
var
   SStream    : Tstringstream;
   HTTPCon    : TIdHTTP;
   AntiFreeze : TIdAntiFreeze;
begin
     Result := '';
     if Length(SettingsForm.edtProxyServer.text) >= 7 then  // 0.0.0.0
     Try
        SStream := NIL;
        AntiFreeze := NIL;
        HTTPCon := NIL;
        Try
           SStream := tstringstream.Create('');
            Create & Set IdHTTP properties 
           HTTPCon := TIdHTTP.create;
           HTTPCon.HandleRedirects := true;
            Check Proxy 
           if checkproxy('http://www.google.com') then
           Begin
                HTTPCon.ProxyParams.ProxyServer := SettingsForm.edtProxyServer.text;
                HTTPCon.ProxyParams.ProxyPort := StrToInt(SettingsForm.edtProxyPort.Text);
                HTTPCon.ProxyParams.BasicAuthentication := True;
                HTTPCon.ProxyParams.ProxyUsername := SettingsForm.edtProxyServer.Text;
                HTTPCon.ProxyParams.ProxyPassword := SettingsForm.edtProxyUserName.Text;
           End;
            Create another AntiFreeze - only 1/app 
           AntiFreeze := TIdAntiFreeze.Create(nil);
           AntiFreeze.Active := true;
           HTTPCon.Get(sURL,SStream);
           Result := UTF8ToWideString(SStream.DataString);
        Finally
           If Assigned(HTTPCon) then FreeAndNil(HTTPCon);
           If Assigned(AntiFreeze) then FreeAndNil(AntiFreeze);
           If Assigned(SStream) then FreeAndNil(SStream);
        End;
     Except
         Handle exceptions 
        On E:Exception do
           MessageDlg('Exception: '+E.Message,mtError, [mbOK], 0);
     End;
end;

function TForm1.checkproxy(sURL : ansistring) : boolean;
var
   HTTPCon : TIdHTTP;
   AntiFreeze : TIdAntiFreeze;
begin
     Result := False;
     Try
         Inti vars 
        AntiFreeze := NIL;
        HTTPCon := NIL;
        Try
            AntiFreeze 
           AntiFreeze := TIdAntiFreeze.Create(NIL);
           AntiFreeze.Active := true;
            Create & Set IdHTTP properties 
           HTTPCon := TIdHTTP.Create(NIL);
           HTTPCon.ProxyParams.ProxyServer := SettingsForm.edtProxyServer.text;
           HTTPCon.ProxyParams.ProxyPort := StrToInt(SettingsForm.edtProxyPort.Text);
           HTTPCon.ProxyParams.BasicAuthentication := True;
           HTTPCon.ProxyParams.ProxyUsername := SettingsForm.edtProxyServer.Text;
           HTTPCon.ProxyParams.ProxyPassword := SettingsForm.edtProxyUserName.Text;
           HTTPCon.HandleRedirects := true;
           HTTPCon.ConnectTimeout := 1000;
           HTTPCon.Request.Connection := 'close';
           HTTPCon.Head(sURL);
        Finally
            Cleanup 
           if Assigned(HTTPCon) then
           Begin
                 Return Success/Failure 
                Result := HTTPCon.ResponseCode = 200;
                If HTTPCon.Connected then HTTPCon.Disconnect;
                FreeAndNil(HTTPCon);
           End;
           if Assigned(AntiFreeze) then FreeAndNil(AntiFreeze);
        End;
     Except
        On E:EIdException do ;
         Handle exceptions 
        On E:Exception do
           MessageDlg('Exception: '+E.Message,mtError, [mbOK], 0);
     End;
end;

【讨论】:

我不敢相信我错过了!感谢您提供信息和代码。 -布拉德 不客气。第二双眼睛通常会看到第一双眼睛错过的东西!

以上是关于为啥这个检查代理有效性的代码会崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

如果我正在测试原因并绕过有问题的代码,为啥这个应用程序会崩溃?

为啥这个简单的 NSWindow 创建代码会在 ARC 下关闭时触发自动释放池崩溃?

为啥这个 angularjs ui-router 代码会使我的浏览器崩溃?

为啥我的代码会崩溃?

为啥这个应用程序在后台崩溃?

为啥这个程序会崩溃? [关闭]