Commit 9e17fc4c authored by Jacob Vosmaer's avatar Jacob Vosmaer

Move git-related code into internal/git package

parent 27900114
...@@ -8,7 +8,7 @@ import ( ...@@ -8,7 +8,7 @@ import (
"net/http" "net/http"
) )
func contentEncodingHandler(h http.HandlerFunc) http.HandlerFunc { func contentEncodingHandler(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
var body io.ReadCloser var body io.ReadCloser
var err error var err error
...@@ -33,6 +33,6 @@ func contentEncodingHandler(h http.HandlerFunc) http.HandlerFunc { ...@@ -33,6 +33,6 @@ func contentEncodingHandler(h http.HandlerFunc) http.HandlerFunc {
r.Body = body r.Body = body
r.Header.Del("Content-Encoding") r.Header.Del("Content-Encoding")
h(w, r) h.ServeHTTP(w, r)
} }
} }
...@@ -28,14 +28,14 @@ func TestGzipEncoding(t *testing.T) { ...@@ -28,14 +28,14 @@ func TestGzipEncoding(t *testing.T) {
} }
req.Header.Set("Content-Encoding", "gzip") req.Header.Set("Content-Encoding", "gzip")
contentEncodingHandler(func(_ http.ResponseWriter, r *http.Request) { contentEncodingHandler(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
if _, ok := r.Body.(*gzip.Reader); !ok { if _, ok := r.Body.(*gzip.Reader); !ok {
t.Fatal("Expected gzip reader for body, but it's:", reflect.TypeOf(r.Body)) t.Fatal("Expected gzip reader for body, but it's:", reflect.TypeOf(r.Body))
} }
if r.Header.Get("Content-Encoding") != "" { if r.Header.Get("Content-Encoding") != "" {
t.Fatal("Content-Encoding should be deleted") t.Fatal("Content-Encoding should be deleted")
} }
})(resp, req) }))(resp, req)
helper.AssertResponseCode(t, resp, 200) helper.AssertResponseCode(t, resp, 200)
} }
...@@ -52,14 +52,14 @@ func TestNoEncoding(t *testing.T) { ...@@ -52,14 +52,14 @@ func TestNoEncoding(t *testing.T) {
} }
req.Header.Set("Content-Encoding", "") req.Header.Set("Content-Encoding", "")
contentEncodingHandler(func(_ http.ResponseWriter, r *http.Request) { contentEncodingHandler(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
if r.Body != body { if r.Body != body {
t.Fatal("Expected the same body") t.Fatal("Expected the same body")
} }
if r.Header.Get("Content-Encoding") != "" { if r.Header.Get("Content-Encoding") != "" {
t.Fatal("Content-Encoding should be deleted") t.Fatal("Content-Encoding should be deleted")
} }
})(resp, req) }))(resp, req)
helper.AssertResponseCode(t, resp, 200) helper.AssertResponseCode(t, resp, 200)
} }
...@@ -73,9 +73,9 @@ func TestInvalidEncoding(t *testing.T) { ...@@ -73,9 +73,9 @@ func TestInvalidEncoding(t *testing.T) {
} }
req.Header.Set("Content-Encoding", "application/unknown") req.Header.Set("Content-Encoding", "application/unknown")
contentEncodingHandler(func(_ http.ResponseWriter, _ *http.Request) { contentEncodingHandler(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
t.Fatal("it shouldn't be executed") t.Fatal("it shouldn't be executed")
})(resp, req) }))(resp, req)
helper.AssertResponseCode(t, resp, 500) helper.AssertResponseCode(t, resp, 500)
} }
...@@ -5,12 +5,8 @@ Miscellaneous helpers: logging, errors, subprocesses ...@@ -5,12 +5,8 @@ Miscellaneous helpers: logging, errors, subprocesses
package main package main
import ( import (
"fmt"
"net/http" "net/http"
"os"
"os/exec"
"path" "path"
"syscall"
) )
func httpError(w http.ResponseWriter, r *http.Request, error string, code int) { func httpError(w http.ResponseWriter, r *http.Request, error string, code int) {
...@@ -22,38 +18,6 @@ func httpError(w http.ResponseWriter, r *http.Request, error string, code int) { ...@@ -22,38 +18,6 @@ func httpError(w http.ResponseWriter, r *http.Request, error string, code int) {
http.Error(w, error, code) http.Error(w, error, code)
} }
// Git subprocess helpers
func gitCommand(gl_id string, 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("HOME=%s", os.Getenv("HOME")),
fmt.Sprintf("PATH=%s", os.Getenv("PATH")),
fmt.Sprintf("LD_LIBRARY_PATH=%s", os.Getenv("LD_LIBRARY_PATH")),
fmt.Sprintf("GL_ID=%s", gl_id),
}
// If we don't do something with cmd.Stderr, Git errors will be lost
cmd.Stderr = os.Stderr
return cmd
}
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()
}
// Borrowed from: net/http/server.go // Borrowed from: net/http/server.go
// Return the canonical path for p, eliminating . and .. elements. // Return the canonical path for p, eliminating . and .. elements.
func cleanURIPath(p string) string { func cleanURIPath(p string) string {
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
In this file we handle 'git archive' downloads In this file we handle 'git archive' downloads
*/ */
package main package git
import ( import (
"./internal/api" "../api"
"./internal/helper" "../helper"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
...@@ -19,6 +19,9 @@ import ( ...@@ -19,6 +19,9 @@ import (
"time" "time"
) )
func GetArchive(a *api.API) http.Handler {
return repoPreAuthorizeHandler(a, handleGetArchive)
}
func handleGetArchive(w http.ResponseWriter, r *http.Request, a *api.Response) { func handleGetArchive(w http.ResponseWriter, r *http.Request, a *api.Response) {
var format string var format string
urlPath := r.URL.Path urlPath := r.URL.Path
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
In this file we handle the Git 'smart HTTP' protocol In this file we handle the Git 'smart HTTP' protocol
*/ */
package main package git
import ( import (
"./internal/api" "../api"
"./internal/helper" "../helper"
"errors" "errors"
"fmt" "fmt"
"io" "io"
...@@ -18,6 +18,14 @@ import ( ...@@ -18,6 +18,14 @@ import (
"strings" "strings"
) )
func GetInfoRefs(a *api.API) http.Handler {
return repoPreAuthorizeHandler(a, handleGetInfoRefs)
}
func PostRPC(a *api.API) http.Handler {
return repoPreAuthorizeHandler(a, handlePostRPC)
}
func looksLikeRepo(p string) bool { func looksLikeRepo(p string) bool {
// If /path/to/foo.git/objects exists then let's assume it is a valid Git // If /path/to/foo.git/objects exists then let's assume it is a valid Git
// repository. // repository.
......
...@@ -15,6 +15,7 @@ package main ...@@ -15,6 +15,7 @@ package main
import ( import (
"./internal/errorpage" "./internal/errorpage"
"./internal/git"
"flag" "flag"
"fmt" "fmt"
"log" "log"
...@@ -65,24 +66,24 @@ func compileRoutes(u *upstream) { ...@@ -65,24 +66,24 @@ func compileRoutes(u *upstream) {
proxy := u.Proxy proxy := u.Proxy
httpRoutes = []httpRoute{ httpRoutes = []httpRoute{
// Git Clone // Git Clone
httpRoute{"GET", regexp.MustCompile(gitProjectPattern + `info/refs\z`), repoPreAuthorizeHandler(api, handleGetInfoRefs)}, httpRoute{"GET", regexp.MustCompile(gitProjectPattern + `info/refs\z`), git.GetInfoRefs(api)},
httpRoute{"POST", regexp.MustCompile(gitProjectPattern + `git-upload-pack\z`), contentEncodingHandler(repoPreAuthorizeHandler(api, handlePostRPC))}, httpRoute{"POST", regexp.MustCompile(gitProjectPattern + `git-upload-pack\z`), contentEncodingHandler(git.PostRPC(api))},
httpRoute{"POST", regexp.MustCompile(gitProjectPattern + `git-receive-pack\z`), contentEncodingHandler(repoPreAuthorizeHandler(api, handlePostRPC))}, httpRoute{"POST", regexp.MustCompile(gitProjectPattern + `git-receive-pack\z`), contentEncodingHandler(git.PostRPC(api))},
httpRoute{"PUT", regexp.MustCompile(gitProjectPattern + `gitlab-lfs/objects/([0-9a-f]{64})/([0-9]+)\z`), lfsAuthorizeHandler(api, handleStoreLfsObject(proxy))}, httpRoute{"PUT", regexp.MustCompile(gitProjectPattern + `gitlab-lfs/objects/([0-9a-f]{64})/([0-9]+)\z`), lfsAuthorizeHandler(api, handleStoreLfsObject(proxy))},
// Repository Archive // Repository Archive
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.zip\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.zip\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar.gz\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar.gz\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar.bz2\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar.bz2\z`), git.GetArchive(api)},
// Repository Archive API // Repository Archive API
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.zip\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.zip\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar.gz\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar.gz\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar.bz2\z`), repoPreAuthorizeHandler(api, handleGetArchive)}, httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar.bz2\z`), git.GetArchive(api)},
// CI Artifacts API // CI Artifacts API
httpRoute{"POST", regexp.MustCompile(ciAPIPattern + `v1/builds/[0-9]+/artifacts\z`), contentEncodingHandler(artifactsAuthorizeHandler(api, handleFileUploads(proxy)))}, httpRoute{"POST", regexp.MustCompile(ciAPIPattern + `v1/builds/[0-9]+/artifacts\z`), contentEncodingHandler(artifactsAuthorizeHandler(api, handleFileUploads(proxy)))},
......
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