我有自己的运行 lighttpd 的服务器。当我通过我的标准/常规互联网连接在笔记本电脑上使用“curl -I ...”查看标头时,我得到了以下信息:
HTTP/1.1 200 OK
Content-Type: application/zip
ETag: "546653951"
Last-Modified: Wed, 08 May 2013 15:35:42 GMT
Content-Length: 28166067
Date: Wed, 08 May 2013 19:07:36 GMT
Server: lighttpd/1.4.28
当我将笔记本电脑切换到手机连接(wifi热点)时,我在完全相同的终端中对完全相同的服务器运行完全相同的命令,我得到了以下结果:
HTTP/1.1 200 OK
Content-Type: application/zip
Accept-Ranges: bytes
ETag: "546653951"
Last-Modified: Wed, 08 May 2013 15:35:42 GMT
Content-Length: 28166067
Date: Wed, 08 May 2013 19:09:23 GMT
Server: lighttpd/1.4.28
请注意,“Accept-Ranges:bytes”在第二种情况下存在,但在第一种情况下不存在。
这可能是什么原因造成的?我迫切需要这个暂停/恢复功能,我记得我的连接上一直没有这个功能,只是从来没有调查过为什么(不仅仅是我自己的服务器,还有任何我想要下载的服务器/文件)...从我可以访问的另一台计算机上,运行相同的 curl 命令显示 Accept-Ranges: bytes 存在,所以我假设我家里的常规 ISP 出了问题。
网络硬件会导致这种情况吗?可能是路由器/交换机不兼容?或者是 ISP 本身的问题?
有什么想法吗?
根据 Dennis 的要求,输出如下:
echo > tempfile; wget -d -c -O tempfile redtwitz.com
Setting --continue (continue) to 1
Setting --output-document (outputdocument) to tempfile
DEBUG output created by Wget 1.13.4 on linux-gnu.
URI encoding = `UTF-8'
--2013-05-10 12:20:48-- http://redtwitz.com/
Resolving redtwitz.com (redtwitz.com)... 184.22.37.72
Caching redtwitz.com => 184.22.37.72
Connecting to redtwitz.com (redtwitz.com)|184.22.37.72|:80... connected.
Created socket 4.
Releasing 0x00000000013d1310 (new refcount 1).
---request begin---
GET / HTTP/1.1
Range: bytes=1-
User-Agent: Wget/1.13.4 (linux-gnu)
Accept: */*
Host: redtwitz.com
Connection: Keep-Alive
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.1 200 OK
Date: Fri, 10 May 2013 16:21:56 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Thu, 02 Aug 2012 13:41:17 GMT
ETag: "a819c40-d-4c64890da1940"
Content-Length: 13
Vary: Accept-Encoding
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html
---response end---
200 OK
Registered socket 4 for persistent reuse.
Length: 13 [text/html]
Saving to: `tempfile'
100%[================================================================>] 13 --.-K/s in 0s
2013-05-10 12:20:49 (783 KB/s) - `tempfile' saved [13/13]
more tempfile
edtwitz.com
答案1
RFC2616“超文本传输协议--HTTP/1.1”,第14.5节:
14.5 Accept-Ranges Accept-Ranges 响应标头字段允许服务器指示其接受对资源的范围请求:
Accept-Ranges = "Accept-Ranges" ":" acceptable-ranges acceptable-ranges = 1#range-unit | "none"
接受字节范围请求的源服务器可能会发送
Accept-Ranges: bytes
但不要求这样做。客户端可以在未收到所涉及资源的此标头的情况下生成字节范围请求。范围单位定义在第 3.12 节中。
不接受任何资源范围请求的服务器可能会发送
Accept-Ranges: none
建议客户端不要尝试范围请求。
简而言之,这是远程服务器告诉你的 UA,它只愿意接受部分资源的请求,如RFC2616 第 14.35 节。由于这是实现恢复失败下载的机制,因此看到Accept-Ranges
服务器响应中的标头实际上是一个好兆头,表明您能够在此处完成您的目标。
事实上,curl
似乎实现了这种能力,如下所述这里;该命令的两种形式为:
cat file-that-failed-to-download.zip | curl -C - http://www.somewhere.com/file-I-want-to-download.zip >successfully-downloaded.zip
和
curl -C - -o partially_downloaded_file 'www.example.com/path/to/the/file'
在我看来,这两种形式应该或多或少表现相同,但我都没有尝试过,所以不能确定。假设 Curl 的行为与宣传的一致,那么每次需要恢复下载时,您应该能够简单地重新发出相同的命令(可能略有修改,就像在第一种形式中需要更改文件名一样),然后 Curl 将检查您迄今为止下载的内容并发出Range
仅指定文件中剩余字节的标头。
至于为什么您在原始请求的响应中看不到Accept-Ranges
标头,也许服务器具有某种状态性,这样它就可以识别出您的 UA 对相同资源的第二个请求,并有帮助地包含标Accept-Ranges
头以确保您的 UA 知道尝试恢复下载会成功。 无论如何,这不应该特别重要;根据上面的 RFC 引用,您的客户端可以(在没有Accept-Ranges: none
来自服务器的预先存在的标头的情况下)发出字节范围请求,无论它是否已经看到标Accept-Ranges
头,并且确实不需要在任何情况下在第一个请求上指定范围,因为它试图下载整个资源而不是其中的一部分。