为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Go 提供 http 部分内容?

如何使用 Go 提供 http 部分内容?

Go
Helenr 2022-01-04 10:43:45
我有一个用 go 编写的网络服务器,我正在提供来自不同来源(本地、其他服务器、S3)的一些音频文件。我想为此文件提供部分内容,以便 HTML 音频标签能够搜索和循环。我怎样才能做到这一点?我知道http包ServeContent函数会这样做,但我如何通过自己提供文件来做到这一点?我需要在没有这个的情况下这样做,以便我可以使用相同的处理程序提供来自不同来源的文件。
查看完整描述

1 回答

?
慕仙森

TA贡献1827条经验 获得超8个赞

提供部分内容并非易事。有关介绍,请参阅维基百科上的字节服务。您必须处理特定的状态代码和标头(请求和响应),这并不难,但您不应该自己浪费时间。


如果要提供(或从中提供)的内容是一个文件,您可以http.ServeFile()像您提到的那样使用它来处理部分内容(范围请求)。


如果要提供的内容不是作为文件存在,那么http.ServeContent()您的朋友是:


func ServeContent(w ResponseWriter, req *Request,

    name string, modtime time.Time, content io.ReadSeeker)

是的,它还处理提供部分内容(范围请求):


ServeContent 相对于 io.Copy 的主要好处是它可以正确处理 Range 请求、设置 MIME 类型并处理 If-Modified-Since 请求。


您需要做的就是提供内容的io.ReadSeeker“视图”,这是必需的,以便实现可以“跳转”到客户端请求的部分,即需要提供服务的部分。你可能会问:怎么做?


该bytes包包含一个实现io.ReadSeeker:的类型bytes.Reader。


因此,例如,如果您将内容作为[]byte,您可能会获得io.ReadSeeker这样的:


var content []byte

// fill content

r := bytes.NewReader(content)

如果您没有完整的内容[]byte怎么办?一种选择是提供您自己的类型的值,该值实现io.ReadSeeker.


io.ReadSeeker 是:


type ReadSeeker interface {

    Reader

    Seeker

}

io.Reader 包含一种方法:


Read(p []byte) (n int, err error)

io.Seeker 还包含一种方法:


Seek(offset int64, whence int) (int64, error)

您的内容可以在某处访问,不知何故,您知道如何。Seek()被调用是为了让您知道您的内容需要哪个部分(位置),并被Read()调用以便您可以填充传递的切片(以提供实际内容)。请注意,这些方法可能会被多次调用,因此您必须跟踪您在内容(源)中的位置。如果您选择沿着这条路走下去,请阅读链接接口的文档,以确保您符合接口的“通用合同”以避免意外错误。


查看完整回答
反对 回复 2022-01-04
  • 1 回答
  • 0 关注
  • 221 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号