Commit 4194124c authored by Jacob Vosmaer's avatar Jacob Vosmaer

Move routes into upstream

parent 9e17fc4c
......@@ -14,8 +14,6 @@ In this file we start the web server and hand off to the upstream type.
package main
import (
"./internal/errorpage"
"./internal/git"
"flag"
"fmt"
"log"
......@@ -23,7 +21,6 @@ import (
"net/http"
_ "net/http/pprof"
"os"
"regexp"
"syscall"
"time"
)
......@@ -42,82 +39,6 @@ var documentRoot = flag.String("documentRoot", "public", "Path to static files c
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")
type httpRoute struct {
method string
regex *regexp.Regexp
handler http.Handler
}
const projectPattern = `^/[^/]+/[^/]+/`
const gitProjectPattern = `^/[^/]+/[^/]+\.git/`
const apiPattern = `^/api/`
const projectsAPIPattern = `^/api/v3/projects/[^/]+/`
const ciAPIPattern = `^/ci/api/`
// Routing table
// We match against URI not containing the relativeUrlRoot:
// see upstream.ServeHTTP
var httpRoutes []httpRoute
func compileRoutes(u *upstream) {
api := u.API
proxy := u.Proxy
httpRoutes = []httpRoute{
// Git Clone
httpRoute{"GET", regexp.MustCompile(gitProjectPattern + `info/refs\z`), git.GetInfoRefs(api)},
httpRoute{"POST", regexp.MustCompile(gitProjectPattern + `git-upload-pack\z`), contentEncodingHandler(git.PostRPC(api))},
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))},
// Repository Archive
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.zip\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar.gz\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar.bz2\z`), git.GetArchive(api)},
// Repository Archive API
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.zip\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar.gz\z`), git.GetArchive(api)},
httpRoute{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar.bz2\z`), git.GetArchive(api)},
// CI Artifacts API
httpRoute{"POST", regexp.MustCompile(ciAPIPattern + `v1/builds/[0-9]+/artifacts\z`), contentEncodingHandler(artifactsAuthorizeHandler(api, handleFileUploads(proxy)))},
// Explicitly proxy API requests
httpRoute{"", regexp.MustCompile(apiPattern), proxy},
httpRoute{"", regexp.MustCompile(ciAPIPattern), proxy},
// Serve assets
httpRoute{"", regexp.MustCompile(`^/assets/`),
u.handleServeFile(documentRoot, CacheExpireMax,
handleDevelopmentMode(developmentMode,
handleDeployPage(documentRoot,
errorpage.Inject(*documentRoot,
proxy,
),
),
),
),
},
// Serve static files or forward the requests
httpRoute{"", nil,
u.handleServeFile(documentRoot, CacheDisabled,
handleDeployPage(documentRoot,
errorpage.Inject(*documentRoot,
proxy,
),
),
),
},
}
}
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
......@@ -159,7 +80,5 @@ func main() {
}()
}
upstream := newUpstream(*authBackend, *authSocket)
compileRoutes(upstream)
log.Fatal(http.Serve(listener, upstream))
log.Fatal(http.Serve(listener, newUpstream(*authBackend, *authSocket)))
}
......@@ -328,7 +328,6 @@ func testAuthServer(url *regexp.Regexp, code int, body interface{}) *httptest.Se
func startWorkhorseServer(authBackend string) *httptest.Server {
u := newUpstream(authBackend, "")
compileRoutes(u)
return httptest.NewServer(u)
}
......
......@@ -8,12 +8,15 @@ package main
import (
"./internal/api"
"./internal/errorpage"
"./internal/git"
"./internal/proxy"
"fmt"
"log"
"net"
"net/http"
"net/url"
"regexp"
"strings"
"time"
)
......@@ -23,6 +26,81 @@ type upstream struct {
Proxy *proxy.Proxy
authBackend string
relativeURLRoot string
routes []route
}
type route struct {
method string
regex *regexp.Regexp
handler http.Handler
}
const projectPattern = `^/[^/]+/[^/]+/`
const gitProjectPattern = `^/[^/]+/[^/]+\.git/`
const apiPattern = `^/api/`
const projectsAPIPattern = `^/api/v3/projects/[^/]+/`
const ciAPIPattern = `^/ci/api/`
// Routing table
// We match against URI not containing the relativeUrlRoot:
// see upstream.ServeHTTP
var routes []route
func (u *upstream) compileRoutes() {
u.routes = []route{
// Git Clone
route{"GET", regexp.MustCompile(gitProjectPattern + `info/refs\z`), git.GetInfoRefs(u.API)},
route{"POST", regexp.MustCompile(gitProjectPattern + `git-upload-pack\z`), contentEncodingHandler(git.PostRPC(u.API))},
route{"POST", regexp.MustCompile(gitProjectPattern + `git-receive-pack\z`), contentEncodingHandler(git.PostRPC(u.API))},
route{"PUT", regexp.MustCompile(gitProjectPattern + `gitlab-lfs/objects/([0-9a-f]{64})/([0-9]+)\z`), lfsAuthorizeHandler(u.API, handleStoreLfsObject(u.Proxy))},
// Repository Archive
route{"GET", regexp.MustCompile(projectPattern + `repository/archive\z`), git.GetArchive(u.API)},
route{"GET", regexp.MustCompile(projectPattern + `repository/archive.zip\z`), git.GetArchive(u.API)},
route{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar\z`), git.GetArchive(u.API)},
route{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar.gz\z`), git.GetArchive(u.API)},
route{"GET", regexp.MustCompile(projectPattern + `repository/archive.tar.bz2\z`), git.GetArchive(u.API)},
// Repository Archive API
route{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive\z`), git.GetArchive(u.API)},
route{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.zip\z`), git.GetArchive(u.API)},
route{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar\z`), git.GetArchive(u.API)},
route{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar.gz\z`), git.GetArchive(u.API)},
route{"GET", regexp.MustCompile(projectsAPIPattern + `repository/archive.tar.bz2\z`), git.GetArchive(u.API)},
// CI Artifacts API
route{"POST", regexp.MustCompile(ciAPIPattern + `v1/builds/[0-9]+/artifacts\z`), contentEncodingHandler(artifactsAuthorizeHandler(u.API, handleFileUploads(u.Proxy)))},
// Explicitly u.Proxy API requests
route{"", regexp.MustCompile(apiPattern), u.Proxy},
route{"", regexp.MustCompile(ciAPIPattern), u.Proxy},
// Serve assets
route{"", regexp.MustCompile(`^/assets/`),
u.handleServeFile(documentRoot, CacheExpireMax,
handleDevelopmentMode(developmentMode,
handleDeployPage(documentRoot,
errorpage.Inject(*documentRoot,
u.Proxy,
),
),
),
),
},
// Serve static files or forward the requests
route{"", nil,
u.handleServeFile(documentRoot, CacheDisabled,
handleDeployPage(documentRoot,
errorpage.Inject(*documentRoot,
u.Proxy,
),
),
),
},
}
}
func newUpstream(authBackend string, authSocket string) *upstream {
......@@ -63,7 +141,7 @@ func newUpstream(authBackend string, authSocket string) *upstream {
Proxy: proxy.NewProxy(parsedURL, proxyTransport, Version),
relativeURLRoot: relativeURLRoot,
}
up.compileRoutes()
return up
}
......@@ -72,7 +150,7 @@ func (u *upstream) relativeURIPath(p string) string {
}
func (u *upstream) ServeHTTP(ow http.ResponseWriter, r *http.Request) {
var g httpRoute
var g route
w := newLoggingResponseWriter(ow)
defer w.Log(r)
......@@ -98,7 +176,7 @@ func (u *upstream) ServeHTTP(ow http.ResponseWriter, r *http.Request) {
// Look for a matching Git service
foundService := false
for _, g = range httpRoutes {
for _, g = range u.routes {
if g.method != "" && r.Method != g.method {
continue
}
......
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