咳,放血疗法,300分 : 如何用TidHttpServer实现IIS的限制下载速度功能?(300分)

  • 主题发起人 主题发起人 千中元
  • 开始时间 开始时间

千中元

Unregistered / Unconfirmed
GUEST, unregistred user!
我很关注
 
idHttpServer
能不能对客户端的post请求返回数据呢?
 
to coolbaby :
当然可以。
 
这个功能估计TidHttpServer是实现不了的.等以后有时间研究协议本身后再实现吧.

改题目如下:
TidHttpServer的Demo运行后,如果是输入http://169.12.X.X/A.html
可以在浏览器中看到该网页,如果请求一个文件类似http://169.12.X.X/A.rar
这样的文件,则在浏览器中给你解析了A.rar文件,出现一片乱码.而我想实现的
功能却是下载 A.rar.
 
对于修改后题目,是ContentType未设置。
请在HTTPServer的OnCommandGet事件中
语句
ByteSent := HTTPServer.ServeFile(AThread, ResponseInfo, LocalDoc);
前插入:
ResultFile := TFileStream.create(LocalDoc, fmOpenRead or
fmShareDenyWrite);
try
ResponseInfo.ContentType := GetMIMEType(LocalDoc);
finally
ResultFile.Free;
// We must free this file since it won't be done by the web server component
end;
 
kyq兄,
不知道你测试了没有.我现在用的代码和你上面一样.
访问网页可以,但是其他比如 .zip,rar等文件,出现的是乱码.
我的原意是支持下载文件
 
已经测试通过了。
关掉当前IE,开一个新的IE在测试一下,以防IE缓冲。
 
也就是Demo中的代码了,我这里到另一台机器上开IE都不能通过测试,问题和
以前所说一样:

if AnsiSameText(RequestInfo.Command, 'HEAD') then
begin
ResultFile := TFileStream.create(LocalDoc, fmOpenRead or
fmShareDenyWrite);
try
ResponseInfo.ResponseNo := 200;
ResponseInfo.ContentType := GetMIMEType(LocalDoc);
ResponseInfo.ContentLength := ResultFile.Size;
finally
ResultFile.Free;
end;
ByteSent := HTTPServer.ServeFile(AThread, ResponseInfo, LocalDoc);
 
千中元就是千中元,我来学习.
up
 
问题一: "TidHttpServer实现IIS的限制下载速度"
TIdHttpServer是用于实现一个独立的HTTP Server吧, 既然独立, 又何谈"IIS的限制下载"
呢? ----对不起, 我从来不用Indy的控件, 所以, 也许它是实现Filter的, 也未为可知. ^0^

问题二:
如果是独立的HTTP Server, 那么, 所有的HTTP协议通道都是由你控制的, 这样, 向客户端
通告"能/不能"下载就是很容易做到的了. 但问题是, 如何通告客户端什么时候再次下载?
其实很容易了, 发一个"refresh"标头就可以了.
这个只是一个想法, 我并没有试过. 目前, 还没有时间来测试它. 哈哈.

问题之三:
由于客户端对服务器端的请求是未知的, 我们除了通过延时控制它的下载速度之外, 还可通
过数据块的大小来控制下载速度. 也就是说, 如果客户端的请求是一个文件, 我们发送的返
回标头可以是Context-Length=1M, 而返Body区却只有0字节, 这样, 客户将不得不重复请求
来得到更多的数据块. 这样也可以使流量得到控制.

问题之四:
这是你需要考虑的, 如何对同一用户的多个连接进行识别, 单独的限速是没有多大意思的,
你必须考虑连接数限制. ^-^


其它
-----------
事实上, 最近我们公司也有计划开发一个类似的产品, 当然不是用IdHttpServer, 而是用
ISAPI Filter载入到IIS内部来控制IIS的连接和流量. 上面的其实也是我对这个产品的一
些尚不成熟, 未经测试的想法.
供参考先. ^-^
 
"则在浏览器中给你解析了A.rar文件,出现一片乱码.而我想实现的功能却是下载 A.rar."
----这个问题是由于返回的mime标识为浏览器不识别所导致的. 在accept标头中处理即可.
 
TidHttpServer实现 IIS的限制下载速度功能
---这样表达容易引起歧义,我的本意是:自己的Web Server可以有限制下载速度的
功能,就像IIS一样。

不过ok,这个先不考虑。

function DocumentToContentType(FileName : String) : String;
var
Ext : String;
begin
{ We probably should the registry to find MIME type for known file types }
Ext := LowerCase(ExtractFileExt(FileName));
if Length(Ext) > 1 then
Ext := Copy(Ext, 2, Length(Ext));
if (Ext = 'htm') or (Ext = 'html') then
Result := 'text/html'
else if Ext = 'gif' then
Result := 'image/gif'
else if Ext = 'bmp' then
Result := 'image/bmp'
else if (Ext = 'jpg') or (Ext = 'jpeg') then
Result := 'image/jpeg'
else if Ext = 'txt' then
Result := 'text/plain'
else
Result := 'application/x-zip-compressed';
end;

在OnCommandGet中:
AResponseInfo.ContentType := DocumentToContentType(LocalDoc);

仍然不能认得是什么文件。

初次做这样的程序,请问:
在accept标头中处理即可 什么意思?有没有处理该标头的Demo?
 
关于标头处理, 给你一个工具, 你自己分析吧. :)
你用它可以看到IIS或其它Web服务器端返回时的全部的头信息, 你在IndyServer返回的
头模拟一个就可以了. :)

http://www.concentric.net/~Sstmail/httptracer.zip
注册可以试试这个:
Name : ForYou
Pass : 25293134323532343129
 
To 千中元:
1. 你代码中的
if (Ext = 'htm') or (Ext = 'html') then等应该改为
if (Ext = '.htm') or (Ext = '.html') then

2. 可能是我表达得不清楚,我的意思是Demo中代码改为
if AnsiSameText(RequestInfo.Command, 'HEAD') then
begin
// HEAD request, don't send the document but still send back it's size
ResultFile := TFileStream.create(LocalDoc, fmOpenRead or
fmShareDenyWrite);
try
ResponseInfo.ResponseNo := 200;
ResponseInfo.ContentType := GetMIMEType(LocalDoc);
ResponseInfo.ContentLength := ResultFile.Size;
finally
ResultFile.Free;
// We must free this file since it won't be done by the web server component
end;
end
else
begin

// Normal document request
// Send the document back
////////////////////////////////////////////////////////////////////////////////////
ResultFile := TFileStream.create(LocalDoc, fmOpenRead or
fmShareDenyWrite);
try
ResponseInfo.ContentType := GetMIMEType(LocalDoc);
finally
ResultFile.Free;
// We must free this file since it won't be done by the web server component
end;
////////////////////////////////////////////////////////////////////////////
ByteSent := HTTPServer.ServeFile(AThread, ResponseInfo, LocalDoc);
DisplayMessage(Format('Serving file %s (%d bytes / %d bytes sent) to %s:%d',
[LocalDoc, ByteSent, FileSizeByName(LocalDoc),
AThread.Connection.Binding.PeerIP,
AThread.Connection.Binding.PeerPort]));
end;
 
To 千中元:
Sorry, 第1点我收回,看错了。

这函数逻辑是正确的,
ResponseInfo.ContentType := DocumentToContentType(LocalDoc);
放在ByteSent := HTTPServer.ServeFile(AThread, ResponseInfo, LocalDoc);前
就应该可以了。已经测试通过。
 
你把我拉过来想帮你一把吗?嘿嘿,我最近也正为这些东西感到有些迷惑呢,
我倒得先谢谢你了[:)]
 
大家讨论差不多了? 签到吧
 
类型是看标识头,但是进行什么操作是自己控制的。。。

是显示,还是下载保存。。。由自己控制。。。
 
后退
顶部