2020-06-21 23:12:04 +03:00
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
|
|
|
|
"github.com/MichaelMure/git-bug/cache"
|
2020-07-01 20:39:02 +03:00
|
|
|
"github.com/MichaelMure/git-bug/repository"
|
2020-06-21 23:12:04 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
// implement a http.Handler that will read and server git blob.
|
|
|
|
//
|
|
|
|
// Expected gorilla/mux parameters:
|
|
|
|
// - "repo" : the ref of the repo or "" for the default one
|
|
|
|
// - "hash" : the git hash of the file to retrieve
|
|
|
|
type gitFileHandler struct {
|
|
|
|
mrc *cache.MultiRepoCache
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewGitFileHandler(mrc *cache.MultiRepoCache) http.Handler {
|
|
|
|
return &gitFileHandler{mrc: mrc}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gfh *gitFileHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
|
|
|
var repo *cache.RepoCache
|
|
|
|
var err error
|
|
|
|
|
|
|
|
repoVar := mux.Vars(r)["repo"]
|
|
|
|
switch repoVar {
|
|
|
|
case "":
|
|
|
|
repo, err = gfh.mrc.DefaultRepo()
|
|
|
|
default:
|
|
|
|
repo, err = gfh.mrc.ResolveRepo(repoVar)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, "invalid repo reference", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-07-01 20:39:02 +03:00
|
|
|
hash := repository.Hash(mux.Vars(r)["hash"])
|
2020-06-21 23:12:04 +03:00
|
|
|
if !hash.IsValid() {
|
|
|
|
http.Error(rw, "invalid git hash", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: this mean that the whole file will he buffered in memory
|
|
|
|
// This can be a problem for big files. There might be a way around
|
|
|
|
// that by implementing a io.ReadSeeker that would read and discard
|
|
|
|
// data when a seek is called.
|
|
|
|
data, err := repo.ReadData(hash)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
http.ServeContent(rw, r, "", time.Now(), bytes.NewReader(data))
|
|
|
|
}
|