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

Top*_*opo 9 http go http-content-range server

我有一个用go编写的网络服务器,我正在提供来自不同来源(本地,其他服务器,S3)的一些音频文件.我想为这些文件启用部分内容,以便HTML音频标签能够搜索和循环.

我怎么能得到这个?我知道httpServeContent函数可以做到这一点,但我怎么能通过自己提供文件来实现呢?我需要在没有这个的情况下这样做,以便我可以使用相同的处理程序提供来自不同来源的文件.

icz*_*cza 21

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

如果要提供(或提供)的内容是文件,您可以http.ServeFile()像上面提到的那样使用,它处理服务部分内容(范围请求).

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

func ServeContent(w ResponseWriter, req *Request,
    name string, modtime time.Time, content io.ReadSeeker)
Run Code Online (Sandbox Code Playgroud)

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

ServeContent优于io.Copy的主要好处是它正确处理Range请求,设置MIME类型,并处理If-Modified-Since请求.

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

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

因此,例如,如果您将内容作为a []byte,您可能会获得io.ReadSeeker如下所示:

var content []byte
// fill content
r := bytes.NewReader(content)
Run Code Online (Sandbox Code Playgroud)

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

io.ReadSeeker 是:

type ReadSeeker interface {
    Reader
    Seeker
}
Run Code Online (Sandbox Code Playgroud)

io.Reader 包含一种方法:

Read(p []byte) (n int, err error)
Run Code Online (Sandbox Code Playgroud)

io.Seeker 还包含一种方法:

Seek(offset int64, whence int) (int64, error)
Run Code Online (Sandbox Code Playgroud)

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