Commit 46e1ae4e authored by Jacob Vosmaer's avatar Jacob Vosmaer

Simplify code organization

parent 397ae85c
...@@ -39,7 +39,7 @@ type gitEnv struct { ...@@ -39,7 +39,7 @@ type gitEnv struct {
GL_ID string GL_ID string
} }
var Version string var Version string // Set at build time in the Makefile
var httpClient = &http.Client{} var httpClient = &http.Client{}
// Command-line options // Command-line options
...@@ -50,6 +50,7 @@ var listenNetwork = flag.String("listenNetwork", "tcp", "Listen 'network' (proto ...@@ -50,6 +50,7 @@ var listenNetwork = flag.String("listenNetwork", "tcp", "Listen 'network' (proto
var listenUmask = flag.Int("listenUmask", 022, "Umask for Unix socket, default: 022") var listenUmask = flag.Int("listenUmask", 022, "Umask for Unix socket, default: 022")
var authBackend = flag.String("authBackend", "http://localhost:8080", "Authentication/authorization backend") var authBackend = flag.String("authBackend", "http://localhost:8080", "Authentication/authorization backend")
// Routing table
var gitServices = [...]gitService{ var gitServices = [...]gitService{
gitService{"GET", "/info/refs", handleGetInfoRefs, ""}, gitService{"GET", "/info/refs", handleGetInfoRefs, ""},
gitService{"POST", "/git-upload-pack", handlePostRPC, "git-upload-pack"}, gitService{"POST", "/git-upload-pack", handlePostRPC, "git-upload-pack"},
...@@ -75,8 +76,6 @@ func main() { ...@@ -75,8 +76,6 @@ func main() {
} }
log.Printf("repoRoot: %s", repoRoot) log.Printf("repoRoot: %s", repoRoot)
http.HandleFunc("/", gitHandler)
// Good housekeeping for Unix sockets: unlink before binding // Good housekeeping for Unix sockets: unlink before binding
if *listenNetwork == "unix" { if *listenNetwork == "unix" {
if err := os.Remove(*listenAddr); err != nil && !os.IsNotExist(err) { if err := os.Remove(*listenAddr); err != nil && !os.IsNotExist(err) {
...@@ -92,6 +91,7 @@ func main() { ...@@ -92,6 +91,7 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
http.HandleFunc("/", gitHandler)
log.Fatal(http.Serve(listener, nil)) log.Fatal(http.Serve(listener, nil))
} }
...@@ -214,7 +214,7 @@ func handleGetInfoRefs(env gitEnv, _ string, path string, w http.ResponseWriter, ...@@ -214,7 +214,7 @@ func handleGetInfoRefs(env gitEnv, _ string, path string, w http.ResponseWriter,
// Start writing the response // Start writing the response
w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-advertisement", rpc)) w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-advertisement", rpc))
setHeaderNoCache(w) w.Header().Add("Cache-Control", "no-cache")
w.WriteHeader(200) // Don't bother with HTTP 500 from this point on, just panic w.WriteHeader(200) // Don't bother with HTTP 500 from this point on, just panic
if err := pktLine(w, fmt.Sprintf("# service=%s\n", rpc)); err != nil { if err := pktLine(w, fmt.Sprintf("# service=%s\n", rpc)); err != nil {
panic(err) panic(err)
...@@ -230,22 +230,6 @@ func handleGetInfoRefs(env gitEnv, _ string, path string, w http.ResponseWriter, ...@@ -230,22 +230,6 @@ func handleGetInfoRefs(env gitEnv, _ string, path string, w http.ResponseWriter,
} }
} }
func subCommand(rpc string) string {
return strings.TrimPrefix(rpc, "git-")
}
func gitCommand(env gitEnv, name string, args ...string) *exec.Cmd {
cmd := exec.Command(name, args...)
// Start the command in its own process group (nice for signalling)
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
// Explicitly set the environment for the Git command
cmd.Env = []string{
fmt.Sprintf("PATH=%s", os.Getenv("PATH")),
fmt.Sprintf("GL_ID=%s", env.GL_ID),
}
return cmd
}
func handlePostRPC(env gitEnv, rpc string, path string, w http.ResponseWriter, r *http.Request) { func handlePostRPC(env gitEnv, rpc string, path string, w http.ResponseWriter, r *http.Request) {
var body io.Reader var body io.Reader
var err error var err error
...@@ -290,7 +274,7 @@ func handlePostRPC(env gitEnv, rpc string, path string, w http.ResponseWriter, r ...@@ -290,7 +274,7 @@ func handlePostRPC(env gitEnv, rpc string, path string, w http.ResponseWriter, r
// Start writing the response // Start writing the response
w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-result", rpc)) w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-result", rpc))
setHeaderNoCache(w) w.Header().Add("Cache-Control", "no-cache")
w.WriteHeader(200) // Don't bother with HTTP 500 from this point on, just panic w.WriteHeader(200) // Don't bother with HTTP 500 from this point on, just panic
if _, err := io.Copy(w, stdout); err != nil { if _, err := io.Copy(w, stdout); err != nil {
panic(err) panic(err)
...@@ -300,23 +284,26 @@ func handlePostRPC(env gitEnv, rpc string, path string, w http.ResponseWriter, r ...@@ -300,23 +284,26 @@ func handlePostRPC(env gitEnv, rpc string, path string, w http.ResponseWriter, r
} }
} }
func pktLine(w io.Writer, s string) error {
_, err := fmt.Fprintf(w, "%04x%s", len(s)+4, s)
return err
}
func pktFlush(w io.Writer) error {
_, err := fmt.Fprint(w, "0000")
return err
}
func fail500(w http.ResponseWriter, err error) { func fail500(w http.ResponseWriter, err error) {
http.Error(w, "Internal server error", 500) http.Error(w, "Internal server error", 500)
log.Print(err) log.Print(err)
} }
func setHeaderNoCache(w http.ResponseWriter) { // Git subprocess helpers
w.Header().Add("Cache-Control", "no-cache") func subCommand(rpc string) string {
return strings.TrimPrefix(rpc, "git-")
}
func gitCommand(env gitEnv, name string, args ...string) *exec.Cmd {
cmd := exec.Command(name, args...)
// Start the command in its own process group (nice for signalling)
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
// Explicitly set the environment for the Git command
cmd.Env = []string{
fmt.Sprintf("PATH=%s", os.Getenv("PATH")),
fmt.Sprintf("GL_ID=%s", env.GL_ID),
}
return cmd
} }
func cleanUpProcessGroup(cmd *exec.Cmd) { func cleanUpProcessGroup(cmd *exec.Cmd) {
...@@ -333,3 +320,14 @@ func cleanUpProcessGroup(cmd *exec.Cmd) { ...@@ -333,3 +320,14 @@ func cleanUpProcessGroup(cmd *exec.Cmd) {
// reap our child process // reap our child process
cmd.Wait() cmd.Wait()
} }
// Git HTTP line protocol functions
func pktLine(w io.Writer, s string) error {
_, err := fmt.Fprintf(w, "%04x%s", len(s)+4, s)
return err
}
func pktFlush(w io.Writer) error {
_, err := fmt.Fprint(w, "0000")
return err
}
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