2016-04-11 6 views
3

私は外出先で書かれたWebサーバーを持っています。私は、さまざまなソース(ローカル、他のサーバー、S3)からいくつかのオーディオファイルを提供しています。 HTMLオーディオタグがシークしてループできるように、このファイルの部分コンテンツの配信を有効にしたいと考えています。Goでhttp部分コンテンツを提供するにはどうすればよいですか?

どうすればこの問題を解決できますか?私はhttpパッケージServeContent機能がこれを行うことを知っていますが、ファイルを自分で提供することでどうすればいいですか?私は同じハンドラで異なるソースからファイルを提供できるように、これを使わずにやる必要があります。

答えて

11

サービングの部分コンテンツは重要ではありません。紹介については、wikipediaのByte servingを参照してください。特定のステータスコードとヘッダー(リクエストとレスポンスの両方)を処理する必要がありますが、これはあまり難しくありませんが、自分で時間を無駄にするべきではありません。

配信するコンテンツ(または配信元)がファイルの場合は、上述のとおり、http.ServeFile()を使用して部分コンテンツ(範囲リクエスト)を処理します。

提供されるコンテンツは、ファイルとして存在していない、その後http.ServeContent()はあなたの友人である場合:

func ServeContent(w ResponseWriter, req *Request, 
    name string, modtime time.Time, content io.ReadSeeker) 

そして、はい、それはまた、部分コンテンツ(範囲要求)を提供扱う:

io.Copyに対するServeContentの主な利点は、Range要求を適切に処理し、MIMEタイプを設定し、If-Modified-Since要求を処理することです。

必要とするクライアントによって要求された部分に「ジャンプ」することができ、実装、部品が提供されるようにしますが、これを必要とするコンテンツのio.ReadSeeker「ビュー」を提供するだけです。あなたは質問するかもしれません:それを行う方法?

bytesパッケージには、io.ReadSeekerbytes.Readerを実装するタイプが含まれています。あなたは[]byteなどのコンテンツを持っている場合

したがって、たとえば、あなたは、このようなio.ReadSeekerを得ることができる:

var content []byte 
// fill content 
r := bytes.NewReader(content) 

そして、何をあなたは[]byteとして全体のコンテンツを持っていない場合は? 1つのオプションは、io.ReadSeekerを実装する独自の型の値を提供することです。

io.ReadSeekerは次のとおりです。

type ReadSeeker interface { 
    Reader 
    Seeker 
} 

io.Readerは1つの方法含まれています

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

io.Seekerのもひとつの方法が含まれます。

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

内容をどこかにアクセス可能ですが、どういうわけか、あなたはどのように知っています。 Seek()が呼び出され、コンテンツから必要な部分(位置)を知ることができます。Read()が呼び出され、渡されたスライスを(実際のコンテンツを提供するために)読み込むことができます。これらのメソッドは複数回呼び出される可能性があるので、コンテンツの場所(ソース)を常に把握しておく必要があります。このパスを下ることを選択した場合は、リンクされたインターフェイスのドキュメントを読んで、間違いを避けるためにインターフェイスの「一般契約」を満たしていることを確認してください。

関連する問題