diff --git a/error_pages.go b/error_pages.go index 26364f21e56da7c7365798fde028089653de3a85..4f09ff2b705493279c70db5c66ca882d42df85ba 100644 --- a/error_pages.go +++ b/error_pages.go @@ -3,8 +3,8 @@ package main import ( "fmt" "io/ioutil" - "net/http" "log" + "net/http" ) type errorPageResponseWriter struct { diff --git a/main.go b/main.go index 7956f5c64c236c359d91a2cb72869bbb08d75281..7bc445bf8e264ac8baaedcc115a5db5117b59c2e 100644 --- a/main.go +++ b/main.go @@ -22,6 +22,7 @@ import ( _ "net/http/pprof" "os" "regexp" + "strings" "syscall" "time" ) @@ -35,6 +36,7 @@ var listenUmask = flag.Int("listenUmask", 022, "Umask for Unix socket, default: var authBackend = flag.String("authBackend", "http://localhost:8080", "Authentication/authorization backend") var authSocket = flag.String("authSocket", "", "Optional: Unix domain socket to dial authBackend at") var pprofListenAddr = flag.String("pprofListenAddr", "", "pprof listening address, e.g. 'localhost:6060'") +var relativeUrlRoot = flag.String("relativeUrlRoot", "/", "GitLab relative URL root") type httpRoute struct { method string @@ -84,6 +86,10 @@ func main() { os.Exit(0) } + if !strings.HasSuffix(*relativeUrlRoot, "/") { + *relativeUrlRoot += "/" + } + log.Printf("Starting %s", version) // Good housekeeping for Unix sockets: unlink before binding @@ -128,6 +134,6 @@ func main() { // Because net/http/pprof installs itself in the DefaultServeMux // we create a fresh one for the Git server. serveMux := http.NewServeMux() - serveMux.Handle("/", newUpstream(*authBackend, authTransport)) + serveMux.Handle(*relativeUrlRoot, newUpstream(*authBackend, authTransport)) log.Fatal(http.Serve(listener, serveMux)) } diff --git a/sendfile.go b/sendfile.go index 39cc6227ed594976957cc90a7e6c44b78406d31f..4b77eff94134c20c814d38ff59f465b93a1fbca5 100644 --- a/sendfile.go +++ b/sendfile.go @@ -22,8 +22,8 @@ type sendFileResponseWriter struct { func newSendFileResponseWriter(rw http.ResponseWriter, req *http.Request) *sendFileResponseWriter { s := &sendFileResponseWriter{ - rw: rw, - req: req, + rw: rw, + req: req, } req.Header.Set("X-Sendfile-Type", "X-Sendfile") return s diff --git a/servefile.go b/servefile.go index bd7998575d8193a9e89b60ee584aa32d87e1d392..497bb8441c2c11f963d7840f1d993b7ba19865f1 100644 --- a/servefile.go +++ b/servefile.go @@ -16,7 +16,7 @@ func handleServeFile(rootDir string, notFoundHandler serviceHandleFunc) serviceH } return func(w http.ResponseWriter, r *gitRequest) { - file := filepath.Join(rootDir, r.URL.Path) + file := filepath.Join(rootDir, r.relativeUriPath) file, err := filepath.Abs(file) if err != nil { fail500(w, fmt.Errorf("invalid path:"+file, err)) diff --git a/upstream.go b/upstream.go index ebc3681566e674572e55ccdb1f4457019865e7db..6a4b03feb98d002c16e4cac80fda702dcb6c7507 100644 --- a/upstream.go +++ b/upstream.go @@ -11,6 +11,7 @@ import ( "net/http" "net/http/httputil" "net/url" + "strings" ) type serviceHandleFunc func(w http.ResponseWriter, r *gitRequest) @@ -53,6 +54,7 @@ type authorizationResponse struct { // GitLab Rails application. type gitRequest struct { *http.Request + relativeUriPath string authorizationResponse u *upstream } @@ -78,6 +80,9 @@ func (u *upstream) ServeHTTP(ow http.ResponseWriter, r *http.Request) { w := newLoggingResponseWriter(ow) defer w.Log(r) + // Strip prefix and add "/" + relativeUriPath := "/" + strings.TrimPrefix(r.RequestURI, *relativeUrlRoot) + // Look for a matching Git service foundService := false for _, g = range httpRoutes { @@ -85,7 +90,7 @@ func (u *upstream) ServeHTTP(ow http.ResponseWriter, r *http.Request) { continue } - if g.regex == nil || g.regex.MatchString(r.URL.Path) { + if g.regex == nil || g.regex.MatchString(relativeUriPath) { foundService = true break } @@ -98,8 +103,9 @@ func (u *upstream) ServeHTTP(ow http.ResponseWriter, r *http.Request) { } request := gitRequest{ - Request: r, - u: u, + Request: r, + relativeUriPath: relativeUriPath, + u: u, } g.handleFunc(w, &request)