aboutsummaryrefslogtreecommitdiffstats
path: root/api/http/git_file_handler.go
diff options
context:
space:
mode:
Diffstat (limited to 'api/http/git_file_handler.go')
-rw-r--r--api/http/git_file_handler.go61
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))
+}