Golang io.copier deux fois sur le corps de la requête

Je suis la construction d'un système de stockage d'objets blob et j'ai choisi d'Aller comme langage de programmation.
- Je créer un flux pour faire un multipart upload de fichier du client vers le blob serveur.

Le stream fonctionne très bien, mais je veux faire un hash sha1 de le corps de la requête. J'ai besoin de io.Copiez le corps par deux fois. Le sha1 est créé mais la multipart flux de 0 octets après.

  1. Pour la création de la table de hachage
  2. Pour le streaming, le corps comme multipart

une idée de comment je peux faire cela?

le client de téléchargement

func (c *Client) Upload(h *UploadHandle) (*PutResult, error) {
body, bodySize, err := h.Read()
if err != nil {
    return nil, err
}

//Creating a sha1 hash from the bytes of body
dropRef, err := drop.Sha1FromReader(body)
if err != nil {
    return nil, err
}

bodyReader, bodyWriter := io.Pipe()
writer := multipart.NewWriter(bodyWriter)

errChan := make(chan error, 1)
go func() {
    defer bodyWriter.Close()
    part, err := writer.CreateFormFile(dropRef, dropRef)
    if err != nil {
        errChan <- err
        return
    }
    if _, err := io.Copy(part, body); err != nil {
        errChan <- err
        return
    }
    if err = writer.Close(); err != nil {
        errChan <- err
    }
}()

req, err := http.NewRequest("POST", c.Server+"/drops/upload", bodyReader)
req.Header.Add("Content-Type", writer.FormDataContentType())
resp, err := c.Do(req)
if err != nil {
    return nil, err
}
  .....
 }

le sha1 func

func Sha1FromReader(src io.Reader) (string, error) {
hash := sha1.New()
_, err := io.Copy(hash, src)
if err != nil {
    return "", err
}
return hex.EncodeToString(hash.Sum(nil)), nil

}

télécharger poignée

func (h *UploadHandle) Read() (io.Reader, int64, error) {
var b bytes.Buffer

hw := &Hasher{&b, sha1.New()}
n, err := io.Copy(hw, h.Contents)

if err != nil {
    return nil, 0, err
}

return &b, n, nil

}

Je l'ai fait pour travailler merci à @OneofOne je poste le résultat final plus tard, quand j'ai nettoyé les dégâts que j'ai faite
Vous n'avez pas vraiment besoin de beaucoup de code et vous certainement n'avez pas besoin de stocker un ensemble contigu copie de votre blob dans la mémoire RAM. J'ai fait une chose similaire avec multi-GO gouttes sur la mémoire vive de faim appareils sans problème.
que feriez-vous dans ce cas?
Que faites-vous avec les trucs que vous écrivez dans ce buffer? Le faire sans l'écrire dans la mémoire tampon. Envisagez de cette aire de jeu lien -- qui ne fonctionne pas sur le terrain de jeu parce que vous ne pouvez pas créer de fichiers, mais peut manipuler arbitrairement long entrées correctement avec un minimum de l'utilisation de la mémoire. J'ai fait une chose similaire pour un CAS qui a également vérifié l'extérieur de la bande de hachage, puis renommé le fichier après la clôture avec succès.
Comme alternative, vous pouvez utiliser cette bibliothèque https://github.com/hyperboloide/sprocess pour traiter de téléchargement de fichiers torrents

OriginalL'auteur Anthony De Meulemeester | 2014-09-04