zoukankan      html  css  js  c++  java
  • 断点续传 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

  • 相关阅读:
    Android开源框架——Volley
    Android中的事件传递机制
    @ViewDebug.ExportedProperty的使用
    字符间距——扩展
    读取assets文件夹下图片(ods_interview)
    Android消息推送——JPush极光推送
    深入模块
    正则表达式和re模块
    初识模块
    迭代器和生成器
  • 原文地址:https://www.cnblogs.com/develon/p/10964727.html
Copyright © 2011-2022 走看看