We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
package main import ( "compress/gzip" "flag" "fmt" "io" "io/ioutil" "log" "net/http" "os" "os/exec" "path" "regexp" "strings" ) type gitHandler struct { method string regexp *regexp.Regexp handle_func func(string, string, http.ResponseWriter, *http.Request) rpc string } var repo_root string var git_handlers = [...]gitHandler{ 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-receive-pack\z`), handle_post_rpc, "git-receive-pack"}, } func main() { flag.Parse() repo_root = flag.Arg(0) log.Printf("repo_root: %s", repo_root) http.HandleFunc("/", git_handler) log.Fatal(http.ListenAndServe(":8080", nil)) } func git_handler(w http.ResponseWriter, r *http.Request) { log.Print(r) for _, g := range git_handlers { m := g.regexp.FindStringSubmatch(r.URL.Path) if r.Method == g.method && m != nil { g.handle_func(g.rpc, path.Join(repo_root, m[1]), w, r) return } } log.Print("Reached end of dispatch for loop") w.WriteHeader(404) } func handle_get_info_refs(_ string, path string, w http.ResponseWriter, r *http.Request) { rpc := r.URL.Query().Get("service") switch rpc { case "git-upload-pack", "git-receive-pack": w.Header().Set("Content-Type", fmt.Sprintf("application/x-%s-advertisement", rpc)) w.Header().Set("Cache-Control", "no-cache") if err := pktLine(w, fmt.Sprintf("# service=%s\n", rpc)); err != nil { fmt.Errorf("pktLine: %v", err) return } if err := pktFlush(w); err != nil { fmt.Errorf("pktFlush: %v", err) return } cmd := exec.Command("git", strings.TrimPrefix(rpc, "git-"), "--stateless-rpc", "--advertise-refs", path) log.Print(cmd.Args) cmd.Stdin = nil cmd.Stdout = w // stdout, err := cmd.StdoutPipe() // if err != nil { // fail_500(w, err) // return // } if err := cmd.Start(); err != nil { fail_500(w, err) return } // w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-advertisement", rpc)) // no_cache(w) // fmt.Fprintf(w, "%s0000", pkt_line(fmt.Sprintf("# service=%s\n", rpc))) // if _, err := io.Copy(w, stdout); err != nil { // fail_500(w, err) // return // } if err := cmd.Wait(); err != nil { fail_500(w, err) return } case "": log.Print("dumb info refs") } } func handle_post_rpc(rpc string, path string, w http.ResponseWriter, r *http.Request) { 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() if err != nil { fail_500(w, err) return } stdin, err := cmd.StdinPipe() if err != nil { fail_500(w, err) return } if err := cmd.Start(); err != nil { fail_500(w, err) return } w.Header().Add("Content-Type", fmt.Sprintf("application/x-%s-result", rpc)) no_cache(w) if _, err := io.Copy(stdin, body); err != nil { fail_500(w, err) return } stdin.Close() if _, err := io.Copy(w, stdout); err != nil { fail_500(w, err) return } if err := cmd.Wait(); err != nil { fail_500(w, err) return } } func pkt_line(s string) string { return fmt.Sprintf("%04x%s", len(s)+4, s) } func fail_500(w http.ResponseWriter, err error) { w.WriteHeader(500) log.Print(err) } func no_cache(w http.ResponseWriter) { w.Header().Add("Cache-Control", "no-cache") } 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 CleanUpProcessGroup(cmd *exec.Cmd) { // if cmd == nil { // return // } // process := cmd.Process // if process != nil && process.Pid > 0 { // // Send SIGTERM to the process group of cmd // syscall.Kill(-process.Pid, syscall.SIGTERM) // } // // reap our child process // cmd.Wait() // } func ReadAllTempfile(r io.Reader) (tempfile *os.File, err error) { tempfile, err = ioutil.TempFile("", "gitlab-workhorse-read-all-tempfile") if err != nil { return nil, err } defer func() { // Avoid leaking an open file if the function returns with an error if err != nil { tempfile.Close() } }() if err := os.Remove(tempfile.Name()); err != nil { return nil, err } if _, err := io.Copy(tempfile, r); err != nil { return nil, err } if _, err := tempfile.Seek(0, 0); err != nil { return nil, err } return tempfile, nil }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
The text was updated successfully, but these errors were encountered: