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
2960ec22
Commit
2960ec22
authored
Dec 04, 2015
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
X AuthCache is now per upstream. Tests pass
parent
4b3b9a15
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
17 additions
and
12 deletions
+17
-12
blob.go
blob.go
+13
-11
upstream.go
upstream.go
+4
-1
No files found.
blob.go
View file @
2960ec22
...
@@ -53,17 +53,20 @@ type AuthCacheEntry struct {
...
@@ -53,17 +53,20 @@ type AuthCacheEntry struct {
//
//
// XXX should be not only project (private_token etc...)
// XXX should be not only project (private_token etc...)
type
AuthCache
struct
{
type
AuthCache
struct
{
u
*
upstream
// for which upstream we cache auth
mu
sync
.
RWMutex
// guards .cached
mu
sync
.
RWMutex
// guards .cached
cached
map
[
string
]
*
AuthCacheEntry
cached
map
[
string
]
*
AuthCacheEntry
}
}
var
authCache
=
AuthCache
{
cached
:
make
(
map
[
string
]
*
AuthCacheEntry
)}
func
NewAuthCache
(
u
*
upstream
)
*
AuthCache
{
return
&
AuthCache
{
u
:
u
,
cached
:
make
(
map
[
string
]
*
AuthCacheEntry
)}
}
// Verify that download access is ok or not.
// Verify that download access is ok or not.
// first we try to use the cache; if information is not there -> ask auth backend
// first we try to use the cache; if information is not there -> ask auth backend
// download is ok if AuthReply.RepoPath != ""
// download is ok if AuthReply.RepoPath != ""
// XXX u should not be in args?
func
(
c
*
AuthCache
)
VerifyDownloadAccess
(
project
string
)
AuthReply
{
func
(
c
*
AuthCache
)
VerifyDownloadAccess
(
u
*
upstream
,
project
string
)
AuthReply
{
var
authReply
AuthReply
var
authReply
AuthReply
// first try to read from cache in parallel with other readers
// first try to read from cache in parallel with other readers
...
@@ -104,7 +107,7 @@ have_entry:
...
@@ -104,7 +107,7 @@ have_entry:
c
.
mu
.
Unlock
()
c
.
mu
.
Unlock
()
// this goroutine becomes responsible for quering auth backend
// this goroutine becomes responsible for quering auth backend
auth
.
AuthReply
=
askAuthBackend
(
u
,
project
)
auth
.
AuthReply
=
askAuthBackend
(
c
.
u
,
project
)
auth
.
Tauth
=
time
.
Now
()
.
Unix
()
auth
.
Tauth
=
time
.
Now
()
.
Unix
()
auth
.
Nhit
=
0
auth
.
Nhit
=
0
...
@@ -114,7 +117,7 @@ have_entry:
...
@@ -114,7 +117,7 @@ have_entry:
close
(
auth
.
ready
)
close
(
auth
.
ready
)
// launch entry refresher
// launch entry refresher
go
c
.
refreshEntry
(
auth
,
u
,
project
)
go
c
.
refreshEntry
(
auth
,
project
)
}
}
return
authReply
return
authReply
...
@@ -125,7 +128,7 @@ const authCacheRefresh = 30 * time.Second
...
@@ -125,7 +128,7 @@ const authCacheRefresh = 30 * time.Second
// Goroutine to refresh auth cache entry periodically while it is used.
// Goroutine to refresh auth cache entry periodically while it is used.
// if the entry is detected to be not used - remove it from cache and stop refreshing.
// if the entry is detected to be not used - remove it from cache and stop refreshing.
func
(
c
*
AuthCache
)
refreshEntry
(
auth
*
AuthCacheEntry
,
u
*
upstream
,
project
string
)
{
func
(
c
*
AuthCache
)
refreshEntry
(
auth
*
AuthCacheEntry
,
project
string
)
{
for
{
for
{
time
.
Sleep
(
authCacheRefresh
)
time
.
Sleep
(
authCacheRefresh
)
...
@@ -146,7 +149,7 @@ func (c *AuthCache) refreshEntry(auth *AuthCacheEntry, u *upstream, project stri
...
@@ -146,7 +149,7 @@ func (c *AuthCache) refreshEntry(auth *AuthCacheEntry, u *upstream, project stri
}
}
//log.Printf("AUTH - refreshing %v", project)
//log.Printf("AUTH - refreshing %v", project)
authReply
:=
askAuthBackend
(
u
,
project
)
authReply
:=
askAuthBackend
(
c
.
u
,
project
)
auth
.
Lock
()
auth
.
Lock
()
auth
.
AuthReply
=
authReply
auth
.
AuthReply
=
authReply
...
@@ -193,7 +196,7 @@ func askAuthBackend(u *upstream, project string) AuthReply {
...
@@ -193,7 +196,7 @@ func askAuthBackend(u *upstream, project string) AuthReply {
}
}
func
verifyDownloadAccess
(
u
*
upstream
,
project
string
)
AuthReply
{
func
verifyDownloadAccess
(
u
*
upstream
,
project
string
)
AuthReply
{
return
authCache
.
VerifyDownloadAccess
(
u
,
project
)
return
u
.
authCache
.
VerifyDownloadAccess
(
project
)
}
}
// HTTP handler for `.../raw/<ref>/path`
// HTTP handler for `.../raw/<ref>/path`
...
@@ -220,9 +223,8 @@ func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) {
...
@@ -220,9 +223,8 @@ func handleGetBlobRaw(w http.ResponseWriter, r *gitRequest) {
w
.
Header
()[
k
]
=
v
w
.
Header
()[
k
]
=
v
}
}
w
.
WriteHeader
(
authReply
.
RawReply
.
Code
)
w
.
WriteHeader
(
authReply
.
RawReply
.
Code
)
// NOTE do not consume authReply.RawReply.Body with io.Copy -
// NOTE do not consume authReply.RawReply.Body with io.Copy() -
// this way it will be read one time only and next reads will
// this way it will be read one time only and next reads will be empty.
// be empty.
_
,
err
:=
w
.
Write
(
authReply
.
RawReply
.
Body
.
Bytes
())
_
,
err
:=
w
.
Write
(
authReply
.
RawReply
.
Body
.
Bytes
())
if
err
!=
nil
{
if
err
!=
nil
{
logContext
(
"writing authReply.RawReply.Body"
,
err
)
logContext
(
"writing authReply.RawReply.Body"
,
err
)
...
...
upstream.go
View file @
2960ec22
...
@@ -20,6 +20,7 @@ type serviceHandleFunc func(w http.ResponseWriter, r *gitRequest)
...
@@ -20,6 +20,7 @@ type serviceHandleFunc func(w http.ResponseWriter, r *gitRequest)
type
upstream
struct
{
type
upstream
struct
{
httpClient
*
http
.
Client
httpClient
*
http
.
Client
authBackend
string
authBackend
string
authCache
*
AuthCache
}
}
type
gitService
struct
{
type
gitService
struct
{
...
@@ -89,8 +90,10 @@ var gitServices = [...]gitService{
...
@@ -89,8 +90,10 @@ var gitServices = [...]gitService{
}
}
func
newUpstream
(
authBackend
string
,
authTransport
http
.
RoundTripper
)
*
upstream
{
func
newUpstream
(
authBackend
string
,
authTransport
http
.
RoundTripper
)
*
upstream
{
return
&
upstream
{
&
http
.
Client
{
Transport
:
authTransport
},
authBackend
}
u
:=
&
upstream
{
&
http
.
Client
{
Transport
:
authTransport
},
authBackend
,
nil
}
u
.
authCache
=
NewAuthCache
(
u
)
// XXX Timeout: ... ?
// XXX Timeout: ... ?
return
u
}
}
func
(
u
*
upstream
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
(
u
*
upstream
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
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