diff options
Diffstat (limited to 'api/http/git_file_handler.go')
-rw-r--r-- | api/http/git_file_handler.go | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/api/http/git_file_handler.go b/api/http/git_file_handler.go new file mode 100644 index 00000000..6bd6fa85 --- /dev/null +++ b/api/http/git_file_handler.go @@ -0,0 +1,61 @@ +package http + +import ( + "bytes" + "net/http" + "time" + + "github.com/gorilla/mux" + + "github.com/MichaelMure/git-bug/cache" + "github.com/MichaelMure/git-bug/util/git" +) + +// 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 + } + + hash := git.Hash(mux.Vars(r)["hash"]) + 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)) +} |