为啥这个检查代理有效性的代码会崩溃?
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 下关闭时触发自动释放池崩溃?