Обслуживание частичного содержимого нетривиально. См. Byte serving о википедии для введения. Вы должны обрабатывать определенные коды состояния и заголовки (как запрос, так и ответ), что не слишком сложно, но вы не должны тратить свое время на это.
Если контент для подачи (или подачи) из файла является файлом, вы можете использовать http.ServeFile()
так же, как вы упомянули, который обрабатывает частичное содержимое (запросы диапазона).
Если содержание подается не присутствует в файле, то http.ServeContent()
ваш друг:
func ServeContent(w ResponseWriter, req *Request,
name string, modtime time.Time, content io.ReadSeeker)
И да, она также обрабатывает обслуживание частичное содержание (запросы диапазона):
Основное преимущество ServeContent над io.Copy заключается в том, что он правильно обрабатывает запросы диапазона, устанавливает тип 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()
вызывается так, что вы можете заполнить пройденный фрагмент (чтобы предоставить фактический контент). Обратите внимание, что эти методы можно вызывать несколько раз, поэтому вам нужно отслеживать, где вы находитесь в своем контенте (источник).Если вы решите пойти по этому пути, прочитайте документ связанных интерфейсов, чтобы убедиться, что вы отвечаете «генеральному контракту» интерфейсов, чтобы избежать неожиданных ошибок.