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
86971fa6
Commit
86971fa6
authored
Nov 02, 2015
by
Jacob Vosmaer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First steps for downloading uploads
parent
ed976a2f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
64 additions
and
19 deletions
+64
-19
Makefile
Makefile
+1
-1
archive.go
archive.go
+5
-0
git-http.go
git-http.go
+10
-0
githandler.go
githandler.go
+6
-18
helpers.go
helpers.go
+11
-0
upload.go
upload.go
+31
-0
No files found.
Makefile
View file @
86971fa6
PREFIX
=
/usr/local
PREFIX
=
/usr/local
VERSION
=
$(
shell
git describe
)
-
$(
shell
date
-u
+%Y%m%d.%H%M%S
)
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
gitlab-workhorse
:
main.go githandler.go archive.go git-http.go helpers.go
upload.go
go build
-ldflags
"-X main.Version
${VERSION}
"
-o
gitlab-workhorse
go build
-ldflags
"-X main.Version
${VERSION}
"
-o
gitlab-workhorse
install
:
gitlab-workhorse
install
:
gitlab-workhorse
...
...
archive.go
View file @
86971fa6
...
@@ -17,6 +17,11 @@ import (
...
@@ -17,6 +17,11 @@ import (
)
)
func
handleGetArchive
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
format
string
)
{
func
handleGetArchive
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
format
string
)
{
if
!
looksLikeRepo
(
r
.
RepoPath
)
{
http
.
Error
(
w
,
"Not Found"
,
404
)
return
}
archiveFilename
:=
path
.
Base
(
r
.
ArchivePath
)
archiveFilename
:=
path
.
Base
(
r
.
ArchivePath
)
if
cachedArchive
,
err
:=
os
.
Open
(
r
.
ArchivePath
);
err
==
nil
{
if
cachedArchive
,
err
:=
os
.
Open
(
r
.
ArchivePath
);
err
==
nil
{
...
...
git-http.go
View file @
86971fa6
...
@@ -13,6 +13,11 @@ import (
...
@@ -13,6 +13,11 @@ import (
)
)
func
handleGetInfoRefs
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
_
string
)
{
func
handleGetInfoRefs
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
_
string
)
{
if
!
looksLikeRepo
(
r
.
RepoPath
)
{
http
.
Error
(
w
,
"Not Found"
,
404
)
return
}
rpc
:=
r
.
URL
.
Query
()
.
Get
(
"service"
)
rpc
:=
r
.
URL
.
Query
()
.
Get
(
"service"
)
if
!
(
rpc
==
"git-upload-pack"
||
rpc
==
"git-receive-pack"
)
{
if
!
(
rpc
==
"git-upload-pack"
||
rpc
==
"git-receive-pack"
)
{
// The 'dumb' Git HTTP protocol is not supported
// The 'dumb' Git HTTP protocol is not supported
...
@@ -57,6 +62,11 @@ func handleGetInfoRefs(w http.ResponseWriter, r *gitRequest, _ string) {
...
@@ -57,6 +62,11 @@ func handleGetInfoRefs(w http.ResponseWriter, r *gitRequest, _ string) {
}
}
func
handlePostRPC
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
rpc
string
)
{
func
handlePostRPC
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
rpc
string
)
{
if
!
looksLikeRepo
(
r
.
RepoPath
)
{
http
.
Error
(
w
,
"Not Found"
,
404
)
return
}
var
body
io
.
ReadCloser
var
body
io
.
ReadCloser
var
err
error
var
err
error
...
...
githandler.go
View file @
86971fa6
...
@@ -11,8 +11,6 @@ import (
...
@@ -11,8 +11,6 @@ import (
"io"
"io"
"log"
"log"
"net/http"
"net/http"
"os"
"path"
"regexp"
"regexp"
"strings"
"strings"
)
)
...
@@ -48,6 +46,10 @@ type gitRequest struct {
...
@@ -48,6 +46,10 @@ type gitRequest struct {
// CommitId is used do prevent race conditions between the 'time of check'
// CommitId is used do prevent race conditions between the 'time of check'
// in the GitLab Rails app and the 'time of use' in gitlab-workhorse.
// in the GitLab Rails app and the 'time of use' in gitlab-workhorse.
CommitId
string
CommitId
string
// ContentPath is a file on disk we can serve to the client
ContentPath
string
// ContentDisposition is used to set the Content-Disposition header
ContentDisposition
string
}
}
// Routing table
// Routing table
...
@@ -60,6 +62,7 @@ var gitServices = [...]gitService{
...
@@ -60,6 +62,7 @@ var gitServices = [...]gitService{
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.tar\z`
),
handleGetArchive
,
"tar"
},
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.gz\z`
),
handleGetArchive
,
"tar.gz"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.tar.bz2\z`
),
handleGetArchive
,
"tar.bz2"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/repository/archive.tar.bz2\z`
),
handleGetArchive
,
"tar.bz2"
},
gitService
{
"GET"
,
regexp
.
MustCompile
(
`/uploads/`
),
handleGetUpload
,
""
},
}
}
func
newGitHandler
(
authBackend
string
,
authTransport
http
.
RoundTripper
)
*
gitHandler
{
func
newGitHandler
(
authBackend
string
,
authTransport
http
.
RoundTripper
)
*
gitHandler
{
...
@@ -95,7 +98,7 @@ func (h *gitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
...
@@ -95,7 +98,7 @@ func (h *gitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}
defer
authResponse
.
Body
.
Close
()
defer
authResponse
.
Body
.
Close
()
if
authResponse
.
StatusCode
!=
200
{
if
authResponse
.
StatusCode
!=
200
||
authResponse
.
Header
.
Get
(
"GitLab-Workhorse"
)
==
"reject"
{
// The Git request is not allowed by the backend. Maybe the
// The Git request is not allowed by the backend. Maybe the
// client needs to send HTTP Basic credentials. Forward the
// client needs to send HTTP Basic credentials. Forward the
// response from the auth backend to our client. This includes
// response from the auth backend to our client. This includes
...
@@ -134,24 +137,9 @@ func (h *gitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
...
@@ -134,24 +137,9 @@ func (h *gitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}
}
}
if
!
looksLikeRepo
(
gitReq
.
RepoPath
)
{
http
.
Error
(
w
,
"Not Found"
,
404
)
return
}
g
.
handleFunc
(
w
,
gitReq
,
g
.
rpc
)
g
.
handleFunc
(
w
,
gitReq
,
g
.
rpc
)
}
}
func
looksLikeRepo
(
p
string
)
bool
{
// If /path/to/foo.git/objects exists then let's assume it is a valid Git
// repository.
if
_
,
err
:=
os
.
Stat
(
path
.
Join
(
p
,
"objects"
));
err
!=
nil
{
log
.
Print
(
err
)
return
false
}
return
true
}
func
(
h
*
gitHandler
)
doAuthRequest
(
r
*
http
.
Request
)
(
result
*
http
.
Response
,
err
error
)
{
func
(
h
*
gitHandler
)
doAuthRequest
(
r
*
http
.
Request
)
(
result
*
http
.
Response
,
err
error
)
{
url
:=
h
.
authBackend
+
r
.
URL
.
RequestURI
()
url
:=
h
.
authBackend
+
r
.
URL
.
RequestURI
()
authReq
,
err
:=
http
.
NewRequest
(
r
.
Method
,
url
,
nil
)
authReq
,
err
:=
http
.
NewRequest
(
r
.
Method
,
url
,
nil
)
...
...
helpers.go
View file @
86971fa6
...
@@ -10,9 +10,20 @@ import (
...
@@ -10,9 +10,20 @@ import (
"net/http"
"net/http"
"os"
"os"
"os/exec"
"os/exec"
"path"
"syscall"
"syscall"
)
)
func
looksLikeRepo
(
p
string
)
bool
{
// If /path/to/foo.git/objects exists then let's assume it is a valid Git
// repository.
if
_
,
err
:=
os
.
Stat
(
path
.
Join
(
p
,
"objects"
));
err
!=
nil
{
log
.
Print
(
err
)
return
false
}
return
true
}
func
fail500
(
w
http
.
ResponseWriter
,
context
string
,
err
error
)
{
func
fail500
(
w
http
.
ResponseWriter
,
context
string
,
err
error
)
{
http
.
Error
(
w
,
"Internal server error"
,
500
)
http
.
Error
(
w
,
"Internal server error"
,
500
)
logContext
(
context
,
err
)
logContext
(
context
,
err
)
...
...
upload.go
0 → 100644
View file @
86971fa6
package
main
import
(
"fmt"
"net/http"
"os"
"path"
)
func
handleGetUpload
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
_
string
)
{
if
r
.
ContentDisposition
==
"attachment"
{
w
.
Header
()
.
Add
(
"Content-Disposition"
,
fmt
.
Sprintf
(
`attachment; filename="%s"`
,
path
.
Base
(
r
.
ContentPath
)))
}
else
{
w
.
Header
()
.
Add
(
"Content-Disposition"
,
r
.
ContentDisposition
)
}
f
,
err
:=
os
.
Open
(
r
.
ContentPath
)
if
err
!=
nil
{
logContext
(
"handleGetUpload open file"
,
err
)
http
.
Error
(
w
,
"Not Found"
,
404
)
return
}
defer
f
.
Close
()
fi
,
err
:=
f
.
Stat
()
if
err
!=
nil
{
fail500
(
w
,
"handleGetUpload get mtime"
,
err
)
return
}
http
.
ServeContent
(
w
,
r
.
Request
,
""
,
fi
.
ModTime
(),
f
)
}
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