Commit 24041f2e authored by Marin Jankovski's avatar Marin Jankovski

Check if file exists before trying to upload it.

parent 94b19e8c
......@@ -16,7 +16,7 @@ import (
"time"
)
func handleGetArchive(w http.ResponseWriter, r *gitRequest, format string) (callback *gitRequest){
func handleGetArchive(w http.ResponseWriter, r *gitRequest, format string) (callback *gitRequest) {
archiveFilename := path.Base(r.ArchivePath)
if cachedArchive, err := os.Open(r.ArchivePath); err == nil {
......
......@@ -12,7 +12,7 @@ import (
"strings"
)
func handleGetInfoRefs(w http.ResponseWriter, r *gitRequest, _ string) (callback *gitRequest){
func handleGetInfoRefs(w http.ResponseWriter, r *gitRequest, _ string) (callback *gitRequest) {
rpc := r.URL.Query().Get("service")
if !(rpc == "git-upload-pack" || rpc == "git-receive-pack") {
// The 'dumb' Git HTTP protocol is not supported
......@@ -58,7 +58,7 @@ func handleGetInfoRefs(w http.ResponseWriter, r *gitRequest, _ string) (callback
return
}
func handlePostRPC(w http.ResponseWriter, r *gitRequest, rpc string) (callback *gitRequest){
func handlePostRPC(w http.ResponseWriter, r *gitRequest, rpc string) (callback *gitRequest) {
var body io.ReadCloser
var err error
......
......@@ -25,7 +25,7 @@ type gitHandler struct {
type gitService struct {
method string
regex *regexp.Regexp
handleFunc func(w http.ResponseWriter, r *gitRequest, rpc string)(*gitRequest)
handleFunc func(w http.ResponseWriter, r *gitRequest, rpc string) *gitRequest
rpc string
}
......@@ -169,13 +169,23 @@ func looksLikeRepo(p string) bool {
func (h *gitHandler) doAuthRequest(r *http.Request) (result *http.Response, err error) {
url := h.authBackend + r.URL.RequestURI()
authReq := doRequest(r, url)
if authReq != nil {
return h.httpClient.Do(authReq)
authReq, err := http.NewRequest(r.Method, url, nil)
if err != nil {
return nil, err
}
return
// Forward all headers from our client to the auth backend. This includes
// HTTP Basic authentication credentials (the 'Authorization' header).
for k, v := range r.Header {
authReq.Header[k] = v
}
// Also forward the Host header, which is excluded from the Header map by the http libary.
// This allows the Host header received by the backend to be consistent with other
// requests not going through gitlab-workhorse.
authReq.Host = r.Host
// Set a custom header for the request. This can be used in some
// configurations (Passenger) to solve auth request routing problems.
authReq.Header.Set("GitLab-Git-HTTP-Server", Version)
return h.httpClient.Do(authReq)
}
func (h *gitHandler) doCallback(w http.ResponseWriter, r *gitRequest) (result *http.Response, err error) {
......
......@@ -23,9 +23,8 @@ var (
errSizeMismatch = errors.New("Content size does not match")
)
func handleStoreLfsObject(w http.ResponseWriter, r *gitRequest, rpc string) (callback *gitRequest){
func handleStoreLfsObject(w http.ResponseWriter, r *gitRequest, rpc string) (callback *gitRequest) {
var body io.ReadCloser
var err error
urlPath := r.URL.Path
regExp := regexp.MustCompile(`([0-9a-f]{64})/([0-9]+)`)
......@@ -40,69 +39,72 @@ func handleStoreLfsObject(w http.ResponseWriter, r *gitRequest, rpc string) (cal
size := matches[2]
log.Printf("Found oid: %s and size: %s", oid, size)
path := filepath.Join(r.StoreLFSPath, transformKey(oid))
tmpPath := path + ".tmp"
storePath := filepath.Join(r.StoreLFSPath, transformKey(oid))
if _, err := os.Stat(storePath); os.IsNotExist(err) {
var err error
tmpPath := filepath.Join(r.StoreLFSPath, "tmp", oid)
// TODO try removing gzip, possibly not needed
// The client request body may have been gzipped.
if r.Header.Get("Content-Encoding") == "gzip" {
body, err = gzip.NewReader(r.Body)
if err != nil {
fail500(w, "Couldn't handle LFS upload request.", err)
return
}
} else {
body = r.Body
}
defer body.Close()
// TODO try removing gzip, possibly not needed
// The client request body may have been gzipped.
if r.Header.Get("Content-Encoding") == "gzip" {
body, err = gzip.NewReader(r.Body)
if err != nil {
fail500(w, "Couldn't handle LFS upload request.", err)
// TODO maybe set dir permissions to 700
dir := filepath.Dir(tmpPath)
if err := os.MkdirAll(dir, 0750); err != nil {
fail500(w, "Couldn't create directory for storing LFS objects.", err)
return
}
} else {
body = r.Body
}
defer body.Close()
// TODO maybe set dir permissions to 700
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0750); err != nil {
fail500(w, "Couldn't create directory for storing LFS objects.", err)
return
}
// TODO use go library for creating TMP files
file, err := os.OpenFile(tmpPath, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0640)
if err != nil {
fail500(w, "Couldn't open tmp file for writing.", err)
return
}
defer os.Remove(tmpPath)
defer file.Close()
hash := sha256.New()
hw := io.MultiWriter(hash, file)
// TODO use go library for creating TMP files
file, err := os.OpenFile(tmpPath, os.O_CREATE|os.O_WRONLY|os.O_EXCL, 0640)
if err != nil {
fail500(w, "Couldn't open tmp file for writing.", err)
return
}
// defer os.Remove(tmpPath)
defer file.Close()
written, err := io.Copy(hw, body)
if err != nil {
fail500(w, "Failed to save received LFS object.", err)
return
}
file.Close()
hash := sha256.New()
hw := io.MultiWriter(hash, file)
sizeInt, err := strconv.ParseInt(size, 10, 64)
if err != nil {
fail500(w, "Couldn't read size: ", err)
return
}
written, err := io.Copy(hw, body)
if err != nil {
fail500(w, "Failed to save received LFS object.", err)
return
}
file.Close()
if written != sizeInt {
fail500(w, "Inconsistent size: ", errSizeMismatch)
return
}
sizeInt, err := strconv.ParseInt(size, 10, 64)
if err != nil {
fail500(w, "Couldn't read size: ", err)
return
}
shaStr := hex.EncodeToString(hash.Sum(nil))
if shaStr != oid {
fail500(w, "Inconsistent size: ", errSizeMismatch)
return
}
if written != sizeInt {
fail500(w, "Inconsistent size: ", errSizeMismatch)
return
}
if err := os.Rename(tmpPath, path); err != nil {
fail500(w, "Failed to rename temporary LFS object.", err)
return
shaStr := hex.EncodeToString(hash.Sum(nil))
if shaStr != oid {
fail500(w, "Inconsistent size: ", errSizeMismatch)
return
}
}
// if err := os.Rename(tmpPath, path); err != nil {
// fail500(w, "Failed to rename temporary LFS object.", err)
// return
// }
log.Printf("Received the LFS object from client, oid: %s", oid)
......@@ -110,7 +112,7 @@ func handleStoreLfsObject(w http.ResponseWriter, r *gitRequest, rpc string) (cal
}
func handleRetreiveLfsObject(w http.ResponseWriter, r *gitRequest, rpc string) (callback *gitRequest){
func handleRetreiveLfsObject(w http.ResponseWriter, r *gitRequest, rpc string) (callback *gitRequest) {
log.Printf("I should download %s", r)
urlPath := r.URL.Path
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment