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
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
iv
gitlab-workhorse
Commits
d7116ae4
Commit
d7116ae4
authored
Oct 07, 2015
by
Jacob Vosmaer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Serve cached files from disk
parent
103750f1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
53 additions
and
12 deletions
+53
-12
githandler.go
githandler.go
+18
-10
main_test.go
main_test.go
+35
-2
No files found.
githandler.go
View file @
d7116ae4
...
@@ -18,6 +18,7 @@ import (
...
@@ -18,6 +18,7 @@ import (
"path"
"path"
"strings"
"strings"
"syscall"
"syscall"
"time"
)
)
type
gitHandler
struct
{
type
gitHandler
struct
{
...
@@ -205,6 +206,23 @@ func handleGetInfoRefs(env gitEnv, _ string, repoPath string, w http.ResponseWri
...
@@ -205,6 +206,23 @@ func handleGetInfoRefs(env gitEnv, _ string, repoPath string, w http.ResponseWri
}
}
func
handleGetArchive
(
env
gitEnv
,
format
string
,
repoPath
string
,
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
handleGetArchive
(
env
gitEnv
,
format
string
,
repoPath
string
,
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
archiveFilename
:=
path
.
Base
(
env
.
ArchivePath
)
w
.
Header
()
.
Add
(
"Content-Disposition"
,
fmt
.
Sprintf
(
`attachment; filename="%s"`
,
archiveFilename
))
if
format
==
"zip"
{
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/zip"
)
}
else
{
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/octet-stream"
)
}
w
.
Header
()
.
Add
(
"Content-Transfer-Encoding"
,
"binary"
)
w
.
Header
()
.
Add
(
"Cache-Control"
,
"private"
)
if
f
,
err
:=
os
.
Open
(
env
.
ArchivePath
);
err
==
nil
{
defer
f
.
Close
()
log
.
Printf
(
"Serving cached file %q"
,
env
.
ArchivePath
)
http
.
ServeContent
(
w
,
r
,
archiveFilename
,
time
.
Unix
(
0
,
0
),
f
)
return
}
var
compressCmd
*
exec
.
Cmd
var
compressCmd
*
exec
.
Cmd
var
archiveFormat
string
var
archiveFormat
string
switch
format
{
switch
format
{
...
@@ -222,8 +240,6 @@ func handleGetArchive(env gitEnv, format string, repoPath string, w http.Respons
...
@@ -222,8 +240,6 @@ func handleGetArchive(env gitEnv, format string, repoPath string, w http.Respons
compressCmd
=
nil
compressCmd
=
nil
}
}
archiveFilename
:=
path
.
Base
(
env
.
ArchivePath
)
archiveCmd
:=
gitCommand
(
env
,
"git"
,
"--git-dir="
+
repoPath
,
"archive"
,
"--format="
+
archiveFormat
,
"--prefix="
+
env
.
ArchivePrefix
+
"/"
,
env
.
CommitId
)
archiveCmd
:=
gitCommand
(
env
,
"git"
,
"--git-dir="
+
repoPath
,
"archive"
,
"--format="
+
archiveFormat
,
"--prefix="
+
env
.
ArchivePrefix
+
"/"
,
env
.
CommitId
)
archiveStdout
,
err
:=
archiveCmd
.
StdoutPipe
()
archiveStdout
,
err
:=
archiveCmd
.
StdoutPipe
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -260,14 +276,6 @@ func handleGetArchive(env gitEnv, format string, repoPath string, w http.Respons
...
@@ -260,14 +276,6 @@ func handleGetArchive(env gitEnv, format string, repoPath string, w http.Respons
}
}
// Start writing the response
// Start writing the response
if
format
==
"zip"
{
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/zip"
)
}
else
{
w
.
Header
()
.
Add
(
"Content-Type"
,
"application/octet-stream"
)
}
w
.
Header
()
.
Add
(
"Content-Transfer-Encoding"
,
"binary"
)
w
.
Header
()
.
Add
(
"Content-Disposition"
,
fmt
.
Sprintf
(
`attachment; filename="%s"`
,
archiveFilename
))
w
.
Header
()
.
Add
(
"Cache-Control"
,
"private"
)
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
,
stdout
);
err
!=
nil
{
if
_
,
err
:=
io
.
Copy
(
w
,
stdout
);
err
!=
nil
{
logContext
(
"handleGetArchive read from subprocess"
,
err
)
logContext
(
"handleGetArchive read from subprocess"
,
err
)
...
...
main_test.go
View file @
d7116ae4
package
main
package
main
import
(
import
(
"bytes"
"fmt"
"fmt"
"io/ioutil"
"net"
"net"
"net/http"
"net/http"
"net/http/httptest"
"net/http/httptest"
...
@@ -23,6 +25,7 @@ const testProject = "test"
...
@@ -23,6 +25,7 @@ const testProject = "test"
var
remote
=
fmt
.
Sprintf
(
"http://%s/%s"
,
servAddr
,
testRepo
)
var
remote
=
fmt
.
Sprintf
(
"http://%s/%s"
,
servAddr
,
testRepo
)
var
checkoutDir
=
path
.
Join
(
scratchDir
,
"test"
)
var
checkoutDir
=
path
.
Join
(
scratchDir
,
"test"
)
var
cacheDir
=
path
.
Join
(
scratchDir
,
"cache"
)
func
TestAllowedClone
(
t
*
testing
.
T
)
{
func
TestAllowedClone
(
t
*
testing
.
T
)
{
// Prepare clone directory
// Prepare clone directory
...
@@ -187,6 +190,36 @@ func TestAllowedApiDownloadZip(t *testing.T) {
...
@@ -187,6 +190,36 @@ func TestAllowedApiDownloadZip(t *testing.T) {
runOrFail
(
t
,
extractCmd
)
runOrFail
(
t
,
extractCmd
)
}
}
func
TestDownloadCacheHit
(
t
*
testing
.
T
)
{
prepareDownloadDir
(
t
)
// Prepare test server and backend
archiveName
:=
"foobar.zip"
ts
:=
testAuthServer
(
200
,
archiveOkBody
(
t
,
archiveName
))
defer
ts
.
Close
()
defer
cleanUpProcessGroup
(
startServerOrFail
(
t
,
ts
))
if
err
:=
os
.
MkdirAll
(
cacheDir
,
0755
);
err
!=
nil
{
t
.
Fatal
(
err
)
}
cachedContent
:=
[]
byte
{
'c'
,
'a'
,
'c'
,
'h'
,
'e'
,
'd'
}
if
err
:=
ioutil
.
WriteFile
(
path
.
Join
(
cacheDir
,
archiveName
),
cachedContent
,
0644
);
err
!=
nil
{
t
.
Fatal
(
err
)
}
downloadCmd
:=
exec
.
Command
(
"curl"
,
"-J"
,
"-O"
,
fmt
.
Sprintf
(
"http://%s/api/v3/projects/123/repository/archive.zip"
,
servAddr
))
downloadCmd
.
Dir
=
scratchDir
runOrFail
(
t
,
downloadCmd
)
actual
,
err
:=
ioutil
.
ReadFile
(
path
.
Join
(
scratchDir
,
archiveName
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
bytes
.
Compare
(
actual
,
cachedContent
)
!=
0
{
t
.
Fatal
(
"Unexpected file contents in download"
)
}
}
func
prepareDownloadDir
(
t
*
testing
.
T
)
{
func
prepareDownloadDir
(
t
*
testing
.
T
)
{
if
err
:=
os
.
RemoveAll
(
scratchDir
);
err
!=
nil
{
if
err
:=
os
.
RemoveAll
(
scratchDir
);
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
...
@@ -264,10 +297,10 @@ func archiveOkBody(t *testing.T, archiveName string) string {
...
@@ -264,10 +297,10 @@ func archiveOkBody(t *testing.T, archiveName string) string {
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
archivePath
:=
path
.
Join
(
cwd
,
scratchDir
,
"cache"
,
archiveName
)
archivePath
:=
path
.
Join
(
cwd
,
cacheDir
,
archiveName
)
jsonString
:=
`{
jsonString
:=
`{
"RepoPath":"%s",
"RepoPath":"%s",
"ArchivePath":"
/tmp/
%s",
"ArchivePath":"%s",
"CommitId":"c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd",
"CommitId":"c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd",
"ArchivePrefix":"foobar123"
"ArchivePrefix":"foobar123"
}`
}`
...
...
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