From 0f4a7bd33f20182385746250743841f7b745ff56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisendo=CC=88rfer?= Date: Sun, 17 Mar 2013 16:42:47 +0100 Subject: [PATCH] Start with id generation --- src/cmd/tusd/http.go | 61 ++++++++++++++++++++++++++++++++++++++++++++ src/cmd/tusd/main.go | 53 +------------------------------------- src/cmd/tusd/uid.go | 24 +++++++++++++++++ 3 files changed, 86 insertions(+), 52 deletions(-) create mode 100644 src/cmd/tusd/http.go create mode 100644 src/cmd/tusd/uid.go diff --git a/src/cmd/tusd/http.go b/src/cmd/tusd/http.go new file mode 100644 index 0000000..853f063 --- /dev/null +++ b/src/cmd/tusd/http.go @@ -0,0 +1,61 @@ +package main + +import ( + "fmt" + "net/http" + "log" +) + +func serveHttp() error { + http.HandleFunc("/", route) + + addr := ":1080" + log.Printf("serving clients at %s", addr) + + return http.ListenAndServe(addr, nil) +} + +func route(w http.ResponseWriter, r *http.Request) { + log.Printf("request: %s %s", r.Method, r.URL.RequestURI()) + + w.Header().Set("Server", "tusd") + + if r.Method == "POST" && r.URL.Path == "/files" { + createFile(w, r) + } else { + reply(w, http.StatusNotFound, "No matching route") + } +} + +func reply(w http.ResponseWriter, code int, message string) { + w.WriteHeader(code) + fmt.Fprintf(w, "%d - %s: %s\n", code, http.StatusText(code), message) +} + +func createFile(w http.ResponseWriter, r *http.Request) { + contentRange, err := parseContentRange(r.Header.Get("Content-Range")) + if err != nil { + reply(w, http.StatusBadRequest, err.Error()) + return + } + + if contentRange.Size == -1 { + reply(w, http.StatusBadRequest, "Content-Range must indicate total file size.") + return + } + + if contentRange.End != -1 { + reply(w, http.StatusNotImplemented, "File data in initial request.") + return + } + + contentType := r.Header.Get("Content-Type") + if contentType == "" { + contentType = "application/octet-stream" + } + + _ = contentType + id := uid() + + w.Header().Set("Location", "/files/"+id) +} diff --git a/src/cmd/tusd/main.go b/src/cmd/tusd/main.go index 588d780..744bf7d 100644 --- a/src/cmd/tusd/main.go +++ b/src/cmd/tusd/main.go @@ -1,8 +1,6 @@ package main import ( - "fmt" - "net/http" "log" ) @@ -10,56 +8,7 @@ func main() { log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) log.Printf("tusd started") - http.HandleFunc("/", route) - - addr := ":1080" - log.Printf("serving clients at %s", addr) - - err := http.ListenAndServe(addr, nil) - if err != nil { + if err := serveHttp(); err != nil { log.Fatal(err) } } - -func route(w http.ResponseWriter, r *http.Request) { - log.Printf("request: %s %s", r.Method, r.URL.RequestURI()) - - w.Header().Set("Server", "tusd") - - if r.Method == "POST" && r.URL.Path == "/files" { - createFile(w, r) - } else { - reply(w, http.StatusNotFound, "No matching route") - } -} - -func reply(w http.ResponseWriter, code int, message string) { - w.WriteHeader(code) - fmt.Fprintf(w, "%d - %s: %s\n", code, http.StatusText(code), message) -} - -func createFile(w http.ResponseWriter, r *http.Request) { - contentRange, err := parseContentRange(r.Header.Get("Content-Range")) - if err != nil { - reply(w, http.StatusBadRequest, err.Error()) - return - } - - if contentRange.Size == -1 { - reply(w, http.StatusBadRequest, "Content-Range must indicate total file size.") - return - } - - if contentRange.End != -1 { - reply(w, http.StatusNotImplemented, "File data in initial request.") - return - } - - contentType := r.Header.Get("Content-Type") - if contentType == "" { - contentType = "application/octet-stream" - } - - log.Printf("contentType: %s", contentType) - log.Printf("range: %#v", contentRange) -} diff --git a/src/cmd/tusd/uid.go b/src/cmd/tusd/uid.go new file mode 100644 index 0000000..a9d4eb9 --- /dev/null +++ b/src/cmd/tusd/uid.go @@ -0,0 +1,24 @@ +package main + +import ( + "crypto/rand" + "fmt" + "io" +) + +// uid returns a unique id. These ids consist of 128 bits from a +// cryptographically strong pseudo-random generator and are like uuids, but +// without the dashes and significant bits. +// +// See: http://en.wikipedia.org/wiki/UUID#Random_UUID_probability_of_duplicates +func uid() string { + id := make([]byte, 16) + _, err := io.ReadFull(rand.Reader, id) + if err != nil { + // This is probably an appropiate way to handle errors from our source + // for random bits. + panic(err) + } + + return fmt.Sprintf("%x", id) +}