From 771703a40c78dbb7bee6913fb25e846d922554fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisendo=CC=88rfer?= Date: Tue, 19 Mar 2013 10:32:27 +0100 Subject: [PATCH] Implement GetFileChunks --- src/cmd/tusd/data_store.go | 39 ++++++++++++++++++++++++++++++++++++++ src/cmd/tusd/http.go | 12 ++++++------ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/cmd/tusd/data_store.go b/src/cmd/tusd/data_store.go index f40a344..b746e75 100644 --- a/src/cmd/tusd/data_store.go +++ b/src/cmd/tusd/data_store.go @@ -4,8 +4,11 @@ import ( "errors" "fmt" "io" + "io/ioutil" "os" "path" + "strconv" + "strings" ) type DataStore struct { @@ -53,6 +56,42 @@ func (s *DataStore) WriteFileChunk(id string, start int64, end int64, src io.Rea return s.appendFileLog(id, fmt.Sprintf("%d,%d", start, end)) } +func (s *DataStore) GetFileChunks(id string) (chunkSet, error) { + // @TODO stream the file / limit log file size? + data, err := ioutil.ReadFile(s.logPath(id)) + if err != nil { + return nil, err + } + lines := strings.Split(string(data), "\n") + + chunks := make(chunkSet, 0, len(lines)-1) + for i, line := range lines { + // last line is always empty, skip it + if lastLine := i+1 == len(lines); lastLine { + break + } + + parts := strings.Split(line, ",") + if len(parts) != 2 { + return nil, errors.New("getReceivedChunks: corrupt log line: " + line) + } + + start, err := strconv.ParseInt(parts[0], 10, 64) + if err != nil { + return nil, errors.New("getReceivedChunks: invalid start: " + parts[0]) + } + + end, err := strconv.ParseInt(parts[1], 10, 64) + if err != nil { + return nil, errors.New("getReceivedChunks: invalid end: " + parts[1]) + } + + chunks.Add(chunk{Start: start, End: end}) + } + + return chunks, nil +} + 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) diff --git a/src/cmd/tusd/http.go b/src/cmd/tusd/http.go index 4405a0a..b06c2f1 100644 --- a/src/cmd/tusd/http.go +++ b/src/cmd/tusd/http.go @@ -143,21 +143,21 @@ func putFile(w http.ResponseWriter, r *http.Request, fileId string) { } func setFileRangeHeader(w http.ResponseWriter, fileId string) { - chunks, err := getReceivedChunks(fileId) + chunks, err := dataStore.GetFileChunks(fileId) if err != nil { reply(w, http.StatusInternalServerError, err.Error()) return } - received := "" + rangeHeader := "" for i, chunk := range chunks { - received += fmt.Sprintf("%d-%d", chunk.Start, chunk.End) + rangeHeader += fmt.Sprintf("%d-%d", chunk.Start, chunk.End) if i+1 < len(chunks) { - received += "," + rangeHeader += "," } } - if received != "" { - w.Header().Set("Range", "bytes="+received) + if rangeHeader != "" { + w.Header().Set("Range", "bytes="+rangeHeader) } }