Commit 789c7582 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Handle gzip from client and support multiple repos

parent 95de37db
package main package main
import ( import (
"compress/gzip"
"flag"
"fmt" "fmt"
"io" "io"
"log" "log"
"net/http" "net/http"
"os/exec" "os/exec"
"path"
"regexp" "regexp"
"strings" "strings"
) )
...@@ -13,10 +16,12 @@ import ( ...@@ -13,10 +16,12 @@ import (
type gitHandler struct { type gitHandler struct {
method string method string
regexp *regexp.Regexp regexp *regexp.Regexp
handle_func func(string, http.ResponseWriter, *http.Request) handle_func func(string, string, http.ResponseWriter, *http.Request)
rpc string rpc string
} }
var repo_root string
var git_handlers = [...]gitHandler{ var git_handlers = [...]gitHandler{
gitHandler{"GET", regexp.MustCompile(`\A(/..*)/info/refs\z`), handle_get_info_refs, ""}, gitHandler{"GET", regexp.MustCompile(`\A(/..*)/info/refs\z`), handle_get_info_refs, ""},
gitHandler{"POST", regexp.MustCompile(`\A(/..*)/git-upload-pack\z`), handle_post_rpc, "git-upload-pack"}, gitHandler{"POST", regexp.MustCompile(`\A(/..*)/git-upload-pack\z`), handle_post_rpc, "git-upload-pack"},
...@@ -24,6 +29,9 @@ var git_handlers = [...]gitHandler{ ...@@ -24,6 +29,9 @@ var git_handlers = [...]gitHandler{
} }
func main() { func main() {
flag.Parse()
repo_root = flag.Arg(0)
log.Printf("repo_root: %s", repo_root)
http.HandleFunc("/", git_handler) http.HandleFunc("/", git_handler)
log.Fatal(http.ListenAndServe(":8080", nil)) log.Fatal(http.ListenAndServe(":8080", nil))
} }
...@@ -31,8 +39,9 @@ func main() { ...@@ -31,8 +39,9 @@ func main() {
func git_handler(w http.ResponseWriter, r *http.Request) { func git_handler(w http.ResponseWriter, r *http.Request) {
log.Print(r) log.Print(r)
for _, g := range git_handlers { for _, g := range git_handlers {
if r.Method == g.method && g.regexp.MatchString(r.URL.Path) { m := g.regexp.FindStringSubmatch(r.URL.Path)
g.handle_func(g.rpc, w, r) if r.Method == g.method && m != nil {
g.handle_func(g.rpc, path.Join(repo_root, m[1]), w, r)
return return
} }
} }
...@@ -40,11 +49,12 @@ func git_handler(w http.ResponseWriter, r *http.Request) { ...@@ -40,11 +49,12 @@ func git_handler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404) w.WriteHeader(404)
} }
func handle_get_info_refs(_ string, w http.ResponseWriter, r *http.Request) { func handle_get_info_refs(_ string, path string, w http.ResponseWriter, r *http.Request) {
rpc := r.URL.Query().Get("service") rpc := r.URL.Query().Get("service")
switch rpc { switch rpc {
case "git-upload-pack", "git-receive-pack": case "git-upload-pack", "git-receive-pack":
cmd := exec.Command("git", strings.TrimPrefix(rpc, "git-"), "--stateless-rpc", "--advertise-refs", "data/foo/bar.git") cmd := exec.Command("git", strings.TrimPrefix(rpc, "git-"), "--stateless-rpc", "--advertise-refs", path)
log.Print(cmd.Args)
stdout, err := cmd.StdoutPipe() stdout, err := cmd.StdoutPipe()
if err != nil { if err != nil {
fail_500(w, err) fail_500(w, err)
...@@ -70,8 +80,20 @@ func handle_get_info_refs(_ string, w http.ResponseWriter, r *http.Request) { ...@@ -70,8 +80,20 @@ func handle_get_info_refs(_ string, w http.ResponseWriter, r *http.Request) {
} }
} }
func handle_post_rpc(rpc string, w http.ResponseWriter, r *http.Request) { func handle_post_rpc(rpc string, path string, w http.ResponseWriter, r *http.Request) {
cmd := exec.Command("git", strings.TrimPrefix(rpc, "git-"), "--stateless-rpc", "data/foo/bar.git") var body io.Reader
var err error
if r.Header.Get("Content-Encoding") == "gzip" {
body, err = gzip.NewReader(r.Body)
if err != nil {
fail_500(w, err)
return
}
} else {
body = r.Body
}
cmd := exec.Command("git", strings.TrimPrefix(rpc, "git-"), "--stateless-rpc", path)
log.Print(cmd.Args)
stdout, err := cmd.StdoutPipe() stdout, err := cmd.StdoutPipe()
if err != nil { if err != nil {
fail_500(w, err) fail_500(w, err)
...@@ -88,7 +110,7 @@ func handle_post_rpc(rpc string, w http.ResponseWriter, r *http.Request) { ...@@ -88,7 +110,7 @@ func handle_post_rpc(rpc string, w http.ResponseWriter, r *http.Request) {
} }
w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-result", rpc)) w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-result", rpc))
no_cache(w) no_cache(w)
if _, err := io.Copy(stdin, r.Body); err != nil { if _, err := io.Copy(stdin, body); err != nil {
fail_500(w, err) fail_500(w, err)
return return
} }
......
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