// // POST /upload/<encodedKeyHandle> // BODY: video stream with Content-Length // return: <key> // func (s *Service) upload(w http.ResponseWriter, req *http.Request) { query := strings.Split(req.URL.Path[1:], "/") if len(query) < 2 { w.WriteHeader(http.StatusMethodNotAllowed) return } encodedKeyHandle := query[1] kh, err := keystore.Decode(encodedKeyHandle) if err != nil { log.Println("upload: keystore.Decode error:", err) w.WriteHeader(404) return } key := kh.Key if time.Now().Unix() > kh.Expire { log.Println("upload: encodedKeyHandle expired.") w.WriteHeader(404) return } log.Println("upload: key:", key) defer req.Body.Close() err = s.stg.Put(key, req.Body, req.ContentLength) if err != nil { log.Println("upload: s.stg.Put", err) w.WriteHeader(400) return } w.Header().Set("Content-Length", strconv.Itoa(len(key))) w.WriteHeader(200) io.WriteString(w, key) }
// // GET /file/<encodedKeyHandle>(?thumb=0, 1) // func (s *Service) file(w http.ResponseWriter, req *http.Request) { query := strings.Split(req.URL.Path[1:], "/") if len(query) < 2 { w.WriteHeader(http.StatusMethodNotAllowed) return } encodedKeyHandle := query[1] kh, err := keystore.Decode(encodedKeyHandle) if err != nil { log.Println("file: keystore.Decode error:", err) w.WriteHeader(404) return } key := kh.Key if time.Now().Unix() > kh.Expire { log.Println("file: encodedKeyHandle expired.") w.WriteHeader(404) return } log.Println("file: key:", key) if q := req.URL.Query(); q.Get("thumb") != "" { s.getThumb(w, key, q.Get("thumb")) return } r, length, err := s.stg.Get(key) if err != nil { log.Println("file: s.stg.Get error:", err) w.WriteHeader(404) return } defer r.Close() h := w.Header() h.Set("Accept-Ranges", "bytes") h.Set("Content-Transfer-Encoding", "binary") if rg1, ok := req.Header["Range"]; ok { from, to, ok := ParseOneRange(rg1[0], length) if !ok { log.Println("get: ParseOnerange !ok") w.WriteHeader(http.StatusRequestedRangeNotSatisfiable) return } rg := "bytes " + strconv.FormatInt(from, 10) + "-" + strconv.FormatInt(to-1, 10) + "/" + strconv.FormatInt(length, 10) h.Set("Content-Length", strconv.FormatInt(to-from, 10)) h.Set("Content-Range", rg) w.WriteHeader(206) r.Seek(from, 0) io.Copy(w, io.LimitReader(r, to-from)) } else { h.Set("Content-Length", strconv.FormatInt(length, 10)) w.WriteHeader(200) io.CopyN(w, r, length) } }