我让人们使用HTTP从Yaws下载文件。我已经在yaws_appmod_dav.erl中实现了它,它工作得很好。
case file:read(Fd,PPS) of
{ok,Data} when size(Data)<PPS ->
?DEBUG("only chunk~n"),
status(200,H,{content,Mimetype,Data});
{ok,Data} ->
?DEBUG("first chunk~n"),
spawn(fun() -> deliver_rest(Pid,Fd) end),
status(200,H,{streamcontent,Mimetype,Data});
eof ->
status(200,{content,"application/octet-stream",<<>>});
{error,Reason} ->
Response = [{'D:error',[{'xmlns:D',"DAV:"}],[Reason]}],
status(500,{xml,Response})
end;
我想在服务器上标记一个成功的下载,即当客户机接受了最后一个包时。
我该怎么做?
一个小问题:在webdav-应用程序Yaws中,在获取文件时使用yaws_api:stream_chunk_deliver而不是yaws_api:stream_chunk_deliver_blocking。(见dav.erl中的第449行)
为什么这不成问题?根据http://yaws.hyber.org/stream.yaws,“每当流的生产者比使用者(即WWW客户端)更快时,我们就必须使用代码的同步版本。”我注意到这两个版本都很好,受影响的仅仅是服务器上的内存量吗?
发布于 2016-03-11 11:40:48
HTTP协议没有指定客户端通知服务器下载成功的方式。客户机要么获得由结果代码200
(或206
)确认的请求数据,要么没有,在这种情况下,它得到一个错误代码。然后客户端可以自由地重新请求数据。所以,没有一个可靠的方法来实现你想要的。
您可以记录最后一块数据已经发送到客户端的事实,并假设它已经成功,除非客户端重新请求该数据,在这种情况下,您可以使前面的假设无效。
另外,请注意,HTTP规范允许在向范围标头发送GET请求时从服务器请求数据的任何部分。请参阅此模糊-httpfs实现中的一个示例和该所以贴中的一些更多信息。如果您不知道使用范围标头的GET请求是最后一个(例如,客户端可以向后顺序下载整个文件),那么如何确定下载是否成功。
这也可能会回答你一些小问题。客户端通过从给定文件中请求指定的字节范围来控制流。我不知道WebDAV协议的实现,但是它可能不会立即请求整个文件,因此服务器可以以块的形式传递数据,并且不会溢出客户端。
HTTP报头与位于TCP协议级别的TCP窗口大小是独立的(HTTP是在TCP之上实现的应用程序级协议)。假设客户端请求整个文件,服务器就这样发送它。不是说整个文件已经通过网络发送了。要发送的数据将在内核中缓冲,并根据TCP窗口大小发送块。如果客户端只请求部分带有范围标头的数据,那么只有该部分将在内核中被缓冲。
https://stackoverflow.com/questions/35934074
复制相似问题