From 44d3e7bc14596e8c427c7b82f18415ad74b3a11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisendo=CC=88rfer?= Date: Mon, 18 Mar 2013 17:34:02 +0100 Subject: [PATCH] Implement initial file downloading --- src/cmd/tusd/data.go | 15 +++++++++++++++ src/cmd/tusd/http.go | 31 +++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/cmd/tusd/data.go b/src/cmd/tusd/data.go index 3da2227..0dc996d 100644 --- a/src/cmd/tusd/data.go +++ b/src/cmd/tusd/data.go @@ -123,3 +123,18 @@ func getReceivedChunks(fileId string) (chunkSet, error) { return chunks, nil } + +func getFileData(fileId string) (io.ReadCloser, int64, error) { + d := dataPath(fileId) + file, err := os.Open(d) + if err != nil { + return nil, 0, err + } + + stat, err := file.Stat() + if err != nil { + return nil, 0, err + } + + return file, stat.Size(), nil +} diff --git a/src/cmd/tusd/http.go b/src/cmd/tusd/http.go index 615d420..fee2772 100644 --- a/src/cmd/tusd/http.go +++ b/src/cmd/tusd/http.go @@ -2,9 +2,11 @@ package main import ( "fmt" + "io" "log" "net/http" "regexp" + "strconv" ) var fileRoute = regexp.MustCompile("^/files/([^/]+)$") @@ -27,12 +29,11 @@ func route(w http.ResponseWriter, r *http.Request) { postFiles(w, r) } else if match := fileRoute.FindStringSubmatch(r.URL.Path); match != nil { id := match[1] - // WIP switch r.Method { case "HEAD": headFile(w, r, id) case "GET": - reply(w, http.StatusNotImplemented, "File download") + getFile(w, r, id) case "PUT": putFile(w, r, id) default: @@ -82,6 +83,28 @@ func postFiles(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) } +func headFile(w http.ResponseWriter, r *http.Request, fileId string) { + setFileRangeHeader(w, fileId) +} + +func getFile(w http.ResponseWriter, r *http.Request, fileId string) { + data, size, err := getFileData(fileId) + if err != nil { + // @TODO: Could be a 404 as well + reply(w, http.StatusInternalServerError, err.Error()) + return + } + defer data.Close() + + setFileRangeHeader(w, fileId) + w.Header().Set("Content-Length", strconv.FormatInt(size, 10)) + + if _, err := io.CopyN(w, data, size); err != nil { + log.Printf("getFile: CopyN failed with: %s", err.Error()) + return + } +} + func putFile(w http.ResponseWriter, r *http.Request, fileId string) { contentRange, err := parseContentRange(r.Header.Get("Content-Range")) if err != nil { @@ -101,10 +124,6 @@ func putFile(w http.ResponseWriter, r *http.Request, fileId string) { setFileRangeHeader(w, fileId) } -func headFile(w http.ResponseWriter, r *http.Request, fileId string) { - setFileRangeHeader(w, fileId) -} - func setFileRangeHeader(w http.ResponseWriter, fileId string) { chunks, err := getReceivedChunks(fileId) if err != nil {