Commit d7116ae4 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Serve cached files from disk

parent 103750f1
......@@ -18,6 +18,7 @@ import (
"path"
"strings"
"syscall"
"time"
)
type gitHandler struct {
......@@ -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) {
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 archiveFormat string
switch format {
......@@ -222,8 +240,6 @@ func handleGetArchive(env gitEnv, format string, repoPath string, w http.Respons
compressCmd = nil
}
archiveFilename := path.Base(env.ArchivePath)
archiveCmd := gitCommand(env, "git", "--git-dir="+repoPath, "archive", "--format="+archiveFormat, "--prefix="+env.ArchivePrefix+"/", env.CommitId)
archiveStdout, err := archiveCmd.StdoutPipe()
if err != nil {
......@@ -260,14 +276,6 @@ func handleGetArchive(env gitEnv, format string, repoPath string, w http.Respons
}
// 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
if _, err := io.Copy(w, stdout); err != nil {
logContext("handleGetArchive read from subprocess", err)
......
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/http/httptest"
......@@ -23,6 +25,7 @@ const testProject = "test"
var remote = fmt.Sprintf("http://%s/%s", servAddr, testRepo)
var checkoutDir = path.Join(scratchDir, "test")
var cacheDir = path.Join(scratchDir, "cache")
func TestAllowedClone(t *testing.T) {
// Prepare clone directory
......@@ -187,6 +190,36 @@ func TestAllowedApiDownloadZip(t *testing.T) {
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) {
if err := os.RemoveAll(scratchDir); err != nil {
t.Fatal(err)
......@@ -264,10 +297,10 @@ func archiveOkBody(t *testing.T, archiveName string) string {
if err != nil {
t.Fatal(err)
}
archivePath := path.Join(cwd, scratchDir, "cache", archiveName)
archivePath := path.Join(cwd, cacheDir, archiveName)
jsonString := `{
"RepoPath":"%s",
"ArchivePath":"/tmp/%s",
"ArchivePath":"%s",
"CommitId":"c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd",
"ArchivePrefix":"foobar123"
}`
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment