From 815964e4a8811252f6323d11bfee89df2b03d452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisendo=CC=88rfer?= Date: Tue, 19 Mar 2013 10:29:06 +0100 Subject: [PATCH] Implement WriteFileChunk --- src/cmd/tusd/data_store.go | 44 ++++++++++++++++++++++++++++++++++++++ src/cmd/tusd/http.go | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/cmd/tusd/data_store.go b/src/cmd/tusd/data_store.go index ab986a0..f40a344 100644 --- a/src/cmd/tusd/data_store.go +++ b/src/cmd/tusd/data_store.go @@ -1,6 +1,9 @@ package main import ( + "errors" + "fmt" + "io" "os" "path" ) @@ -27,6 +30,47 @@ func (s *DataStore) CreateFile(id string, size int64) error { return nil } +func (s *DataStore) WriteFileChunk(id string, start int64, end int64, src io.Reader) error { + file, err := os.OpenFile(dataPath(id), os.O_WRONLY, 0666) + if err != nil { + return err + } + defer file.Close() + + if n, err := file.Seek(start, os.SEEK_SET); err != nil { + return err + } else if n != start { + return errors.New("WriteFileChunk: seek failure") + } + + size := end - start + 1 + if n, err := io.CopyN(file, src, size); err != nil { + return err + } else if n != size { + return errors.New("WriteFileChunk: partial copy") + } + + return s.appendFileLog(id, fmt.Sprintf("%d,%d", start, end)) +} + +func (s *DataStore) appendFileLog(id string, entry string) error { + logPath := s.logPath(id) + logFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666) + if err != nil { + return err + } + defer logFile.Close() + + if _, err := logFile.WriteString(entry + "\n"); err != nil { + return err + } + return nil +} + func (s *DataStore) filePath(id string) string { return path.Join(s.dir, id) } + +func (s *DataStore) logPath(id string) string { + return s.filePath(id) + ".log" +} diff --git a/src/cmd/tusd/http.go b/src/cmd/tusd/http.go index ecc0074..4405a0a 100644 --- a/src/cmd/tusd/http.go +++ b/src/cmd/tusd/http.go @@ -89,7 +89,7 @@ func postFiles(w http.ResponseWriter, r *http.Request) { } if contentRange.End != -1 { - if err := putFileChunk(id, contentRange.Start, contentRange.End, r.Body); err != nil { + if err := dataStore.WriteFileChunk(id, contentRange.Start, contentRange.End, r.Body); err != nil { // @TODO: Could be a 404 as well reply(w, http.StatusInternalServerError, err.Error()) return