Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-workhorse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-workhorse
Commits
43b75c8c
Commit
43b75c8c
authored
Nov 05, 2015
by
Marin Jankovski
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into lfs_support
parents
24041f2e
c2697091
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
50 additions
and
89 deletions
+50
-89
Makefile
Makefile
+1
-1
main.go
main.go
+2
-2
main_test.go
main_test.go
+1
-1
upstream.go
upstream.go
+46
-85
No files found.
Makefile
View file @
43b75c8c
PREFIX
=
/usr/local
VERSION
=
$(
shell
git describe
)
-
$(
shell
date
-u
+%Y%m%d.%H%M%S
)
gitlab-workhorse
:
main.go
githandler
.go archive.go git-http.go helpers.go lfs.go
gitlab-workhorse
:
main.go
upstream
.go archive.go git-http.go helpers.go lfs.go
go build
-ldflags
"-X main.Version
${VERSION}
"
-o
gitlab-workhorse
install
:
gitlab-workhorse
...
...
main.go
View file @
43b75c8c
...
...
@@ -9,7 +9,7 @@ backend (for authentication and authorization) and local disk access
to Git repositories managed by GitLab. In GitLab, this role was previously
performed by gitlab-grack.
In this file we start the web server and hand off to the
gitHandler
type.
In this file we start the web server and hand off to the
upstream
type.
*/
package
main
...
...
@@ -92,6 +92,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
(
"/"
,
new
GitHandler
(
*
authBackend
,
authTransport
))
serveMux
.
Handle
(
"/"
,
new
Upstream
(
*
authBackend
,
authTransport
))
log
.
Fatal
(
http
.
Serve
(
listener
,
serveMux
))
}
main_test.go
View file @
43b75c8c
...
...
@@ -269,7 +269,7 @@ func testAuthServer(code int, body string) *httptest.Server {
}
func
startServerOrFail
(
t
*
testing
.
T
,
ts
*
httptest
.
Server
)
*
exec
.
Cmd
{
cmd
:=
exec
.
Command
(
"go"
,
"run"
,
"main.go"
,
"
githandler
.go"
,
"archive.go"
,
"git-http.go"
,
"helpers.go"
,
"lfs.go"
,
fmt
.
Sprintf
(
"-authBackend=%s"
,
ts
.
URL
),
fmt
.
Sprintf
(
"-listenAddr=%s"
,
servAddr
))
cmd
:=
exec
.
Command
(
"go"
,
"run"
,
"main.go"
,
"
upstream
.go"
,
"archive.go"
,
"git-http.go"
,
"helpers.go"
,
"lfs.go"
,
fmt
.
Sprintf
(
"-authBackend=%s"
,
ts
.
URL
),
fmt
.
Sprintf
(
"-listenAddr=%s"
,
servAddr
))
cmd
.
SysProcAttr
=
&
syscall
.
SysProcAttr
{
Setpgid
:
true
}
cmd
.
Stdout
=
os
.
Stdout
cmd
.
Stderr
=
os
.
Stderr
...
...
githandler
.go
→
upstream
.go
View file @
43b75c8c
/*
The
gitHandler
type implements http.Handler.
The
upstream
type implements http.Handler.
In this file we handle request routing and interaction with the authBackend.
*/
...
...
@@ -17,7 +17,7 @@ import (
"strings"
)
type
gitHandler
struct
{
type
upstream
struct
{
httpClient
*
http
.
Client
authBackend
string
}
...
...
@@ -25,7 +25,8 @@ type gitHandler struct {
type
gitService
struct
{
method
string
regex
*
regexp
.
Regexp
handleFunc
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
rpc
string
)
*
gitRequest
middlewareFunc
func
(
u
*
upstream
,
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
handleFunc
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
rpc
string
),
rpc
string
)
handleFunc
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
rpc
string
)
rpc
string
}
...
...
@@ -55,23 +56,23 @@ type gitRequest struct {
// Routing table
var
gitServices
=
[
...
]
gitService
{
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/info/refs\z`
),
handleGetInfoRefs
,
""
},
gitService
{
"POST"
,
regexp
.
MustCompile
(
`/git-upload-pack\z`
),
handlePostRPC
,
"git-upload-pack"
},
gitService
{
"POST"
,
regexp
.
MustCompile
(
`/git-receive-pack\z`
),
handlePostRPC
,
"git-receive-pack"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive\z`
),
handleGetArchive
,
"tar.gz"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.zip\z`
),
handleGetArchive
,
"zip"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.tar\z`
),
handleGetArchive
,
"tar"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.tar.gz\z`
),
handleGetArchive
,
"tar.gz"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.tar.bz2\z`
),
handleGetArchive
,
"tar.bz2"
},
gitService
{
"PUT"
,
regexp
.
MustCompile
(
`/gitlab-lfs/objects/([0-9a-f]{64})/([0-9]+)\z`
),
handleStoreLfsObject
,
"lfs-object-receive"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/gitlab-lfs/objects/([0-9a-f]{64})\z`
),
handleRetreiveLfsObject
,
"lfs-object-upload"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/info/refs\z`
),
repoPreAuth
,
handleGetInfoRefs
,
""
},
gitService
{
"POST"
,
regexp
.
MustCompile
(
`/git-upload-pack\z`
),
repoPreAuth
,
handlePostRPC
,
"git-upload-pack"
},
gitService
{
"POST"
,
regexp
.
MustCompile
(
`/git-receive-pack\z`
),
repoPreAuth
,
handlePostRPC
,
"git-receive-pack"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive\z`
),
repoPreAuth
,
handleGetArchive
,
"tar.gz"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.zip\z`
),
repoPreAuth
,
handleGetArchive
,
"zip"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.tar\z`
),
repoPreAuth
,
handleGetArchive
,
"tar"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.tar.gz\z`
),
repoPreAuth
,
handleGetArchive
,
"tar.gz"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.tar.bz2\z`
),
repoPreAuth
,
handleGetArchive
,
"tar.bz2"
},
gitService
{
"PUT"
,
regexp
.
MustCompile
(
`/gitlab-lfs/objects/([0-9a-f]{64})/([0-9]+)\z`
),
repoPreAuth
,
handleStoreLfsObject
,
"lfs-object-receive"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/gitlab-lfs/objects/([0-9a-f]{64})\z`
),
repoPreAuth
,
handleRetreiveLfsObject
,
"lfs-object-upload"
},
}
func
new
GitHandler
(
authBackend
string
,
authTransport
http
.
RoundTripper
)
*
gitHandler
{
return
&
gitHandler
{
&
http
.
Client
{
Transport
:
authTransport
},
authBackend
}
func
new
Upstream
(
authBackend
string
,
authTransport
http
.
RoundTripper
)
*
upstream
{
return
&
upstream
{
&
http
.
Client
{
Transport
:
authTransport
},
authBackend
}
}
func
(
h
*
gitHandler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
(
u
*
upstream
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
var
g
gitService
log
.
Printf
(
"%s %q"
,
r
.
Method
,
r
.
URL
)
...
...
@@ -91,9 +92,31 @@ func (h *gitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
// Ask the auth backend if the request is allowed, and what the
// user ID (GL_ID) is.
authResponse
,
err
:=
h
.
doAuthRequest
(
r
)
g
.
middlewareFunc
(
u
,
w
,
r
,
g
.
handleFunc
,
g
.
rpc
)
}
func
repoPreAuth
(
u
*
upstream
,
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
handleFunc
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
rpc
string
),
rpc
string
)
{
url
:=
u
.
authBackend
+
r
.
URL
.
RequestURI
()
authReq
,
err
:=
http
.
NewRequest
(
r
.
Method
,
url
,
nil
)
if
err
!=
nil
{
fail500
(
w
,
"doAuthRequest"
,
err
)
return
}
// Forward all headers from our client to the auth backend. This includes
// HTTP Basic authentication credentials (the 'Authorization' header).
for
k
,
v
:=
range
r
.
Header
{
authReq
.
Header
[
k
]
=
v
}
// Also forward the Host header, which is excluded from the Header map by the http libary.
// This allows the Host header received by the backend to be consistent with other
// requests not going through gitlab-workhorse.
authReq
.
Host
=
r
.
Host
// Set a custom header for the request. This can be used in some
// configurations (Passenger) to solve auth request routing problems.
authReq
.
Header
.
Set
(
"GitLab-Git-HTTP-Server"
,
Version
)
authResponse
,
err
:=
u
.
httpClient
.
Do
(
authReq
)
if
err
!=
nil
{
fail500
(
w
,
"doAuthRequest"
,
err
)
return
...
...
@@ -144,17 +167,7 @@ func (h *gitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
callback
:=
g
.
handleFunc
(
w
,
gitReq
,
g
.
rpc
)
if
callback
==
nil
{
return
}
h
.
doCallback
(
w
,
callback
)
// _, err := h.doCallback(w, callback)
// h.doCallback(w, callback)
// if err != nil
// return nil, err
// }
handleFunc
(
w
,
gitReq
,
rpc
)
}
func
looksLikeRepo
(
p
string
)
bool
{
...
...
@@ -167,55 +180,3 @@ func looksLikeRepo(p string) bool {
return
true
}
func
(
h
*
gitHandler
)
doAuthRequest
(
r
*
http
.
Request
)
(
result
*
http
.
Response
,
err
error
)
{
url
:=
h
.
authBackend
+
r
.
URL
.
RequestURI
()
authReq
,
err
:=
http
.
NewRequest
(
r
.
Method
,
url
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
// Forward all headers from our client to the auth backend. This includes
// HTTP Basic authentication credentials (the 'Authorization' header).
for
k
,
v
:=
range
r
.
Header
{
authReq
.
Header
[
k
]
=
v
}
// Also forward the Host header, which is excluded from the Header map by the http libary.
// This allows the Host header received by the backend to be consistent with other
// requests not going through gitlab-workhorse.
authReq
.
Host
=
r
.
Host
// Set a custom header for the request. This can be used in some
// configurations (Passenger) to solve auth request routing problems.
authReq
.
Header
.
Set
(
"GitLab-Git-HTTP-Server"
,
Version
)
return
h
.
httpClient
.
Do
(
authReq
)
}
func
(
h
*
gitHandler
)
doCallback
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
(
result
*
http
.
Response
,
err
error
)
{
url
:=
h
.
authBackend
+
r
.
URL
.
RequestURI
()
+
"/callback"
callbackReq
:=
doRequest
(
r
,
url
)
if
callbackReq
!=
nil
{
return
h
.
httpClient
.
Do
(
callbackReq
)
}
return
}
func
doRequest
(
r
*
gitRequest
,
url
string
)
(
request
*
http
.
Request
)
{
request
,
err
:=
http
.
NewRequest
(
r
.
Method
,
url
,
nil
)
if
err
!=
nil
{
return
nil
}
// Forward all headers from our client to the auth backend. This includes
// HTTP Basic authentication credentials (the 'Authorization' header).
for
k
,
v
:=
range
r
.
Header
{
request
.
Header
[
k
]
=
v
}
// Also forward the Host header, which is excluded from the Header map by the http libary.
// This allows the Host header received by the backend to be consistent with other
// requests not going through gitlab-workhorse.
request
.
Host
=
r
.
Host
// Set a custom header for the request. This can be used in some
// configurations (Passenger) to solve auth request routing problems.
request
.
Header
.
Set
(
"GitLab-Git-HTTP-Server"
,
Version
)
return
request
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment