断点续传 HTTP range requests

HTTP range requests

HTTP范围请求仅允许将HTTP消息的一部分从服务器发送到客户端。例如,部分请求对于大型媒体或具有暂停和恢复功能的文件下载很有用。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests

检查服务器是否支持范围请求

假如在响应中存在 Accept-Ranges 首部(并且它的值不为 “none”),那么表示该服务器支持范围请求。
其实标准的服务器会发送206响应,并且标头还有:

  'accept-ranges': 'bytes',
  'content-range': 'bytes 0-2036635788/2036635789',

通常发送一个HEAD请求来检测。

import * as http from 'http';
import * as https from 'https';
import { URL } from 'url';

/**
 * 判断url是否支持范围请求
 * @param url 
 */
function isSupportedRange(url: URL | string): Promise<boolean> {
    return new Promise((resolve, reject) => {
        if (typeof url === 'string') url = new URL(url);
        const options: http.RequestOptions = {
            method: 'HEAD',
            headers: {
                'Range': 'bytes=0-',
            },
        };
        let req: http.ClientRequest; // 根据URL协议,判断使用http还是https模块发送请求
        function callback(response: http.IncomingMessage) {
            // console.log(response.statusCode);
            // console.log(response.headers);
            // 假如在响应中存在 Accept-Ranges 首部(并且它的值不为 “none”),那么表示该服务器支持范围请求。
            if (response.statusCode === 206 || (response.headers["accept-ranges"] && response.headers["accept-ranges"] !== 'none')) resolve(true);
            resolve(false);
        }
        switch (url.protocol) {
            case 'http:': {
                req = http.request(url, options, callback);
                break;
            }
            case 'https:': {
                req = https.request(url, options, callback);
                break;
            }
            default: return void resolve(false);
        }
        req.addListener('error', (err: Error) => {
            reject(err); // 请求失败
        });
        req.end(); // refresh request stream
    });
}

断点续传原理

静态Web服务器支持仅发送静态资源的指定范围数据, 请求头为 Range

$ telnet abc.com 80
HEAD /rap.flv HTTP/1.1
Host: a.c
RANGE: bytes=2000070-

HTTP/1.1 206 Partial Content
Server: nginx
Date: Sun, 02 Jun 2019 14:10:43 GMT
Content-Type: video/x-flv
Content-Length: 16404710
Last-Modified: Fri, 26 Apr 2019 07:18:55 GMT
Connection: keep-alive
ETag: "5cc2b0df-118d5ac"
developer: develon
原始uri: /rap.flv
Content-Range: bytes 2000070-18404779/18404780

HEAD /rap.flv HTTP/1.1
Host: a.c
RANGE: bytes=2000070-2000071

HTTP/1.1 206 Partial Content
Server: nginx
Date: Sun, 02 Jun 2019 14:11:43 GMT
Content-Type: video/x-flv
Content-Length: 2
Last-Modified: Fri, 26 Apr 2019 07:18:55 GMT
Connection: keep-alive
ETag: "5cc2b0df-118d5ac"
developer: develon
原始uri: /rap.flv
Content-Range: bytes 2000070-2000071/18404780

URL url = new URL("http://www.sjtu.edu.cn/down.zip"); 
HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection(); 

// 设置 User-Agent 
httpConnection.setRequestProperty("User-Agent","NetFox"); 
// 设置断点续传的开始位置 
httpConnection.setRequestProperty("RANGE","bytes=2000070"); 
// 获得输入流 
InputStream input = httpConnection.getInputStream(); 

https://www.ibm.com/developerworks/cn/java/joy-down/index.html

posted @ 2019-06-02 22:17  develon  阅读(653)  评论(0编辑  收藏  举报