【问题标题】:how to resume an interrupted download - part 2如何恢复中断的下载 - 第 2 部分
【发布时间】:2011-03-26 13:55:28
【问题描述】:

这是我在不是注册用户时发布的my previous question 的延续。作为复习,我正在尝试从我的 Yahoo! 继续下载一个大文件!下载中断时的网站服务器。我以前认为中断是由于 100 秒的超时限制(因为 Yahoo! 对用户编写的脚本强制执行该时间限制)。然而,当我测量下载中断的时间时,我发现中断时间变化很大(有时下载运行不间断的时间不到 100 秒,有时长达 7 分钟)。所以我不知道超时的原因,我只是想解决它们。

我尝试了naikus 的建议(谢谢),根据 http 标头字段的转储,我的 Yahoo!网站服务器确实识别了“范围”属性,该属性应该允许下载在中断的偏移处恢复。不幸的是,尽管字节范围在恢复连接的 http 标头中显示正确,但传输的内容总是在文件开头重新开始。 (我的测试文件是一个由 50,000 个 4 字节整数组成的数组,从 0 开始递增。我下载的文件总是在发生下载中断的每个偏移量处从 0 开始重新计数。)

我是否应该提出其他一些 http 连接属性请求来获取 Yahoo!服务器实际跳转到在标头的字节范围中指定的文件偏移量?这是代码及其转储的内容:

         // Setup connection.
         URL url = new URL(strUrl[0]);
         URLConnection connection = url.openConnection();
         downloaded = Integer.parseInt(strUrl[3]);
         if (downloaded > 0) {
             connection.setRequestProperty("Range", "bytes="+downloaded+"-");
             connection.connect();
             fileLength = mDownloadFileLength;
             Log.d("AsyncDownloadFile", 
                 "new download seek: " + downloaded +
                 "; lengthFile: " + fileLength);
         }
         else {
             connection.connect();
             downloaded = 0;
             fileLength = connection.getContentLength();
             mDownloadFileLength = fileLength;
         }
         Map<String, List<String>> map = connection.getHeaderFields();
         Log.d("AsyncDownloadFile", "header fields: " + map.toString());

         // Setup streams and buffers.
         input = new BufferedInputStream(url.openStream(), 8192);
         outFile = new RandomAccessFile(strUrl[1], "rw");
         if (downloaded > 0)  
             outFile.seek(downloaded);
         byte data[] = new byte[1024];

         // Download file.
         for (int count=0, i=0; (count=input.read(data, 0, 1024)) != -1; i++) { 
             outFile.write(data, 0, count);
             downloaded += count; 
             if (downloaded >= fileLength)
                 break;

             // Display progress.
             Log.d("AsyncDownloadFile", "bytes: " + downloaded);
             if ((i%10) == 0)
                 publishProgress((int)(downloaded*100/fileLength));
             if (mFlagDisableAsyncTask) {
                 downloaded = 0;
                 break;
             }
         }

         // Close streams.
         outFile.close();
         input.close();

转储:

@ 4:08:24  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[2000000], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:08:33 GMT]}  
D/AsyncDownloadFile( 2372): bytes: 1024  
D/AsyncDownloadFile( 2372): bytes: 1033  
D/AsyncDownloadFile( 2372): bytes: 2057  
D/AsyncDownloadFile( 2372): bytes: 2493  
D/AsyncDownloadFile( 2372): bytes: 3517  
D/AsyncDownloadFile( 2372): bytes: 3953  

.
.
.

@ 4:13:25  
D/AsyncDownloadFile( 2372): bytes: 386473  
D/AsyncDownloadFile( 2372): bytes: 387497  
D/AsyncDownloadFile( 2372): bytes: 387933  
D/AsyncDownloadFile( 2372): new download seek: 387933; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1612067], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:13:29 GMT], co
ntent-range=[bytes 387933-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 388957  
D/AsyncDownloadFile( 2372): bytes: 389981  
D/AsyncDownloadFile( 2372): bytes: 390409  
D/AsyncDownloadFile( 2372): bytes: 391433  
D/AsyncDownloadFile( 2372): bytes: 391869  
D/AsyncDownloadFile( 2372): bytes: 392893  

.
.
.

@ 4:18:45  
D/AsyncDownloadFile( 2372): bytes: 775413  
D/AsyncDownloadFile( 2372): bytes: 775849  
D/AsyncDownloadFile( 2372): bytes: 776873  
D/AsyncDownloadFile( 2372): bytes: 777309  
D/AsyncDownloadFile( 2372): new download seek: 777309; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1222691], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:18:54 GMT], co
ntent-range=[bytes 777309-1999999/2000000]}  
D/dalvikvm( 2372): GC_FOR_MALLOC freed 11019 objects / 470560 bytes in 155ms  
D/AsyncDownloadFile( 2372): bytes: 778333  
D/AsyncDownloadFile( 2372): bytes: 779357  
D/AsyncDownloadFile( 2372): bytes: 779790  
D/AsyncDownloadFile( 2372): bytes: 780814  
D/AsyncDownloadFile( 2372): bytes: 781250  
D/AsyncDownloadFile( 2372): bytes: 782274  

.
.
.

@ 4:23:45  
D/AsyncDownloadFile( 2372): bytes: 1163334  
D/AsyncDownloadFile( 2372): bytes: 1163770  
D/AsyncDownloadFile( 2372): bytes: 1164794  
D/AsyncDownloadFile( 2372): bytes: 1165230  
D/AsyncDownloadFile( 2372): new download seek: 1165230; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[834770], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:23:47 GMT], con
tent-range=[bytes 1165230-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 1166246  
D/AsyncDownloadFile( 2372): bytes: 1167270  
D/AsyncDownloadFile( 2372): bytes: 1167706  
D/AsyncDownloadFile( 2372): bytes: 1168730  
D/AsyncDownloadFile( 2372): bytes: 1169754  
D/AsyncDownloadFile( 2372): bytes: 1170778  

.
.
.

@ 4:30:25  
D/AsyncDownloadFile( 2372): bytes: 1551255  
D/AsyncDownloadFile( 2372): bytes: 1551691  
D/AsyncDownloadFile( 2372): bytes: 1552715  
D/AsyncDownloadFile( 2372): bytes: 1553151  
D/AsyncDownloadFile( 2372): new download seek: 1553151; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[446849], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:30:44 GMT], con
tent-range=[bytes 1553151-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 1554167  
D/AsyncDownloadFile( 2372): bytes: 1554184  
D/AsyncDownloadFile( 2372): bytes: 1555208  
D/AsyncDownloadFile( 2372): bytes: 1555644  
D/AsyncDownloadFile( 2372): bytes: 1556668  
D/AsyncDownloadFile( 2372): bytes: 1557104  

.
.
.

@ 4:37:10  
D/AsyncDownloadFile( 2372): bytes: 1939188  
D/AsyncDownloadFile( 2372): bytes: 1939624  
D/AsyncDownloadFile( 2372): bytes: 1940648  
D/AsyncDownloadFile( 2372): bytes: 1941084  
D/AsyncDownloadFile( 2372): new download seek: 1941084; lengthFile: 2000000  
D/dalvikvm( 2372): GC_FOR_MALLOC freed 13701 objects / 604600 bytes in 128ms
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[58916], age=[0], server=
[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:37:16 GMT], cont
ent-range=[bytes 1941084-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 1942108  
D/AsyncDownloadFile( 2372): bytes: 1942117  
D/AsyncDownloadFile( 2372): bytes: 1943141  
D/AsyncDownloadFile( 2372): bytes: 1943577  
D/AsyncDownloadFile( 2372): bytes: 1944601  
D/AsyncDownloadFile( 2372): bytes: 1945037  

.
.
.

@ 4:38:30  
D/AsyncDownloadFile( 2372): bytes: 1993217  
D/AsyncDownloadFile( 2372): bytes: 1994241  
D/AsyncDownloadFile( 2372): bytes: 1994677  
D/AsyncDownloadFile( 2372): bytes: 1995701  
D/AsyncDownloadFile( 2372): bytes: 1996137  
D/AsyncDownloadFile( 2372): bytes: 1997161  
D/AsyncDownloadFile( 2372): bytes: 1997597  
D/AsyncDownloadFile( 2372): bytes: 1998621  
D/AsyncDownloadFile( 2372): bytes: 1999057  
D/onPostExecute( 2372): download: unsuccessful  

- - -  

根据 BalusC 的提示(谢谢),我修改了连接设置,但 Yahoo!服务器在每次中断时继续重置到文件的开头。这是更改后的代码和生成的转储:

            // Setup connection.
            URL url = new URL(strUrl[0]);
            URLConnection connection = url.openConnection();
            downloaded = Integer.parseInt(strUrl[3]);
            if (downloaded == 0) {
                connection.connect();
                strLastModified = connection.getHeaderField("Last-Modified");
                fileLength = connection.getContentLength();
                mDownloadFileLength = fileLength;
            }
            else {
                connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
                connection.setRequestProperty("If-Range", strLastModified);
                connection.connect();
                fileLength = mDownloadFileLength;
                Log.d("AsyncDownloadFile", 
                        "new download seek: " + downloaded +
                        "; lengthFile: " + fileLength);
            }
            map = connection.getHeaderFields();
            Log.d("AsyncDownloadFile", "header fields: " + map.toString());

转储:

@12:36:40 started  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.c
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTP
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA P
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-m
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[2000000], age=[0], serv
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:36:56 GMT]}  
D/AsyncDownloadFile(  413): bytes: 1024  
D/AsyncDownloadFile(  413): bytes: 2048  
D/AsyncDownloadFile(  413): bytes: 2476  
D/AsyncDownloadFile(  413): bytes: 3500  
D/AsyncDownloadFile(  413): bytes: 3936  

...

@12:39:20 interrupted  
D/AsyncDownloadFile(  413): bytes: 388068  
D/AsyncDownloadFile(  413): bytes: 389092  
D/AsyncDownloadFile(  413): bytes: 389376  
D/AsyncDownloadFile(  413): new download seek: 389376; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1610624], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:39:21 GMT], co
ntent-range=[bytes 389376-1999999/2000000]}  
D/AsyncDownloadFile(  413): bytes: 390400  
D/AsyncDownloadFile(  413): bytes: 390409  
D/AsyncDownloadFile(  413): bytes: 391433  
D/AsyncDownloadFile(  413): bytes: 391869  

...

@12:44:10 interrupted  
D/AsyncDownloadFile(  413): bytes: 775413  
D/AsyncDownloadFile(  413): bytes: 775849  
D/AsyncDownloadFile(  413): bytes: 776873  
D/AsyncDownloadFile(  413): bytes: 777309  
D/AsyncDownloadFile(  413): new download seek: 777309; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1222691], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:44:20 GMT], co
ntent-range=[bytes 777309-1999999/2000000]}  
D/dalvikvm(  413): GC_FOR_MALLOC freed 10869 objects / 465664 bytes in 122ms  
D/AsyncDownloadFile(  413): bytes: 778333  
D/AsyncDownloadFile(  413): bytes: 778342  
D/AsyncDownloadFile(  413): bytes: 779366  
D/AsyncDownloadFile(  413): bytes: 779802  

...

@12:49:30 interrupted  
D/AsyncDownloadFile(  413): bytes: 1163782  
D/AsyncDownloadFile(  413): bytes: 1164806  
D/AsyncDownloadFile(  413): bytes: 1165242  
D/AsyncDownloadFile(  413): new download seek: 1165242; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[834758], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:49:43 GMT], con
tent-range=[bytes 1165242-1999999/2000000]}  
D/AsyncDownloadFile(  413): bytes: 1166266  
D/AsyncDownloadFile(  413): bytes: 1167290  
D/AsyncDownloadFile(  413): bytes: 1167718  
D/AsyncDownloadFile(  413): bytes: 1168742  

...

@12:55:30 interrupted  
D/AsyncDownloadFile(  413): bytes: 1552722  
D/AsyncDownloadFile(  413): bytes: 1553158  
D/AsyncDownloadFile(  413): bytes: 1554182  
D/AsyncDownloadFile(  413): bytes: 1554618  
D/AsyncDownloadFile(  413): new download seek: 1554618; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[445382], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:55:39 GMT], con
tent-range=[bytes 1554618-1999999/2000000]}  
D/AsyncDownloadFile(  413): bytes: 1555642  
D/AsyncDownloadFile(  413): bytes: 1556666  
D/AsyncDownloadFile(  413): bytes: 1557094  
D/AsyncDownloadFile(  413): bytes: 1558118  

...

@12:57:20 interrupted  
D/AsyncDownloadFile(  413): bytes: 1941834  
D/AsyncDownloadFile(  413): bytes: 1942858  
D/AsyncDownloadFile(  413): bytes: 1943882  
D/AsyncDownloadFile(  413): bytes: 1943994  
D/AsyncDownloadFile(  413): new download seek: 1943994; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[56006], age=[0], server=
[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:57:15 GMT], cont
ent-range=[bytes 1943994-1999999/2000000]}  
D/dalvikvm(  413): GC_FOR_MALLOC freed 13617 objects / 602200 bytes in 165ms  
D/AsyncDownloadFile(  413): bytes: 1945018  
D/AsyncDownloadFile(  413): bytes: 1946042  
D/AsyncDownloadFile(  413): bytes: 1946470  
D/AsyncDownloadFile(  413): bytes: 1947494  

...

@12:58:10 finished  
D/AsyncDownloadFile(  413): bytes: 1996103  
D/AsyncDownloadFile(  413): bytes: 1997127  
D/AsyncDownloadFile(  413): bytes: 1997563  
D/AsyncDownloadFile(  413): bytes: 1998587  
D/AsyncDownloadFile(  413): bytes: 1999023  
D/onPostExecute(  413): downloaded: unsuccessful  

【问题讨论】:

标签: java android http download


【解决方案1】:

要恢复下载,您不仅需要发送Range 请求标头,还需要发送If-Range 请求标头,其中应包含唯一文件标识符或文件修改时间戳。

如果服务器在初始下载时返回 ETag 响应标头,那么您应该在后续恢复请求的 If-Range 标头中使用它。或者如果它返回一个Last-Modified 响应头,那么你应该在If-Range 请求头中使用它。

查看您的日志,服务器已发送Last-Modified 响应标头。所以你应该在简历请求的If-Range 标头中将其发送回去。

// Initial download.
String lastModified = connection.getHeaderField("Last-Modified");

// ...

// Resume download.
connection.setRequestProperty("If-Range", lastModified); 

服务器将使用此信息来验证您请求的文件是否完全相同。

【讨论】:

  • 感谢您的建议。一时兴起,我还尝试将下载的文件名的扩展名从 .zip(即 content-type=[application/zip])更改为 .dat(即 content-type=[application/octet-stream]),然后我尝试将请求属性键更改为小写。不幸的是,雅虎!服务器继续在文件开头恢复下载。
  • 无济于事,我也尝试更改 connection.setRequestProperty("Range", "bytes="+downloaded+"-"); to connection.setRequestProperty("Range", "bytes=-"+(mDownloadFileLength - 已下载));
  • 我收到了来自 Yahoo! 的回复技术支持说,雅虎!服务器不支持字节范围请求:“Yahoo!虚拟主机不支持接受范围标头,因为我们使用服务器池并且每个请求都可能到达不同的服务器。您将在响应标头中看到 connection=[close] 指示这个。”
  • 使用If-Range时一定要检查状态码。当 If-Range 的值无法识别时,服务器可能会返回带有 full 响应(忽略您请求的范围)而不是 206 Partial Content200 OK
  • @BalusC 你能帮我解决这个问题吗:stackoverflow.com/q/45324253/1830228 在此先感谢
【解决方案2】:

好像问题来了

input = new BufferedInputStream(url.openStream(), 8192);

而不是

input = new BufferedInputStream(connection.getInputStream(), 8192);

url.openStream() 再次调用openConnection() 没有 range 属性。

【讨论】:

    【解决方案3】:

    我设法在我的客户端 Java 应用程序上实现 http 恢复下载,技巧是使用已接受答案中提到的“If-Range:original_ETag”请求标头。这是完整的标头调试信息,它可以帮助您了解简历的工作原理。

    服务器正常回复,文件从头到尾读取。 ETag 值是来自磁盘文件的 W/“filesize_bytes-modified_utc”元数据。它可能是其他东西,但这就是 Tomcat 使用的,通常最适合常规文件内容。

    HTTP/1.1 200 OK 
    ETag: W/"19097900-1410863319978" 
    Last-Modified: Tue, 16 Sep 2014 10:28:39 GMT 
    Content-Length: 19097900 
    Content-Type: application/octet-stream 
    Accept-Ranges: bytes 
    Server: Apache-Coyote/1.1 
    Date: Wed, 17 Sep 2014 10:39:52 GMT 
    

    客户端通过添加 Range 和 If-Range 标头从文件中读取给定的块。字节范围可以打开,因此服务器应该从给定索引开始读取到末尾。注意 Content-Length 不是文件的总长度,而是这块字节。

    Range: bytes=10000000-
    If-Range: W/"19097900-1410863319978"
    
    HTTP/1.1 206 Partial Content 
    ETag: W/"19097900-1410863319978" 
    Last-Modified: Tue, 16 Sep 2014 10:28:39 GMT 
    Content-Length: 9097900 
    Content-Type: application/octet-stream 
    Accept-Ranges: bytes 
    Content-Range: bytes 10000000-19097899/19097900 
    Server: Apache-Coyote/1.1 
    Date: Wed, 17 Sep 2014 18:12:36 GMT 
    

    如果远程文件已更改,则服务器不应返回 206-PartialContent 而是定期返回 200-OK 回复。服务器应该使用 If-Range 值来检查一致性。一些像 VLCPlayer 这样的客户端将 Range 字段放入没有 If-Range 值。

    当客户端发出一个没有 Range+If-Range 标头的初始请求时,它可能会添加“If-Modified-Since: modified_http_date”标头。服务器可能会返回 304-NotModified 状态并且客户端已完成。如果客户端给出 byteStartIdx>=filesize 则服务器返回 416-RequestedRangeNotSatisfiable。

    附加调试转储以阐明 http-resume 的工作原理。

    Range=bytes=0-0
    If-Range=W/"19097900-1410863319978"
    
    HTTP/1.1 206 Partial Content 
    ETag=W/"19097900-1410863319978" 
    Date=Fri, 19 Sep 2014 12:53:36 GMT 
    Content-Length=1 
    Last-Modified=Tue, 16 Sep 2014 10:28:39 GMT 
    Content-Type=application/octet-stream 
    Accept-Ranges=bytes 
    Server=Apache-Coyote/1.1 
    Content-Range=bytes 0-0/19097900 
    - - - - -
    
    Range=bytes=19097800-29097800
    If-Range=W/"19097900-1410863319978"
    
    HTTP/1.1 206 Partial Content 
    ETag=W/"19097900-1410863319978" 
    Date=Fri, 19 Sep 2014 12:59:24 GMT 
    Content-Length=100 
    Last-Modified=Tue, 16 Sep 2014 10:28:39 GMT 
    Content-Type=application/octet-stream 
    Accept-Ranges=bytes 
    Server=Apache-Coyote/1.1 
    Content-Range=bytes 19097800-19097899/19097900 
    - - - - - - - - 
    
    Range=bytes=19097899-19097899
    If-Range=W/"19097900-1410863319978"
    
    HTTP/1.1 206 Partial Content 
    ETag=W/"19097900-1410863319978" 
    Date=Fri, 19 Sep 2014 13:01:47 GMT 
    Content-Length=1 
    Last-Modified=Tue, 16 Sep 2014 10:28:39 GMT 
    Content-Type=application/octet-stream 
    Accept-Ranges=bytes 
    Server=Apache-Coyote/1.1 
    Content-Range=bytes 19097899-19097899/19097900 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-07
      • 1970-01-01
      • 2018-09-03
      • 2021-10-17
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多