Comment servir le contenu partiel http avec Go?

J’ai un serveur web écrit en go et je sers des fichiers audio de différentes sources (locales, autres serveurs, S3). Je veux activer la diffusion de contenu partiel pour ces fichiers afin que les balises audio HTML puissent rechercher et boucler.

Comment puis-je y parvenir? Je sais que la fonction ServeContent paquetage http fait cela, mais comment puis-je le faire en servant moi-même les fichiers? Je dois le faire sans cela afin que je puisse servir des fichiers de différentes sources avec le même gestionnaire.

    Servir un contenu partiel n’est pas sortingvial. Voir Byte servant sur Wikipedia pour une introduction. Vous devez gérer des codes d’état et des en-têtes spécifiques (à la fois demande et réponse), ce qui n’est pas trop difficile, mais vous ne devriez pas perdre votre temps à le faire vous-même.

    Si le contenu à servir (ou à servir) est un fichier, vous pouvez utiliser http.ServeFile() comme vous l’avez mentionné, qui gère le service de contenu partiel (demandes de plage).

    Si le contenu à servir n’est pas un fichier, http.ServeContent() est votre ami:

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

    Et oui, il gère également le service de contenu partiel (demandes de plage):

    Le principal avantage de ServeContent sur io.Copy est qu’il gère correctement les requêtes Range, définit le type MIME et gère les requêtes If-Modified-Since.

    Tout ce que vous avez à faire est de fournir une “vue” io.ReadSeeker de votre contenu, ceci est nécessaire pour que l’implémentation puisse “sauter” vers la partie demandée par le client, la partie devant être servie. Vous pourriez demander: comment faire cela?

    Le paquet d’ bytes contient un type qui implémente io.ReadSeeker : bytes.Reader .

    Ainsi, par exemple, si vous avez le contenu sous la forme d’un []byte , vous pouvez obtenir un io.ReadSeeker comme celui-ci:

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

    Et si vous n’avez pas tout le contenu sous la forme d’un []byte ? Une option consiste à fournir une valeur de votre propre type qui implémente io.ReadSeeker .

    io.ReadSeeker est:

     type ReadSeeker interface { Reader Seeker } 

    io.Reader contient une méthode:

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

    io.Seeker contient également une méthode:

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

    Votre contenu est accessible quelque part, vous savez comment. Seek() est appelée pour vous permettre de savoir quelle partie (position) est requirejse de votre contenu et Read() est appelée pour que vous puissiez renseigner la tranche transmise (pour fournir le contenu réel). Notez que ces méthodes peuvent être appelées plusieurs fois, vous devez donc garder une trace de votre contenu (source). Si vous choisissez de suivre ce chemin, veuillez lire le document des interfaces liées pour vous assurer que vous respectez le “contrat général” des interfaces pour éviter les erreurs de surprise.