我想使用TIdHttp(Indy10)实现一个简单的http下载器.我从互联网上找到了两种代码示例.不幸的是,他们都没有100%满足我.这是代码,我想要一些建议.
变式1
var
Buffer: TFileStream;
HttpClient: TIdHttp;
begin
Buffer := TFileStream.Create('somefile.exe', fmCreate or fmShareDenyWrite);
try
HttpClient := TIdHttp.Create(nil);
try
HttpClient.Get('http://somewhere.com/somefile.exe', Buffer); // wait until it is done
finally
HttpClient.Free;
end;
finally
Buffer.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
代码紧凑,易于理解.问题是它在下载开始时分配磁盘空间.另一个问题是我们无法直接在GUI中显示下载进度,除非代码在后台线程中执行(或者我们可以绑定HttpClient.OnWork事件).
变式2:
const
RECV_BUFFER_SIZE = 32768;
var
HttpClient: TIdHttp;
FileSize: Int64;
Buffer: TMemoryStream;
begin
HttpClient := TIdHttp.Create(nil);
try
HttpClient.Head('http://somewhere.com/somefile.exe');
FileSize := HttpClient.Response.ContentLength;
Buffer := TMemoryStream.Create;
try
while Buffer.Size < FileSize do
begin
HttpClient.Request.ContentRangeStart := Buffer.Size;
if Buffer.Size + RECV_BUFFER_SIZE < FileSize then
HttpClient.Request.ContentRangeEnd := Buffer.Size + …Run Code Online (Sandbox Code Playgroud) 请解释一下如何使用SSL(https://)从服务器下载文件.我没有在互联网上找到合适的答案.
每个人都说TIdSSLIOHandlerSocket,但我只有TIdSSLIOHandlerSocketOpenSSL.如果我使用TIdSSLIOHandlerSocketOpenSSL,我有一个错误'无法加载SSL库'.有人说它需要一个图书馆,但最不提的是它.我是否需要使用http://www.indyproject.org/sockets/SSL.EN.aspx中的库?
我在程序的文件夹中有这些DLL.根据:http://edn.embarcadero.com/article/31279 "在运行时,Indy尝试加载libeay32.dll和ssleay32.dll." 我不知道Indy试图加载DDL的位置 - >我有一个错误:'无法加载SSL库.'
procedure TForm1.FormCreate(Sender: TObject);
var UpdateMemoryStream:tmemorystream;
begin
try
UpdateMemoryStream:=TMemoryStream.Create;
try
idhttp2.Get('https://example.com/list.rar',UpdateMemoryStream); //I have: Exception class EIdOSSLCouldNotLoadSSLLibrary with message 'Could not load SSL library.'
except
on E : Exception do
begin showmessage('Error: '+E.Message);
end;
end;
UpdateMemoryStream.SaveToFile('d:\1.rar');
finally
UpdateMemoryStream.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
为什么我有这个错误?我有Delphi 2010.
我正在使用idhttp(Indy)做一些网站检查.我想要它做的就是在我的请求发送后检查来自服务器的响应代码,我不想实际上必须从服务器接收HTML输出,因为我只监视200 OK代码,任何其他代码意味着存在某种形式的问题.
我查了idhttp帮助文档,我能看到的唯一方法就是将代码分配给a MemoryStream,然后立即清除它,但这不是很有效并且使用不需要的内存.有没有办法只是调用一个站点并获得响应,但忽略发回的HTML更高效,不浪费内存?
目前代码看起来像这样.然而,这只是我尚未测试的示例代码,我只是用它来解释我正在尝试做什么.
Procedure Button1Click(Sender: TObject);
var
http : TIdHttp;
s : TStream;
url : string;
code : integer;
begin
s := TStream.Create();
http := Tidhttp.create();
url := 'http://www.WEBSITE.com';
try
http.get(url,s);
code := http.ResponseCode;
ShowMessage(IntToStr(code));
finally
s.Free();
http.Free();
end;
Run Code Online (Sandbox Code Playgroud) 我正在 Delphi 中编写一个下载管理器,其中包含一些自定义功能,例如可恢复下载和通过代理下载。
我正在研究不同的组件解决方案:Indy 和 NetHTTP,两者看起来非常接近。
TNetHTTPClient好像是 的接口winhttp.dll。
TIdHTTP似乎是wininet.dll(但我不确定)的接口。
TIdHTTP 似乎是一个非常古老的组件(可能非常稳定/经过测试)并且有大量在线文档。
TNetHTTPClient 似乎是一个非常新的组件,并且没有很好的在线文档。
我有点犹豫……该选择哪一个?
关键是:这两个组件之间的主要区别是什么?
我的问题有点有争议(主要基于意见),但我还没有找到这两个组件之间的任何实际比较。
我发现在为TIdHTTP组件设置ConnectTimeoout属性时,它会使请求(GET和POST)变得慢约120ms?
为什么会这样,我可以以某种方式避免/绕过这个吗?
环境:D2010发布的Indy组件,为D2010安装了所有更新.操作系统是WinXP(32位)SP3,大多数补丁......
我的计时程序是:
Procedure DoGet;
Var
Freq,T1,T2 : Int64;
Cli : TIdHTTP;
S : String;
begin
QueryPerformanceFrequency(Freq);
Try
QueryPerformanceCounter(T1);
Cli := TIdHTTP.Create( NIL );
Cli.ConnectTimeout := 1000; // without this we get < 15ms!!
S := Cli.Get('http://127.0.0.1/empty_page.php');
Finally
FreeAndNil(Cli);
QueryPerformanceCounter(T2);
End;
Memo1.Lines.Add('Time = '+FormatFloat('0.000',(T2-T1)/Freq) );
End;
Run Code Online (Sandbox Code Playgroud)
在代码中设置ConnectTimeout,我得到了平均值.130-140ms的时间,没有它约5-15ms ......
我使用TidHTTP + TIdSSLIOHandlerSocketOpenSSL + 2 DLL:来自http://indy.fulgan.com/SSL的 ssleay32.dll和libeay32.dll .
但我可以在HTTP Analyzer中看到我的程序的所有工作!它可以用作HTTP,而不是HTTPS.如果我使用Opera,我看不到使用相同网站下载(https://esta.cbp.dhs.gov/esta).
我没有为TidHTTP和TIdSSLIOHandlerSocketOpenSSL设置任何特殊参数(可能是我必须但我不知道到底是什么).
我必须使用TIdSSLVersion(sslvSSLv23)+ SSL证书的位置吗?我在哪里可以获得此证书?还是只有RootCertFile?
如何将idHttp的端口更改为443(我必须这样做吗?)?
我用:
procedure TForm1.FormCreate(Sender: TObject);
var mem:tmemorystream;
begin
try
mem:=TMemoryStream.Create();
try
idhttp1.Get('https://esta.cbp.dhs.gov/esta/',Mem);
except
on E : Exception do ShowMessage(E.Message);
end;
finally
mem.Free;
idhttp1.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
请参阅我的视频:http://liga-installer.realservers.info/ssl.mp4
截屏:

谢谢谢谢你的帮助!
我使用delphi和python实现了相同的代码(发布表单).python代码运行完美,但delphi代码失败.在python中,我可以简单地写httplib2.debuglevel=4一下,看看实际发送到服务器的内容是什么.但我不知道如何在delphi中打印内容.
def python_request_data(url, cookie, data):
httplib2.debuglevel = 4
conn = httplib2.Http()
conn.follow_all_redirects = True
headers = {'Cookie': cookie, 'Content-Type': 'application/x-www-form-urlencoded'}
response, contents = conn.request(url, 'POST', data, headers=headers)
procedure DelphiRequestData(const Url, Cookie, Data: string);
var
Client: TIdHttp;
Params: TStringList;
Response: string;
begin
Client := TIdHttp.Create(nil);
try
Client.HTTPOptions := [hoKeepOrigProtocol];
Client.Request.CustomHeaders.AddValue('Cookie', Cookie);
Params := TStringList.Create;
try
Params.QuoteChar := #0;
Params.Delimiter := '&';
Params.DelimiterText := Data;
Client.Request.ContentType := 'application/x-www-form-urlencoded';
Client.Request.ContentLength := Length(Params.DelimitedText);
Response := Client.Post(Url, Params);
finally
Params.Free;
end;
finally
Client.Free; …Run Code Online (Sandbox Code Playgroud) 我正在使用Indy(idHTTP)从Internet下载EXE文件,我可以使用memorystream或filestream将其保存到磁盘,但我真的不知道它们之间是否有任何区别(可能在文件的结果结构中? ).我找不到答案.
这里有两个简单的函数来模拟我在做什么:
Function DownloadMS(FUrl, Dest: String): Boolean;
var
Http: TIdHTTP;
Strm: TMemoryStream;
Begin
Result := False;
Http := TIdHTTP.Create;
Strm := TMemoryStream.Create;
With Http, Strm Do
Try
Try
Get(FUrl, Strm);
If (Size > 0) Then
Begin
Position := 0;
SaveToFile(Dest);
Result := True;
end;
Except
end;
Finally
Strm.Free;
Http.Free;
end;
end;
Function DownloadFS(FUrl, Dest: String): Boolean;
var
Http: TIdHTTP;
Strm: TFileStream;
Begin
Result := False;
Http := TIdHTTP.Create;
Strm := TFileStream.Create(Dest, fmCreate);
With Http, Strm Do
Try
Try
Get(FUrl, …Run Code Online (Sandbox Code Playgroud) 采取以下情况:
procedure Test;
var
Response : String;
begin
Response := IdHttp.Post(MyUrL, AStream);
DoSomethingWith(Response);
end;
Run Code Online (Sandbox Code Playgroud)
现在,web服务器以UTF-8返回数据.假设它返回一些包含字符é的 UTF-8 XML .如果我使用变量Response它不包含这个字符,但它是UTF-8变种(#C3#A9),所以Indy没有解码?
现在我知道如何解决这个问题:
procedure Test;
var
Response : String;
begin
Response := UTF8ToString(IdHttp.Post(MyUrL, AStream));
DoSomethingWith(Response);
end;
Run Code Online (Sandbox Code Playgroud)
这个解决方案的一个警告:Delphi引发警告W1058(隐式字符串转换,潜在的数据丢失从'string'到'RawByteString')
我的问题:这是处理这个问题的正确方法,还是我可以指示TIdHTTP为我转换为UnicodeString?
我正在尝试使用Indy HTTP类进行HTTP身份验证.但由于某些未知原因,我在此行中收到了访问冲突错误: IdHTTP1.Request.Authentication.Username:= Username;
代码延伸是:
IdHTTP1:= TIdHttp.Create(Application);
IdHTTP1.ConnectTimeout:= 10000;
IdHTTP1.Request.Clear;
IdHTTP1.Request.BasicAuthentication:= true;
IdHTTP1.Request.Authentication.Username := Username;
IdHTTP1.Request.Authentication.Password := Password;
try
IdHTTP1.Get(PbxURL);
HttpCode := IdHTTP1.ResponseCode;
except
on E: EIdHTTPProtocolException do
HttpCode := IdHTTP1.ResponseCode;
Run Code Online (Sandbox Code Playgroud)
我正在使用Delphi 2010,并且已经尝试过如下操作: IdHTTP1.Request.Authentication.Username:='admin'; 但没有解决问题......
delphi ×10
idhttp ×10
indy ×8
ssl ×2
debugging ×1
delphi-2010 ×1
delphi-xe ×1
download ×1
filestream ×1
http ×1
memorystream ×1
unicode ×1
utf-8 ×1