2015-04-23 16:20:36 +00:00
|
|
|
package lfs
|
2013-10-04 14:56:56 +00:00
|
|
|
|
|
|
|
import (
|
2015-04-28 21:37:17 +00:00
|
|
|
"bytes"
|
2013-10-24 16:55:46 +00:00
|
|
|
"crypto/sha256"
|
2013-10-04 14:56:56 +00:00
|
|
|
"encoding/hex"
|
|
|
|
"io"
|
|
|
|
"os"
|
2016-05-06 14:04:47 +00:00
|
|
|
|
2016-11-15 17:01:18 +00:00
|
|
|
"github.com/git-lfs/git-lfs/config"
|
|
|
|
"github.com/git-lfs/git-lfs/errors"
|
|
|
|
"github.com/git-lfs/git-lfs/progress"
|
|
|
|
"github.com/git-lfs/git-lfs/tools"
|
2013-10-04 14:56:56 +00:00
|
|
|
)
|
|
|
|
|
2014-07-28 19:28:05 +00:00
|
|
|
type cleanedAsset struct {
|
2015-06-27 15:36:10 +00:00
|
|
|
Filename string
|
2014-07-28 19:26:10 +00:00
|
|
|
*Pointer
|
2013-10-04 14:56:56 +00:00
|
|
|
}
|
|
|
|
|
2016-05-06 14:04:47 +00:00
|
|
|
func PointerClean(reader io.Reader, fileName string, fileSize int64, cb progress.CopyCallback) (*cleanedAsset, error) {
|
2016-05-13 16:38:06 +00:00
|
|
|
extensions, err := config.Config.SortedExtensions()
|
2013-10-04 14:56:56 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2015-07-24 04:53:36 +00:00
|
|
|
var oid string
|
|
|
|
var size int64
|
|
|
|
var tmp *os.File
|
|
|
|
var exts []*PointerExtension
|
2015-07-21 23:53:31 +00:00
|
|
|
if len(extensions) > 0 {
|
2015-07-24 04:53:36 +00:00
|
|
|
request := &pipeRequest{"clean", reader, fileName, extensions}
|
2015-07-21 23:53:31 +00:00
|
|
|
|
2015-07-24 04:53:36 +00:00
|
|
|
var response pipeResponse
|
|
|
|
if response, err = pipeExtensions(request); err != nil {
|
2015-07-21 23:53:31 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2015-07-24 04:53:36 +00:00
|
|
|
oid = response.results[len(response.results)-1].oidOut
|
|
|
|
tmp = response.file
|
2015-07-21 23:53:31 +00:00
|
|
|
var stat os.FileInfo
|
|
|
|
if stat, err = os.Stat(tmp.Name()); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
size = stat.Size()
|
2015-07-24 04:53:36 +00:00
|
|
|
|
|
|
|
for _, result := range response.results {
|
|
|
|
if result.oidIn != result.oidOut {
|
|
|
|
ext := NewPointerExtension(result.name, len(exts), result.oidIn)
|
|
|
|
exts = append(exts, ext)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
oid, size, tmp, err = copyToTemp(reader, fileSize, cb)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2015-07-21 23:53:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pointer := NewPointer(oid, size, exts)
|
|
|
|
return &cleanedAsset{tmp.Name(), pointer}, err
|
|
|
|
}
|
|
|
|
|
2016-05-06 14:04:47 +00:00
|
|
|
func copyToTemp(reader io.Reader, fileSize int64, cb progress.CopyCallback) (oid string, size int64, tmp *os.File, err error) {
|
2015-07-21 23:53:31 +00:00
|
|
|
tmp, err = TempFile("")
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-06-27 15:36:10 +00:00
|
|
|
defer tmp.Close()
|
|
|
|
|
2013-10-24 16:55:46 +00:00
|
|
|
oidHash := sha256.New()
|
|
|
|
writer := io.MultiWriter(oidHash, tmp)
|
2014-08-07 17:01:06 +00:00
|
|
|
|
2015-07-21 23:53:31 +00:00
|
|
|
if fileSize == 0 {
|
2014-08-07 17:01:06 +00:00
|
|
|
cb = nil
|
|
|
|
}
|
|
|
|
|
2016-12-23 19:16:57 +00:00
|
|
|
ptr, buf, err := DecodeFrom(reader)
|
2017-01-12 00:17:14 +00:00
|
|
|
|
|
|
|
by := make([]byte, blobSizeCutoff)
|
|
|
|
n, rerr := buf.Read(by)
|
|
|
|
by = by[:n]
|
|
|
|
|
2016-12-23 19:16:57 +00:00
|
|
|
if rerr != nil || (err == nil && len(by) < 512) {
|
2016-08-18 21:24:11 +00:00
|
|
|
err = errors.NewCleanPointerError(ptr, by)
|
2015-07-21 23:53:31 +00:00
|
|
|
return
|
2015-04-28 21:37:17 +00:00
|
|
|
}
|
|
|
|
|
2016-11-04 20:25:06 +00:00
|
|
|
var from io.Reader = bytes.NewReader(by)
|
2017-08-09 03:07:40 +00:00
|
|
|
if fileSize < 0 || int64(len(by)) < fileSize {
|
2016-11-04 20:25:06 +00:00
|
|
|
// If there is still more data to be read from the file, tack on
|
|
|
|
// the original reader and continue the read from there.
|
|
|
|
from = io.MultiReader(from, reader)
|
|
|
|
}
|
|
|
|
|
|
|
|
size, err = tools.CopyWithCallback(writer, from, fileSize, cb)
|
2013-10-04 14:56:56 +00:00
|
|
|
|
2015-07-21 23:53:31 +00:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
oid = hex.EncodeToString(oidHash.Sum(nil))
|
|
|
|
return
|
2014-08-07 21:32:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (a *cleanedAsset) Teardown() error {
|
2015-06-27 15:36:10 +00:00
|
|
|
return os.Remove(a.Filename)
|
2013-10-04 14:56:56 +00:00
|
|
|
}
|