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
38d44f67
Commit
38d44f67
authored
Dec 08, 2015
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
37b49c54
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
41 additions
and
17 deletions
+41
-17
blob.go
blob.go
+15
-17
main_test.go
main_test.go
+26
-0
No files found.
blob.go
View file @
38d44f67
...
@@ -9,6 +9,7 @@ package main
...
@@ -9,6 +9,7 @@ package main
import
(
import
(
"bufio"
"bufio"
"errors"
"fmt"
"fmt"
"io"
"io"
"log"
"log"
...
@@ -58,8 +59,6 @@ type AuthCacheKey struct {
...
@@ -58,8 +59,6 @@ type AuthCacheKey struct {
// Authorization reply cache
// Authorization reply cache
// {} project -> AuthCacheEntry
// {} project -> AuthCacheEntry
//
// XXX should be not only project (private_token etc...)
type
AuthCache
struct
{
type
AuthCache
struct
{
u
*
upstream
// for which upstream we cache auth
u
*
upstream
// for which upstream we cache auth
...
@@ -178,9 +177,8 @@ func askAuthBackend(u *upstream, project, query string) AuthReply {
...
@@ -178,9 +177,8 @@ func askAuthBackend(u *upstream, project, query string) AuthReply {
// Request to auth backend to verify whether download is possible.
// Request to auth backend to verify whether download is possible.
// - first option is via asking as `git fetch` would do, but on Rails
// - first option is via asking as `git fetch` would do, but on Rails
// side this supports only basic auth, not private token.
// side this supports only basic auth, not private token.
// - that's why we auth backend to authenticate as if it is request to
// - that's why we auth backend to authenticate as if it was request to
// get repo archive XXX
// get repo archive.
// XXX private_token not propagated, etc ...
// XXX PRIVATE-TOKEN (in header)
// XXX PRIVATE-TOKEN (in header)
// url := project+".git/info/refs?service=git-upload-pack"
// url := project+".git/info/refs?service=git-upload-pack"
url
:=
project
+
"/repository/archive.zip"
url
:=
project
+
"/repository/archive.zip"
...
@@ -189,7 +187,7 @@ func askAuthBackend(u *upstream, project, query string) AuthReply {
...
@@ -189,7 +187,7 @@ func askAuthBackend(u *upstream, project, query string) AuthReply {
}
}
reqDownloadAccess
,
err
:=
http
.
NewRequest
(
"GET"
,
url
,
nil
)
reqDownloadAccess
,
err
:=
http
.
NewRequest
(
"GET"
,
url
,
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
authReply
.
RawReply
,
"GET git-upload-pack"
,
err
)
fail500
(
authReply
.
RawReply
,
fmt
.
Errorf
(
"GET git-upload-pack: %v"
,
err
)
)
return
authReply
return
authReply
}
}
...
@@ -224,7 +222,7 @@ func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) {
...
@@ -224,7 +222,7 @@ func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) {
u
:=
r
.
Request
.
URL
// XXX naming
u
:=
r
.
Request
.
URL
// XXX naming
rawLoc
:=
rawRe
.
FindStringIndex
(
u
.
Path
)
rawLoc
:=
rawRe
.
FindStringIndex
(
u
.
Path
)
if
rawLoc
==
nil
{
if
rawLoc
==
nil
{
fail500
(
w
,
"extract project name"
,
nil
)
// XXX err=nil
fail500
(
w
,
errors
.
New
(
"extract project name"
))
return
return
}
}
project
:=
u
.
Path
[
:
rawLoc
[
0
]]
project
:=
u
.
Path
[
:
rawLoc
[
0
]]
...
@@ -252,7 +250,7 @@ func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) {
...
@@ -252,7 +250,7 @@ func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) {
// this way it will be read one time only and next reads will be empty.
// this way it will be read one time only and next reads will be empty.
_
,
err
:=
w
.
Write
(
authReply
.
RawReply
.
Body
.
Bytes
())
_
,
err
:=
w
.
Write
(
authReply
.
RawReply
.
Body
.
Bytes
())
if
err
!=
nil
{
if
err
!=
nil
{
log
Context
(
"writing authReply.RawReply.Body"
,
err
)
log
Error
(
fmt
.
Errorf
(
"writing authReply.RawReply.Body: %v"
,
err
)
)
}
}
return
return
}
}
...
@@ -269,13 +267,13 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
...
@@ -269,13 +267,13 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
queryCmd
:=
gitCommand
(
""
,
"git"
,
"--git-dir="
+
repopath
,
"cat-file"
,
"--batch"
)
queryCmd
:=
gitCommand
(
""
,
"git"
,
"--git-dir="
+
repopath
,
"cat-file"
,
"--batch"
)
queryStdin
,
err
:=
queryCmd
.
StdinPipe
()
queryStdin
,
err
:=
queryCmd
.
StdinPipe
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"git cat-file --batch; stdin"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"git cat-file --batch; stdin: %v"
,
err
)
)
return
return
}
}
defer
queryStdin
.
Close
()
defer
queryStdin
.
Close
()
queryStdout
,
err
:=
queryCmd
.
StdoutPipe
()
queryStdout
,
err
:=
queryCmd
.
StdoutPipe
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"git cat-file --batch; stdout"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"git cat-file --batch; stdout: %v"
,
err
)
)
return
return
}
}
defer
queryStdout
.
Close
()
defer
queryStdout
.
Close
()
...
@@ -283,7 +281,7 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
...
@@ -283,7 +281,7 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
err
=
queryCmd
.
Start
()
err
=
queryCmd
.
Start
()
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"git cat-file --batch; start"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"git cat-file --batch; start: %v"
,
err
)
)
return
return
}
}
defer
cleanUpProcessGroup
(
queryCmd
)
defer
cleanUpProcessGroup
(
queryCmd
)
...
@@ -302,13 +300,13 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
...
@@ -302,13 +300,13 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
path
:=
strings
.
Join
(
refpathv
[
i
:
],
"/"
)
path
:=
strings
.
Join
(
refpathv
[
i
:
],
"/"
)
_
,
err
:=
fmt
.
Fprintf
(
queryStdin
,
"%s:%s
\n
"
,
ref
,
path
)
_
,
err
:=
fmt
.
Fprintf
(
queryStdin
,
"%s:%s
\n
"
,
ref
,
path
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"git cat-file --batch; write"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"git cat-file --batch; write: %v"
,
err
)
)
return
return
}
}
reply
,
err
:=
queryReader
.
ReadString
(
'\n'
)
reply
,
err
:=
queryReader
.
ReadString
(
'\n'
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"git cat-file --batch; read"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"git cat-file --batch; read: %v"
,
err
)
)
return
return
}
}
...
@@ -320,7 +318,7 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
...
@@ -320,7 +318,7 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
// <sha1> SP <type> SP <size> LF
// <sha1> SP <type> SP <size> LF
_
,
err
=
fmt
.
Sscanf
(
reply
,
"%s %s %d
\n
"
,
&
sha1
,
&
type_
,
&
size
)
_
,
err
=
fmt
.
Sscanf
(
reply
,
"%s %s %d
\n
"
,
&
sha1
,
&
type_
,
&
size
)
if
err
!=
nil
{
if
err
!=
nil
{
fail500
(
w
,
"git cat-file --batch; reply parse"
,
err
)
fail500
(
w
,
fmt
.
Errorf
(
"git cat-file --batch; reply parse: %v"
,
err
)
)
return
return
}
}
...
@@ -355,20 +353,20 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
...
@@ -355,20 +353,20 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string) {
// holding some tail bytes in queryReader after chat phase
// holding some tail bytes in queryReader after chat phase
_
,
err
=
io
.
CopyN
(
w
,
queryReader
,
size
)
_
,
err
=
io
.
CopyN
(
w
,
queryReader
,
size
)
if
err
!=
nil
{
if
err
!=
nil
{
log
Context
(
"io.CopyN"
,
err
)
log
Error
(
fmt
.
Errorf
(
"io.CopyN: %v"
,
err
)
)
return
return
}
}
// close git stdin explicitly, so it exits cleanly
// close git stdin explicitly, so it exits cleanly
err
=
queryStdin
.
Close
()
err
=
queryStdin
.
Close
()
if
err
!=
nil
{
if
err
!=
nil
{
log
Context
(
"queryStdin.Close"
,
err
)
log
Error
(
fmt
.
Errorf
(
"queryStdin.Close: %v"
,
err
)
)
return
return
}
}
err
=
queryCmd
.
Wait
()
err
=
queryCmd
.
Wait
()
if
err
!=
nil
{
if
err
!=
nil
{
log
Context
(
"wait"
,
err
)
log
Error
(
fmt
.
Errorf
(
"wait: %v"
,
err
)
)
return
return
}
}
}
}
main_test.go
View file @
38d44f67
...
@@ -522,3 +522,29 @@ func TestDeniedBlobDownload(t *testing.T) {
...
@@ -522,3 +522,29 @@ func TestDeniedBlobDownload(t *testing.T) {
downloadAndExpect
(
"874797c3/files/ruby/popen.rb"
,
403
)
downloadAndExpect
(
"874797c3/files/ruby/popen.rb"
,
403
)
downloadAndExpect
(
"master/non-existing-file"
,
403
)
downloadAndExpect
(
"master/non-existing-file"
,
403
)
}
}
func
TestPrivateBlobDownload
(
t
*
testing
.
T
)
{
// access is ok if token is provided either via query or via header
ts
:=
testServerWithHandler
(
url
,
func
(
w
,
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
log
.
Println
(
"UPSTREAM"
,
r
.
Method
,
r
.
URL
)
token_ok1
:=
r
.
URL
.
Query
()
.
Get
(
"aaa_token"
)
==
"TOKEN-4AAA"
token_ok2
:=
r
.
Header
.
Get
(
"BBB-TOKEN"
)
==
"TOKEN-4BBB"
if
!
(
token_ok1
||
token_ok2
)
{
w
.
WriteHeader
(
403
)
fmt
.
Fprintf
(
"w"
,
"Access denied"
)
}
data
,
err
:=
json
.
Marshal
(
gitOkBody
(
t
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
w
.
WriteHeader
(
200
)
w
.
Write
(
data
)
}
defer
ts
.
Close
()
ws
:=
startWorkhorseServer
(
ts
.
URL
)
defer
ws
.
Close
()
download
(
t
,
"%s/%s/raw/5f923865/README.md
}
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