Commit ceb58d11 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Merge branch 'master' of https://gitlab.com/gitlab-org/gitlab-workhorse into uploads-check

parents 8cef7d27 e2ba5727
......@@ -2,6 +2,10 @@
Formerly known as 'gitlab-git-http-server'.
0.5.1
Deprecate -relativeURLRoot option, use -authBackend instead.
0.5.0
Send ALL GitLab requests through gitlab-workhorse.
......
......@@ -41,6 +41,16 @@ Gitlab-workhorse can listen on either a TCP or a Unix domain socket. It
can also open a second listening TCP listening socket with the Go
[net/http/pprof profiler server](http://golang.org/pkg/net/http/pprof/).
### Relative URL support
If you are mounting GitLab at a relative URL, e.g.
`example.com/gitlab`, then you should also use this relative URL in
the `authBackend` setting:
```
gitlab-workhorse -authBackend http://localhost:8080/gitlab
```
## Installation
To install into `/usr/local/bin` run `make install`.
......
......@@ -9,7 +9,7 @@ import (
)
func (u *upstream) newUpstreamRequest(r *http.Request, body io.Reader, suffix string) (*http.Request, error) {
url := u.authBackend + r.URL.RequestURI() + suffix
url := u.authBackend + "/" + strings.TrimPrefix(r.URL.RequestURI(), u.relativeURLRoot) + suffix
authReq, err := http.NewRequest(r.Method, url, body)
if err != nil {
return nil, err
......
......@@ -36,7 +36,6 @@ 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")
var documentRoot = flag.String("documentRoot", "public", "Path to static files content")
var responseHeadersTimeout = flag.Duration("proxyHeadersTimeout", time.Minute, "How long to wait for response headers when proxying the request")
var developmentMode = flag.Bool("developmentMode", false, "Allow to serve assets from Rails app")
......@@ -180,6 +179,5 @@ func main() {
}
upstream := newUpstream(*authBackend, proxyTransport)
upstream.SetRelativeURLRoot(*relativeURLRoot)
log.Fatal(http.Serve(listener, upstream))
}
......@@ -13,6 +13,7 @@ import (
"os/exec"
"path"
"regexp"
"strings"
"testing"
"time"
)
......@@ -238,6 +239,29 @@ func TestAllowedApiDownloadZip(t *testing.T) {
runOrFail(t, extractCmd)
}
func TestAllowedApiDownloadZipWithSlash(t *testing.T) {
prepareDownloadDir(t)
// Prepare test server and backend
archiveName := "foobar.zip"
ts := testAuthServer(nil, 200, archiveOkBody(t, archiveName))
defer ts.Close()
ws := startWorkhorseServer(ts.URL)
defer ws.Close()
// Use foo%2Fbar instead of a numeric ID
downloadCmd := exec.Command("curl", "-J", "-O", fmt.Sprintf("%s/api/v3/projects/foo%%2Fbar/repository/archive.zip", ws.URL))
if !strings.Contains(downloadCmd.Args[3], `projects/foo%2Fbar/repository`) {
t.Fatalf("Cannot find percent-2F: %v", downloadCmd.Args)
}
downloadCmd.Dir = scratchDir
runOrFail(t, downloadCmd)
extractCmd := exec.Command("unzip", archiveName)
extractCmd.Dir = scratchDir
runOrFail(t, extractCmd)
}
func TestDownloadCacheHit(t *testing.T) {
prepareDownloadDir(t)
......
......@@ -64,29 +64,30 @@ type gitRequest struct {
}
func newUpstream(authBackend string, authTransport http.RoundTripper) *upstream {
u, err := url.Parse(authBackend)
gitlabURL, err := url.Parse(authBackend)
if err != nil {
log.Fatalln(err)
}
relativeURLRoot := gitlabURL.Path
if !strings.HasSuffix(relativeURLRoot, "/") {
relativeURLRoot += "/"
}
// If the relative URL is '/foobar' and we tell httputil.ReverseProxy to proxy
// to 'http://example.com/foobar' then we get a redirect loop, so we clear the
// Path field here.
gitlabURL.Path = ""
up := &upstream{
authBackend: authBackend,
httpClient: &http.Client{Transport: authTransport},
httpProxy: httputil.NewSingleHostReverseProxy(u),
relativeURLRoot: "/",
httpProxy: httputil.NewSingleHostReverseProxy(gitlabURL),
relativeURLRoot: relativeURLRoot,
}
up.httpProxy.Transport = authTransport
return up
}
func (u *upstream) SetRelativeURLRoot(relativeURLRoot string) {
u.relativeURLRoot = relativeURLRoot
if !strings.HasSuffix(u.relativeURLRoot, "/") {
u.relativeURLRoot += "/"
}
}
func (u *upstream) ServeHTTP(ow http.ResponseWriter, r *http.Request) {
var g httpRoute
......@@ -106,8 +107,8 @@ func (u *upstream) ServeHTTP(ow http.ResponseWriter, r *http.Request) {
}
// Check URL Root
URIPath := cleanURIPath(r.URL.Path)
if !strings.HasPrefix(URIPath, u.relativeURLRoot) {
URIPath := cleanURIPath(r.URL.EscapedPath())
if !strings.HasPrefix(URIPath, u.relativeURLRoot) && URIPath+"/" != u.relativeURLRoot {
httpError(&w, r, fmt.Sprintf("Not found %q", URIPath), http.StatusNotFound)
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