68 lines
1.4 KiB
Go
68 lines
1.4 KiB
Go
// Copyright Earl Warren <contact@earl-warren.org>
|
|
// Copyright Loïc Dachary <loic@dachary.org>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package objects
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"hash"
|
|
"io"
|
|
"net/http"
|
|
|
|
options_http "code.forgejo.org/f3/gof3/v3/options/http"
|
|
)
|
|
|
|
type SHASetter interface {
|
|
SetSHA(sha string)
|
|
}
|
|
|
|
func FuncReadURLAndSetSHA(newHTTPClient options_http.NewMigrationHTTPClientFun, url string, sha SHASetter) func() io.ReadCloser {
|
|
return func() io.ReadCloser {
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
httpClient := newHTTPClient()
|
|
resp, err := httpClient.Do(req)
|
|
if err != nil {
|
|
panic(fmt.Errorf("while downloading %s %w", url, err))
|
|
}
|
|
|
|
return FuncReadAndSetSHA(resp.Body, sha)()
|
|
}
|
|
}
|
|
|
|
type readAndSetSHA struct {
|
|
reader io.Reader
|
|
closer io.Closer
|
|
sha SHASetter
|
|
hasher hash.Hash
|
|
}
|
|
|
|
func (o *readAndSetSHA) Read(b []byte) (n int, err error) {
|
|
return o.reader.Read(b)
|
|
}
|
|
|
|
func (o *readAndSetSHA) Close() error {
|
|
o.sha.SetSHA(hex.EncodeToString(o.hasher.Sum(nil)))
|
|
return o.closer.Close()
|
|
}
|
|
|
|
func newReadAndSetSHA(reader io.ReadCloser, sha SHASetter) *readAndSetSHA {
|
|
hasher := sha256.New()
|
|
return &readAndSetSHA{
|
|
reader: io.TeeReader(reader, hasher),
|
|
closer: reader,
|
|
sha: sha,
|
|
hasher: hasher,
|
|
}
|
|
}
|
|
|
|
func FuncReadAndSetSHA(reader io.ReadCloser, sha SHASetter) func() io.ReadCloser {
|
|
return func() io.ReadCloser {
|
|
return newReadAndSetSHA(reader, sha)
|
|
}
|
|
}
|