设为首页 加入收藏

TOP

goroutine&waitgroup下载文件(一)
2023-07-23 13:28:57 】 浏览:53
Tags:goroutine&waitgroup 文件

0.1、索引

https://blog.waterflow.link/articles/1663078266267

当我们下载一个大文件的时候,会因为下载时间太久而超时或者出错。那么我么我们可以利用goroutine的特性并发分段的去请求下载资源。

1、Accept-Ranges

首先下载链接需要在响应中返回Accept-Ranges,并且它的值不为 “none”,那么该服务器支持范围请求。比如我们可以利用HEAD请求来进行检测

...

// head请求获取url的header
	head, err := http.Head(url)
	if err != nil {
		return err
	}

  // 判断url是否支持指定范围请求及哪种类型的分段请求
	if head.Header.Get("Accept-Ranges") != "bytes" {
		return errors.New("not support range download")
	}

...

我们可以使用curl命令看下head头

curl -I https://agritrop.cirad.fr/584726/1/Rapport.pdf
HTTP/1.1 200 OK
Date: Tue, 13 Sep 2022 13:52:08 GMT
Server: HTTPD
Strict-Transport-Security: max-age=63072000
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
Content-MD5: K4j+rsagurPwGP/5cm8k8Q==
Last-Modified: Tue, 04 Jul 2017 08:26:16 GMT
Expires: Wed, 13 Sep 2023 13:52:08 GMT
Content-Disposition: inline; filename=Rapport.pdf
Accept-Ranges: bytes # 允许范围请求,单位是字节
Content-Length: 6659798 # 文件的完整大小
Content-Type: application/pdf
X-XSS-Protection: 1; mode=block
X-Permitted-Cross-Domain-Policies: none
Cache-Control: public

其中,Accept-Ranges: bytes 表示界定范围的单位是 bytes 。这里 Content-Length也是有效信息,因为它提供了文件的完整大小。

2、Range

假如服务器支持范围请求的话,你可以使用 Range 首部来生成该类请求。该首部指示服务器应该返回文件的哪一或哪几部分。

...
req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		fmt.Println("初始化request失败:", err)
		return
	}

	rangeL := fmt.Sprintf("bytes=%d-%d", start, end)
	fmt.Println("字符范围:", rangeL)
  // 获取制定范围的数据
	req.Header.Add("Range", rangeL)
	res, err := client.Do(req)
...

单一范围

我们可以请求资源的某一部分。这次我们依然用 cURL 来进行测试。"-H" 选项可以在请求中追加一个首部行,在这个例子中,是用 Range 首部来请求图片文件的前 1024 个字节。

curl https://agritrop.cirad.fr/584726/1/Rapport.pdf -i -H "Range: bytes=0-1023"
HTTP/1.1 206 Partial Content
Date: Tue, 13 Sep 2022 14:00:47 GMT
Server: HTTPD
Strict-Transport-Security: max-age=63072000
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
Content-MD5: K4j+rsagurPwGP/5cm8k8Q==
Last-Modified: Tue, 04 Jul 2017 08:26:16 GMT
Expires: Wed, 13 Sep 2023 14:00:47 GMT
Content-Disposition: inline; filename=Rapport.pdf
Accept-Ranges: bytes
Content-Range: bytes 0-1023/6659798 # 返回指定的字节
Content-Length: 1024
Content-Type: application/pdf
X-XSS-Protection: 1; mode=block
X-Permitted-Cross-Domain-Policies: none
Cache-Control: public

Content-Range表示请求的资源在整个资源中的位置,这个时候Content-Length就不是表示整个资源的大小,而是请求资源的大小。

多重范围

我们也可以请求多个范围,只需要在Range中指定多个即可

curl https://agritrop.cirad.fr/584726/1/Rapport.pdf -i -H "Range: bytes=0-50, 100-150"
HTTP/1.1 206 Partial Content
Date: Tue, 13 Sep 2022 14:04:53 GMT
Server: HTTPD
Strict-Transport-Security: max-age=63072000
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
Content-MD5: K4j+rsagurPwGP/5cm8k8Q==
Last-Modified: Tue, 04 Jul 2017 08:26:16 GMT
Expires: Wed, 13 Sep 2023 14:04:53 GMT
Content-Disposition: inline; filename=Rapport.pdf
Accept-Ranges: bytes
Content-Length: 312
Content-Type: multipart/byteranges; boundary=4876db1cd4aa85af6
X-XSS-Protection: 1; mode=block
X-Permitted-Cross-Domain-Policies: none
Cache-Control: public


--4876db1cd4aa85af6
Content-type: application/pdf
Content-range: bytes 0-50/6659798

内容
--4876db1cd
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇etcd实现分布式锁 下一篇go-zero docker-compose 搭建课件..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目