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
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gitlab-workhorse
Commits
37b49c54
Commit
37b49c54
authored
Dec 08, 2015
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master' into x-blob-raw
parents
ad2b32f0
d1b215d5
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
63 additions
and
61 deletions
+63
-61
archive.go
archive.go
+14
-12
authorization.go
authorization.go
+5
-4
git-http.go
git-http.go
+13
-13
handlers.go
handlers.go
+1
-1
helpers.go
helpers.go
+6
-6
lfs.go
lfs.go
+10
-14
proxy.go
proxy.go
+3
-2
uploads.go
uploads.go
+5
-4
xsendfile.go
xsendfile.go
+6
-5
No files found.
archive.go
View file @
37b49c54
...
@@ -5,7 +5,6 @@ In this file we handle 'git archive' downloads
...
@@ -5,7 +5,6 @@ In this file we handle 'git archive' downloads
package
main
package
main
import
(
import
(
"errors"
"fmt"
"fmt"
"io"
"io"
"io/ioutil"
"io/ioutil"
...
@@ -20,7 +19,8 @@ import (
...
@@ -20,7 +19,8 @@ import (
func
handleGetArchive
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
func
handleGetArchive
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
var
format
string
var
format
string
switch
filepath
.
Base
(
r
.
URL
.
Path
)
{
urlPath
:=
r
.
URL
.
Path
switch
filepath
.
Base
(
urlPath
)
{
case
"archive.zip"
:
case
"archive.zip"
:
format
=
"zip"
format
=
"zip"
case
"archive.tar"
:
case
"archive.tar"
:
...
@@ -30,7 +30,8 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
...
@@ -30,7 +30,8 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
case
"archive.tar.bz2"
:
case
"archive.tar.bz2"
:
format
=
"tar.bz2"
format
=
"tar.bz2"
default
:
default
:
fail500
(
w
,
"handleGetArchive"
,
errors
.
New
(
"invalid archive format"
))
fail500
(
w
,
fmt
.
Errorf
(
"handleGetArchive: invalid format: %s"
,
urlPath
))
return
}
}
archiveFilename
:=
path
.
Base
(
r
.
ArchivePath
)
archiveFilename
:=
path
.
Base
(
r
.
ArchivePath
)
...
@@ -52,7 +53,8 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
...
@@ -52,7 +53,8 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
// to finalize the cached archive.
// to finalize the cached archive.
tempFile
,
err
:=
prepareArchiveTempfile
(
path
.
Dir
(
r
.
ArchivePath
),
archiveFilename
)
tempFile
,
err
:=
prepareArchiveTempfile
(
path
.
Dir
(
r
.
ArchivePath
),
archiveFilename
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"handleGetArchive create tempfile for archive"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleGetArchive: create tempfile: %v"
,
err
))
return
}
}
defer
tempFile
.
Close
()
defer
tempFile
.
Close
()
defer
os
.
Remove
(
tempFile
.
Name
())
defer
os
.
Remove
(
tempFile
.
Name
())
...
@@ -62,12 +64,12 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
...
@@ -62,12 +64,12 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
archiveCmd
:=
gitCommand
(
""
,
"git"
,
"--git-dir="
+
r
.
RepoPath
,
"archive"
,
"--format="
+
archiveFormat
,
"--prefix="
+
r
.
ArchivePrefix
+
"/"
,
r
.
CommitId
)
archiveCmd
:=
gitCommand
(
""
,
"git"
,
"--git-dir="
+
r
.
RepoPath
,
"archive"
,
"--format="
+
archiveFormat
,
"--prefix="
+
r
.
ArchivePrefix
+
"/"
,
r
.
CommitId
)
archiveStdout
,
err
:=
archiveCmd
.
StdoutPipe
()
archiveStdout
,
err
:=
archiveCmd
.
StdoutPipe
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"handleGetArchive"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleGetArchive: archive stdout: %v"
,
err
)
)
return
return
}
}
defer
archiveStdout
.
Close
()
defer
archiveStdout
.
Close
()
if
err
:=
archiveCmd
.
Start
();
err
!=
nil
{
if
err
:=
archiveCmd
.
Start
();
err
!=
nil
{
fail500
(
w
,
"handleGetArchive"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleGetArchive: start %v: %v"
,
archiveCmd
.
Args
,
err
)
)
return
return
}
}
defer
cleanUpProcessGroup
(
archiveCmd
)
// Ensure brute force subprocess clean-up
defer
cleanUpProcessGroup
(
archiveCmd
)
// Ensure brute force subprocess clean-up
...
@@ -80,13 +82,13 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
...
@@ -80,13 +82,13 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
stdout
,
err
=
compressCmd
.
StdoutPipe
()
stdout
,
err
=
compressCmd
.
StdoutPipe
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"handleGetArchive compressCmd stdout pipe"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleGetArchive: compress stdout: %v"
,
err
)
)
return
return
}
}
defer
stdout
.
Close
()
defer
stdout
.
Close
()
if
err
:=
compressCmd
.
Start
();
err
!=
nil
{
if
err
:=
compressCmd
.
Start
();
err
!=
nil
{
fail500
(
w
,
"handleGetArchive start compressCmd process"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleGetArchive: start %v: %v"
,
compressCmd
.
Args
,
err
)
)
return
return
}
}
defer
compressCmd
.
Wait
()
defer
compressCmd
.
Wait
()
...
@@ -101,22 +103,22 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
...
@@ -101,22 +103,22 @@ func handleGetArchive(w http.ResponseWriter, r *gitRequest) {
setArchiveHeaders
(
w
,
format
,
archiveFilename
)
setArchiveHeaders
(
w
,
format
,
archiveFilename
)
w
.
WriteHeader
(
200
)
// Don't bother with HTTP 500 from this point on, just return
w
.
WriteHeader
(
200
)
// Don't bother with HTTP 500 from this point on, just return
if
_
,
err
:=
io
.
Copy
(
w
,
archiveReader
);
err
!=
nil
{
if
_
,
err
:=
io
.
Copy
(
w
,
archiveReader
);
err
!=
nil
{
log
Context
(
"handleGetArchive read from subprocess"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handleGetArchive: read: %v"
,
err
)
)
return
return
}
}
if
err
:=
archiveCmd
.
Wait
();
err
!=
nil
{
if
err
:=
archiveCmd
.
Wait
();
err
!=
nil
{
log
Context
(
"handleGetArchive wait for archiveCmd"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handleGetArchive: archiveCmd: %v"
,
err
)
)
return
return
}
}
if
compressCmd
!=
nil
{
if
compressCmd
!=
nil
{
if
err
:=
compressCmd
.
Wait
();
err
!=
nil
{
if
err
:=
compressCmd
.
Wait
();
err
!=
nil
{
log
Context
(
"handleGetArchive wait for compressCmd"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handleGetArchive: compressCmd: %v"
,
err
)
)
return
return
}
}
}
}
if
err
:=
finalizeCachedArchive
(
tempFile
,
r
.
ArchivePath
);
err
!=
nil
{
if
err
:=
finalizeCachedArchive
(
tempFile
,
r
.
ArchivePath
);
err
!=
nil
{
log
Context
(
"handleGetArchive finalize cached archive"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handleGetArchive: finalize cached archive: %v"
,
err
)
)
return
return
}
}
}
}
...
...
authorization.go
View file @
37b49c54
...
@@ -3,6 +3,7 @@ package main
...
@@ -3,6 +3,7 @@ package main
import
(
import
(
"encoding/json"
"encoding/json"
"errors"
"errors"
"fmt"
"io"
"io"
"net/http"
"net/http"
"strings"
"strings"
...
@@ -12,13 +13,13 @@ func preAuthorizeHandler(handleFunc serviceHandleFunc, suffix string) serviceHan
...
@@ -12,13 +13,13 @@ func preAuthorizeHandler(handleFunc serviceHandleFunc, suffix string) serviceHan
return
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
return
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
authReq
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
nil
,
suffix
)
authReq
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
nil
,
suffix
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"newUpstreamRequest"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"preAuthorizeHandler: newUpstreamRequest: %v"
,
err
)
)
return
return
}
}
authResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
authReq
)
authResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
authReq
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"doAuthRequest"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"preAuthorizeHandler: do %v: %v"
,
authReq
.
URL
.
Path
,
err
)
)
return
return
}
}
defer
authResponse
.
Body
.
Close
()
defer
authResponse
.
Body
.
Close
()
...
@@ -46,7 +47,7 @@ func preAuthorizeHandler(handleFunc serviceHandleFunc, suffix string) serviceHan
...
@@ -46,7 +47,7 @@ func preAuthorizeHandler(handleFunc serviceHandleFunc, suffix string) serviceHan
// request metadata. We must extract this information from the auth
// request metadata. We must extract this information from the auth
// response body.
// response body.
if
err
:=
json
.
NewDecoder
(
authResponse
.
Body
)
.
Decode
(
&
r
.
authorizationResponse
);
err
!=
nil
{
if
err
:=
json
.
NewDecoder
(
authResponse
.
Body
)
.
Decode
(
&
r
.
authorizationResponse
);
err
!=
nil
{
fail500
(
w
,
"decode authorization response"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"preAuthorizeHandler: decode authorization response: %v"
,
err
)
)
return
return
}
}
// Don't hog a TCP connection in CLOSE_WAIT, we can already close it now
// Don't hog a TCP connection in CLOSE_WAIT, we can already close it now
...
@@ -68,7 +69,7 @@ func preAuthorizeHandler(handleFunc serviceHandleFunc, suffix string) serviceHan
...
@@ -68,7 +69,7 @@ func preAuthorizeHandler(handleFunc serviceHandleFunc, suffix string) serviceHan
func
repoPreAuthorizeHandler
(
handleFunc
serviceHandleFunc
)
serviceHandleFunc
{
func
repoPreAuthorizeHandler
(
handleFunc
serviceHandleFunc
)
serviceHandleFunc
{
return
preAuthorizeHandler
(
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
return
preAuthorizeHandler
(
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
if
r
.
RepoPath
==
""
{
if
r
.
RepoPath
==
""
{
fail500
(
w
,
"repoPreAuthorizeHandler"
,
errors
.
New
(
"missing authorization response
"
))
fail500
(
w
,
errors
.
New
(
"repoPreAuthorizeHandler: RepoPath empty
"
))
return
return
}
}
...
...
git-http.go
View file @
37b49c54
...
@@ -24,12 +24,12 @@ func handleGetInfoRefs(w http.ResponseWriter, r *gitRequest) {
...
@@ -24,12 +24,12 @@ func handleGetInfoRefs(w http.ResponseWriter, r *gitRequest) {
cmd
:=
gitCommand
(
r
.
GL_ID
,
"git"
,
subCommand
(
rpc
),
"--stateless-rpc"
,
"--advertise-refs"
,
r
.
RepoPath
)
cmd
:=
gitCommand
(
r
.
GL_ID
,
"git"
,
subCommand
(
rpc
),
"--stateless-rpc"
,
"--advertise-refs"
,
r
.
RepoPath
)
stdout
,
err
:=
cmd
.
StdoutPipe
()
stdout
,
err
:=
cmd
.
StdoutPipe
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"handleGetInfoRefs"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleGetInfoRefs: stdout: %v"
,
err
)
)
return
return
}
}
defer
stdout
.
Close
()
defer
stdout
.
Close
()
if
err
:=
cmd
.
Start
();
err
!=
nil
{
if
err
:=
cmd
.
Start
();
err
!=
nil
{
fail500
(
w
,
"handleGetInfoRefs"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleGetInfoRefs: start %v: %v"
,
cmd
.
Args
,
err
)
)
return
return
}
}
defer
cleanUpProcessGroup
(
cmd
)
// Ensure brute force subprocess clean-up
defer
cleanUpProcessGroup
(
cmd
)
// Ensure brute force subprocess clean-up
...
@@ -39,19 +39,19 @@ func handleGetInfoRefs(w http.ResponseWriter, r *gitRequest) {
...
@@ -39,19 +39,19 @@ func handleGetInfoRefs(w http.ResponseWriter, r *gitRequest) {
w
.
Header
()
.
Add
(
"Cache-Control"
,
"no-cache"
)
w
.
Header
()
.
Add
(
"Cache-Control"
,
"no-cache"
)
w
.
WriteHeader
(
200
)
// Don't bother with HTTP 500 from this point on, just return
w
.
WriteHeader
(
200
)
// Don't bother with HTTP 500 from this point on, just return
if
err
:=
pktLine
(
w
,
fmt
.
Sprintf
(
"# service=%s
\n
"
,
rpc
));
err
!=
nil
{
if
err
:=
pktLine
(
w
,
fmt
.
Sprintf
(
"# service=%s
\n
"
,
rpc
));
err
!=
nil
{
log
Context
(
"handleGetInfoRefs response"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handleGetInfoRefs: pktLine: %v"
,
err
)
)
return
return
}
}
if
err
:=
pktFlush
(
w
);
err
!=
nil
{
if
err
:=
pktFlush
(
w
);
err
!=
nil
{
log
Context
(
"handleGetInfoRefs response"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handleGetInfoRefs: pktFlush: %v"
,
err
)
)
return
return
}
}
if
_
,
err
:=
io
.
Copy
(
w
,
stdout
);
err
!=
nil
{
if
_
,
err
:=
io
.
Copy
(
w
,
stdout
);
err
!=
nil
{
log
Context
(
"handleGetInfoRefs read from subprocess"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handleGetInfoRefs: read from %v: %v"
,
cmd
.
Args
,
err
)
)
return
return
}
}
if
err
:=
cmd
.
Wait
();
err
!=
nil
{
if
err
:=
cmd
.
Wait
();
err
!=
nil
{
log
Context
(
"handleGetInfoRefs wait for subprocess"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handleGetInfoRefs: wait for %v: %v"
,
cmd
.
Args
,
err
)
)
return
return
}
}
}
}
...
@@ -63,7 +63,7 @@ func handlePostRPC(w http.ResponseWriter, r *gitRequest) {
...
@@ -63,7 +63,7 @@ func handlePostRPC(w http.ResponseWriter, r *gitRequest) {
action
:=
filepath
.
Base
(
r
.
URL
.
Path
)
action
:=
filepath
.
Base
(
r
.
URL
.
Path
)
if
!
(
action
==
"git-upload-pack"
||
action
==
"git-receive-pack"
)
{
if
!
(
action
==
"git-upload-pack"
||
action
==
"git-receive-pack"
)
{
// The 'dumb' Git HTTP protocol is not supported
// The 'dumb' Git HTTP protocol is not supported
fail500
(
w
,
"handlePostRPC"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handlePostRPC: unsupported action: %s"
,
r
.
URL
.
Path
)
)
return
return
}
}
...
@@ -71,25 +71,25 @@ func handlePostRPC(w http.ResponseWriter, r *gitRequest) {
...
@@ -71,25 +71,25 @@ func handlePostRPC(w http.ResponseWriter, r *gitRequest) {
cmd
:=
gitCommand
(
r
.
GL_ID
,
"git"
,
subCommand
(
action
),
"--stateless-rpc"
,
r
.
RepoPath
)
cmd
:=
gitCommand
(
r
.
GL_ID
,
"git"
,
subCommand
(
action
),
"--stateless-rpc"
,
r
.
RepoPath
)
stdout
,
err
:=
cmd
.
StdoutPipe
()
stdout
,
err
:=
cmd
.
StdoutPipe
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"handlePostRPC"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handlePostRPC: stdout: %v"
,
err
)
)
return
return
}
}
defer
stdout
.
Close
()
defer
stdout
.
Close
()
stdin
,
err
:=
cmd
.
StdinPipe
()
stdin
,
err
:=
cmd
.
StdinPipe
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"handlePostRPC"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handlePostRPC: stdin: %v"
,
err
)
)
return
return
}
}
defer
stdin
.
Close
()
defer
stdin
.
Close
()
if
err
:=
cmd
.
Start
();
err
!=
nil
{
if
err
:=
cmd
.
Start
();
err
!=
nil
{
fail500
(
w
,
"handlePostRPC"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handlePostRPC: start %v: %v"
,
cmd
.
Args
,
err
)
)
return
return
}
}
defer
cleanUpProcessGroup
(
cmd
)
// Ensure brute force subprocess clean-up
defer
cleanUpProcessGroup
(
cmd
)
// Ensure brute force subprocess clean-up
// Write the client request body to Git's standard input
// Write the client request body to Git's standard input
if
_
,
err
:=
io
.
Copy
(
stdin
,
r
.
Body
);
err
!=
nil
{
if
_
,
err
:=
io
.
Copy
(
stdin
,
r
.
Body
);
err
!=
nil
{
fail500
(
w
,
"handlePostRPC write to subprocess"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handlePostRPC write to %v: %v"
,
cmd
.
Args
,
err
)
)
return
return
}
}
// Signal to the Git subprocess that no more data is coming
// Signal to the Git subprocess that no more data is coming
...
@@ -106,11 +106,11 @@ func handlePostRPC(w http.ResponseWriter, r *gitRequest) {
...
@@ -106,11 +106,11 @@ func handlePostRPC(w http.ResponseWriter, r *gitRequest) {
// This io.Copy may take a long time, both for Git push and pull.
// This io.Copy may take a long time, both for Git push and pull.
if
_
,
err
:=
io
.
Copy
(
w
,
stdout
);
err
!=
nil
{
if
_
,
err
:=
io
.
Copy
(
w
,
stdout
);
err
!=
nil
{
log
Context
(
"handlePostRPC read from subprocess"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handlePostRPC read from %v: %v"
,
cmd
.
Args
,
err
)
)
return
return
}
}
if
err
:=
cmd
.
Wait
();
err
!=
nil
{
if
err
:=
cmd
.
Wait
();
err
!=
nil
{
log
Context
(
"handlePostRPC wait for subprocess"
,
err
)
log
Error
(
fmt
.
Errorf
(
"handlePostRPC wait for %v: %v"
,
cmd
.
Args
,
err
)
)
return
return
}
}
}
}
...
...
handlers.go
View file @
37b49c54
...
@@ -24,7 +24,7 @@ func contentEncodingHandler(handleFunc serviceHandleFunc) serviceHandleFunc {
...
@@ -24,7 +24,7 @@ func contentEncodingHandler(handleFunc serviceHandleFunc) serviceHandleFunc {
}
}
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"contentEncodingHandler"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"contentEncodingHandler: %v"
,
err
)
)
return
return
}
}
defer
body
.
Close
()
defer
body
.
Close
()
...
...
helpers.go
View file @
37b49c54
...
@@ -17,18 +17,18 @@ import (
...
@@ -17,18 +17,18 @@ import (
"syscall"
"syscall"
)
)
func
fail400
(
w
http
.
ResponseWriter
,
context
string
,
err
error
)
{
func
fail400
(
w
http
.
ResponseWriter
,
err
error
)
{
http
.
Error
(
w
,
"Bad request"
,
400
)
http
.
Error
(
w
,
"Bad request"
,
400
)
log
Context
(
context
,
err
)
log
Error
(
err
)
}
}
func
fail500
(
w
http
.
ResponseWriter
,
context
string
,
err
error
)
{
func
fail500
(
w
http
.
ResponseWriter
,
err
error
)
{
http
.
Error
(
w
,
"Internal server error"
,
500
)
http
.
Error
(
w
,
"Internal server error"
,
500
)
log
Context
(
context
,
err
)
log
Error
(
err
)
}
}
func
log
Context
(
context
string
,
err
error
)
{
func
log
Error
(
err
error
)
{
log
.
Printf
(
"
%s: %v"
,
context
,
err
)
log
.
Printf
(
"
error: %v"
,
err
)
}
}
// Git subprocess helpers
// Git subprocess helpers
...
...
lfs.go
View file @
37b49c54
...
@@ -8,6 +8,7 @@ import (
...
@@ -8,6 +8,7 @@ import (
"crypto/sha256"
"crypto/sha256"
"encoding/hex"
"encoding/hex"
"errors"
"errors"
"fmt"
"io"
"io"
"io/ioutil"
"io/ioutil"
"net/http"
"net/http"
...
@@ -15,26 +16,21 @@ import (
...
@@ -15,26 +16,21 @@ import (
"path/filepath"
"path/filepath"
)
)
var
(
errHashMismatch
=
errors
.
New
(
"Content hash does not match OID"
)
errSizeMismatch
=
errors
.
New
(
"Content size does not match"
)
)
func
lfsAuthorizeHandler
(
handleFunc
serviceHandleFunc
)
serviceHandleFunc
{
func
lfsAuthorizeHandler
(
handleFunc
serviceHandleFunc
)
serviceHandleFunc
{
return
preAuthorizeHandler
(
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
return
preAuthorizeHandler
(
func
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
if
r
.
StoreLFSPath
==
""
{
if
r
.
StoreLFSPath
==
""
{
fail500
(
w
,
"lfsAuthorizeHandler"
,
errors
.
New
(
"Don't know where to store object, no store path specified.
"
))
fail500
(
w
,
errors
.
New
(
"lfsAuthorizeHandler: StoreLFSPath empty
"
))
return
return
}
}
if
r
.
LfsOid
==
""
{
if
r
.
LfsOid
==
""
{
fail500
(
w
,
"lfsAuthorizeHandler"
,
errors
.
New
(
"Lfs object oid not specified.
"
))
fail500
(
w
,
errors
.
New
(
"lfsAuthorizeHandler: LfsOid empty
"
))
return
return
}
}
if
err
:=
os
.
MkdirAll
(
r
.
StoreLFSPath
,
0700
);
err
!=
nil
{
if
err
:=
os
.
MkdirAll
(
r
.
StoreLFSPath
,
0700
);
err
!=
nil
{
fail500
(
w
,
"Couldn't create directory for storing LFS tmp objects."
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"lfsAuthorizeHandler: mkdir StoreLFSPath: %v"
,
err
)
)
return
return
}
}
...
@@ -45,7 +41,7 @@ func lfsAuthorizeHandler(handleFunc serviceHandleFunc) serviceHandleFunc {
...
@@ -45,7 +41,7 @@ func lfsAuthorizeHandler(handleFunc serviceHandleFunc) serviceHandleFunc {
func
handleStoreLfsObject
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
func
handleStoreLfsObject
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
file
,
err
:=
ioutil
.
TempFile
(
r
.
StoreLFSPath
,
r
.
LfsOid
)
file
,
err
:=
ioutil
.
TempFile
(
r
.
StoreLFSPath
,
r
.
LfsOid
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"Couldn't open tmp file for writing."
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleStoreLfsObject: create tempfile: %v"
,
err
)
)
return
return
}
}
defer
os
.
Remove
(
file
.
Name
())
defer
os
.
Remove
(
file
.
Name
())
...
@@ -56,32 +52,32 @@ func handleStoreLfsObject(w http.ResponseWriter, r *gitRequest) {
...
@@ -56,32 +52,32 @@ func handleStoreLfsObject(w http.ResponseWriter, r *gitRequest) {
written
,
err
:=
io
.
Copy
(
hw
,
r
.
Body
)
written
,
err
:=
io
.
Copy
(
hw
,
r
.
Body
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"Failed to save received LFS object."
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleStoreLfsObject: write tempfile: %v"
,
err
)
)
return
return
}
}
file
.
Close
()
file
.
Close
()
if
written
!=
r
.
LfsSize
{
if
written
!=
r
.
LfsSize
{
fail500
(
w
,
"Inconsistent size: "
,
errSizeMismatch
)
fail500
(
w
,
fmt
.
Errorf
(
"handleStoreLfsObject: expected size %d, wrote %d"
,
r
.
LfsSize
,
written
)
)
return
return
}
}
shaStr
:=
hex
.
EncodeToString
(
hash
.
Sum
(
nil
))
shaStr
:=
hex
.
EncodeToString
(
hash
.
Sum
(
nil
))
if
shaStr
!=
r
.
LfsOid
{
if
shaStr
!=
r
.
LfsOid
{
fail500
(
w
,
"Inconsistent size: "
,
errSizeMismatch
)
fail500
(
w
,
fmt
.
Errorf
(
"handleStoreLfsObject: expected sha256 %s, got %s"
,
r
.
LfsOid
,
shaStr
)
)
return
return
}
}
r
.
Header
.
Set
(
"X-GitLab-Lfs-Tmp"
,
filepath
.
Base
(
file
.
Name
()))
r
.
Header
.
Set
(
"X-GitLab-Lfs-Tmp"
,
filepath
.
Base
(
file
.
Name
()))
storeReq
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
nil
,
""
)
storeReq
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
nil
,
""
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"newUpstreamRequestLfsStoreCallback"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleStoreLfsObject: newUpstreamRequest: %v"
,
err
)
)
return
return
}
}
storeResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
storeReq
)
storeResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
storeReq
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"doRequestLfsStoreCallback"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleStoreLfsObject: do %v: %v"
,
storeReq
.
URL
.
Path
,
err
)
)
return
return
}
}
defer
storeResponse
.
Body
.
Close
()
defer
storeResponse
.
Body
.
Close
()
...
...
proxy.go
View file @
37b49c54
package
main
package
main
import
(
import
(
"fmt"
"net/http"
"net/http"
)
)
func
proxyRequest
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
func
proxyRequest
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
upRequest
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
r
.
Body
,
""
)
upRequest
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
r
.
Body
,
""
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"newUpstreamRequest"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"proxyRequest: newUpstreamRequest: %v"
,
err
)
)
return
return
}
}
upResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
upRequest
)
upResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
upRequest
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"do upstream request"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"proxyRequest: do %v: %v"
,
upRequest
.
URL
.
Path
,
err
)
)
return
return
}
}
defer
upResponse
.
Body
.
Close
()
defer
upResponse
.
Body
.
Close
()
...
...
uploads.go
View file @
37b49c54
...
@@ -3,6 +3,7 @@ package main
...
@@ -3,6 +3,7 @@ package main
import
(
import
(
"bytes"
"bytes"
"errors"
"errors"
"fmt"
"io"
"io"
"io/ioutil"
"io/ioutil"
"mime/multipart"
"mime/multipart"
...
@@ -84,7 +85,7 @@ func rewriteFormFilesFromMultipart(r *gitRequest, writer *multipart.Writer) (cle
...
@@ -84,7 +85,7 @@ func rewriteFormFilesFromMultipart(r *gitRequest, writer *multipart.Writer) (cle
func
handleFileUploads
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
func
handleFileUploads
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
if
r
.
TempPath
==
""
{
if
r
.
TempPath
==
""
{
fail500
(
w
,
"handleUploadFile"
,
errors
.
New
(
"missing temporary path
"
))
fail500
(
w
,
errors
.
New
(
"handleFileUploads: TempPath empty
"
))
return
return
}
}
...
@@ -98,7 +99,7 @@ func handleFileUploads(w http.ResponseWriter, r *gitRequest) {
...
@@ -98,7 +99,7 @@ func handleFileUploads(w http.ResponseWriter, r *gitRequest) {
if
err
==
http
.
ErrNotMultipart
{
if
err
==
http
.
ErrNotMultipart
{
proxyRequest
(
w
,
r
)
proxyRequest
(
w
,
r
)
}
else
{
}
else
{
fail500
(
w
,
"Couldn't handle upload request."
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleFileUploads: extract files from multipart: %v"
,
err
)
)
}
}
return
return
}
}
...
@@ -113,7 +114,7 @@ func handleFileUploads(w http.ResponseWriter, r *gitRequest) {
...
@@ -113,7 +114,7 @@ func handleFileUploads(w http.ResponseWriter, r *gitRequest) {
// Create request
// Create request
upstreamRequest
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
nil
,
""
)
upstreamRequest
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
nil
,
""
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"Couldn't handle artifacts upload request."
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleFileUploads: newUpstreamRequest: %v"
,
err
)
)
return
return
}
}
...
@@ -125,7 +126,7 @@ func handleFileUploads(w http.ResponseWriter, r *gitRequest) {
...
@@ -125,7 +126,7 @@ func handleFileUploads(w http.ResponseWriter, r *gitRequest) {
// Forward request to backend
// Forward request to backend
upstreamResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
upstreamRequest
)
upstreamResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
upstreamRequest
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"do upstream request"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleFileUploads: do request %v: %v"
,
upstreamRequest
.
URL
.
Path
,
err
)
)
return
return
}
}
defer
upstreamResponse
.
Body
.
Close
()
defer
upstreamResponse
.
Body
.
Close
()
...
...
xsendfile.go
View file @
37b49c54
...
@@ -7,6 +7,7 @@ via the X-Sendfile mechanism. All that is needed in the Rails code is the
...
@@ -7,6 +7,7 @@ via the X-Sendfile mechanism. All that is needed in the Rails code is the
package
main
package
main
import
(
import
(
"fmt"
"io"
"io"
"log"
"log"
"net/http"
"net/http"
...
@@ -16,7 +17,7 @@ import (
...
@@ -16,7 +17,7 @@ import (
func
handleSendFile
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
func
handleSendFile
(
w
http
.
ResponseWriter
,
r
*
gitRequest
)
{
upRequest
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
r
.
Body
,
""
)
upRequest
,
err
:=
r
.
u
.
newUpstreamRequest
(
r
.
Request
,
r
.
Body
,
""
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"newUpstreamRequest"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleSendFile: newUpstreamRequest: %v"
,
err
)
)
return
return
}
}
...
@@ -24,7 +25,7 @@ func handleSendFile(w http.ResponseWriter, r *gitRequest) {
...
@@ -24,7 +25,7 @@ func handleSendFile(w http.ResponseWriter, r *gitRequest) {
upResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
upRequest
)
upResponse
,
err
:=
r
.
u
.
httpClient
.
Do
(
upRequest
)
r
.
Body
.
Close
()
r
.
Body
.
Close
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"do upstream request"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleSendfile: do upstream request: %v"
,
err
)
)
return
return
}
}
...
@@ -45,7 +46,7 @@ func handleSendFile(w http.ResponseWriter, r *gitRequest) {
...
@@ -45,7 +46,7 @@ func handleSendFile(w http.ResponseWriter, r *gitRequest) {
// Copy body from Rails upResponse
// Copy body from Rails upResponse
if
_
,
err
:=
io
.
Copy
(
w
,
upResponse
.
Body
);
err
!=
nil
{
if
_
,
err
:=
io
.
Copy
(
w
,
upResponse
.
Body
);
err
!=
nil
{
fail500
(
w
,
"Couldn't finalize X-File download request."
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleSendFile: copy upstream response: %v"
,
err
)
)
}
}
return
return
}
}
...
@@ -54,14 +55,14 @@ func handleSendFile(w http.ResponseWriter, r *gitRequest) {
...
@@ -54,14 +55,14 @@ func handleSendFile(w http.ResponseWriter, r *gitRequest) {
upResponse
.
Body
.
Close
()
upResponse
.
Body
.
Close
()
content
,
err
:=
os
.
Open
(
sendfile
)
content
,
err
:=
os
.
Open
(
sendfile
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"open sendfile"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleSendile: open sendfile: %v"
,
err
)
)
return
return
}
}
defer
content
.
Close
()
defer
content
.
Close
()
fi
,
err
:=
content
.
Stat
()
fi
,
err
:=
content
.
Stat
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"xSendFile get mtime"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"handleSendfile: get mtime: %v"
,
err
)
)
return
return
}
}
http
.
ServeContent
(
w
,
r
.
Request
,
""
,
fi
.
ModTime
(),
content
)
http
.
ServeContent
(
w
,
r
.
Request
,
""
,
fi
.
ModTime
(),
content
)
...
...
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