import (
"io"
"io/ioutil"
+ "net/http"
"os"
"path/filepath"
"strconv"
"github.com/git-lfs/git-lfs/errors"
"github.com/git-lfs/git-lfs/lfsapi"
- "github.com/git-lfs/git-lfs/progress"
+ "github.com/git-lfs/git-lfs/tools"
)
const (
- BasicAdapterName = "basic"
+ BasicAdapterName = "basic"
+ defaultContentType = "application/octet-stream"
)
// Adapter for basic uploads (non resumable)
return err
}
- if len(req.Header.Get("Content-Type")) == 0 {
- req.Header.Set("Content-Type", "application/octet-stream")
- }
-
if req.Header.Get("Transfer-Encoding") == "chunked" {
req.TransferEncoding = []string{"chunked"}
} else {
}
defer f.Close()
+ if err := setContentTypeFor(req, f); err != nil {
+ return err
+ }
+
// Ensure progress callbacks made while uploading
// Wrap callback to give name context
ccb := func(totalSize int64, readSoFar int64, readSinceLast int) error {
return nil
}
- cbr := progress.NewBodyWithCallback(f, t.Size, ccb)
+ cbr := tools.NewBodyWithCallback(f, t.Size, ccb)
var reader lfsapi.ReadSeekCloser = cbr
// Signal auth was ok on first read; this frees up other workers to start
m.RegisterNewAdapterFunc(BasicAdapterName, Upload, func(name string, dir Direction) Adapter {
switch dir {
case Upload:
- bu := &basicUploadAdapter{newAdapterBase(name, dir, nil)}
+ bu := &basicUploadAdapter{newAdapterBase(m.fs, name, dir, nil)}
// self implements impl
bu.transferImpl = bu
return bu
return nil
})
}
+
+func setContentTypeFor(req *http.Request, r io.ReadSeeker) error {
+ if len(req.Header.Get("Content-Type")) != 0 {
+ return nil
+ }
+
+ buffer := make([]byte, 512)
+ n, err := r.Read(buffer)
+ if err != nil && err != io.EOF {
+ return errors.Wrap(err, "content type detect")
+ }
+
+ contentType := http.DetectContentType(buffer[:n])
+ if _, err := r.Seek(0, 0); err != nil {
+ return errors.Wrap(err, "content type rewind")
+ }
+
+ if contentType == "" {
+ contentType = defaultContentType
+ }
+
+ req.Header.Set("Content-Type", contentType)
+ return nil
+}