Implement GetFileChunks

This commit is contained in:
Felix Geisendörfer 2013-03-19 10:32:27 +01:00
parent 815964e4a8
commit 771703a40c
2 changed files with 45 additions and 6 deletions

View File

@ -4,8 +4,11 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"os" "os"
"path" "path"
"strconv"
"strings"
) )
type DataStore struct { 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)) 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 { func (s *DataStore) appendFileLog(id string, entry string) error {
logPath := s.logPath(id) logPath := s.logPath(id)
logFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666) logFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666)

View File

@ -143,21 +143,21 @@ func putFile(w http.ResponseWriter, r *http.Request, fileId string) {
} }
func setFileRangeHeader(w http.ResponseWriter, fileId string) { func setFileRangeHeader(w http.ResponseWriter, fileId string) {
chunks, err := getReceivedChunks(fileId) chunks, err := dataStore.GetFileChunks(fileId)
if err != nil { if err != nil {
reply(w, http.StatusInternalServerError, err.Error()) reply(w, http.StatusInternalServerError, err.Error())
return return
} }
received := "" rangeHeader := ""
for i, chunk := range chunks { 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) { if i+1 < len(chunks) {
received += "," rangeHeader += ","
} }
} }
if received != "" { if rangeHeader != "" {
w.Header().Set("Range", "bytes="+received) w.Header().Set("Range", "bytes="+rangeHeader)
} }
} }