Commit 825e2afb authored by Jacob Vosmaer's avatar Jacob Vosmaer

Use only one header to send git blobs

parent 0a5bd0fe
......@@ -2,33 +2,60 @@ package git
import (
"../helper"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"strings"
)
func SendGitBlob(w http.ResponseWriter, r *http.Request, repoPath string, blobId string) {
log.Printf("SendGitBlob: sending %q for %q", blobId, r.URL.Path)
type blobParams struct {
RepoPath string
BlobId string
}
const SendBlobPrefix = "git-blob:"
func SendBlob(w http.ResponseWriter, r *http.Request, sendData string) {
params, err := unpackSendData(sendData)
if err != nil {
helper.Fail500(w, fmt.Errorf("SendBlob: unpack sendData: %v", err))
return
}
log.Printf("SendBlob: sending %q for %q", params.BlobId, r.URL.Path)
gitShowCmd := gitCommand("", "git", "--git-dir="+repoPath, "show", blobId)
gitShowCmd := gitCommand("", "git", "--git-dir="+params.RepoPath, "show", params.BlobId)
stdout, err := gitShowCmd.StdoutPipe()
if err != nil {
helper.Fail500(w, fmt.Errorf("SendGitBlob: git show stdout: %v", err))
helper.Fail500(w, fmt.Errorf("SendBlob: git show stdout: %v", err))
return
}
if err := gitShowCmd.Start(); err != nil {
helper.Fail500(w, fmt.Errorf("SendGitBlob: start %v: %v", gitShowCmd, err))
helper.Fail500(w, fmt.Errorf("SendBlob: start %v: %v", gitShowCmd, err))
return
}
defer helper.CleanUpProcessGroup(gitShowCmd)
if _, err := io.Copy(w, stdout); err != nil {
helper.LogError(fmt.Errorf("SendGitBlob: copy git show stdout: %v", err))
helper.LogError(fmt.Errorf("SendBlob: copy git show stdout: %v", err))
return
}
if err := gitShowCmd.Wait(); err != nil {
helper.LogError(fmt.Errorf("SendGitBlob: wait for git show: %v", err))
helper.LogError(fmt.Errorf("SendBlob: wait for git show: %v", err))
return
}
}
func unpackSendData(sendData string) (*blobParams, error) {
jsonBytes, err := base64.URLEncoding.DecodeString(strings.TrimPrefix(sendData, SendBlobPrefix))
if err != nil {
return nil, err
}
result := &blobParams{}
if err := json.Unmarshal([]byte(jsonBytes), result); err != nil {
return nil, err
}
return result, nil
}
......@@ -11,6 +11,7 @@ import (
"../helper"
"log"
"net/http"
"strings"
)
type sendFileResponseWriter struct {
......@@ -44,6 +45,13 @@ func (s *sendFileResponseWriter) Write(data []byte) (n int, err error) {
}
func (s *sendFileResponseWriter) WriteHeader(status int) {
// Never pass these headers to the client
defer func() {
s.Header().Del("X-Sendfile")
s.Header().Del("Gitlab-Workhorse-Send-Data")
}()
if s.status != 0 {
return
}
......@@ -55,27 +63,21 @@ func (s *sendFileResponseWriter) WriteHeader(status int) {
}
if file := s.Header().Get("X-Sendfile"); file != "" {
s.Header().Del("X-Sendfile")
// Mark this connection as hijacked
s.hijacked = true
// Serve the file
sendFileFromDisk(s.rw, s.req, file)
return
} else if repoPath := s.Header().Get("Gitlab-Workhorse-Repo-Path"); repoPath != "" {
}
if sendData := s.Header().Get("Gitlab-Workhorse-Send-Data"); strings.HasPrefix(sendData, "git-blob:") {
s.hijacked = true
s.Header().Del("Gitlab-Workhorse-Repo-Path")
sendBlob := s.Header().Get("Gitlab-Workhorse-Send-Blob")
s.Header().Del("Gitlab-Workhorse-Send-Blob")
git.SendGitBlob(s.rw, s.req, repoPath, sendBlob)
return
} else {
s.rw.WriteHeader(s.status)
git.SendBlob(s.rw, s.req, sendData)
return
}
s.rw.WriteHeader(s.status)
return
}
func sendFileFromDisk(w http.ResponseWriter, r *http.Request, file string) {
......
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