Esempio n. 1
0
func handler(r *data.FileRepo) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		path := path.Clean(req.URL.Path)

		if path == "/" {
			if req.Method == "HEAD" {
				return
			} else if req.Method != "GET" {
				w.WriteHeader(404)
				return
			}
			paths, err := r.List(req.URL.Query().Get("dir"))
			if err != nil && err != backend.ErrNotFound {
				errorResponse(w, err)
				return
			}
			if paths == nil {
				paths = []string{}
			}
			sort.Strings(paths)
			w.WriteHeader(200)
			json.NewEncoder(w).Encode(paths)
			return
		}

		switch req.Method {
		case "HEAD", "GET":
			file, err := r.Get(path, req.Method == "GET")
			if err != nil {
				errorResponse(w, err)
				return
			}
			if file.FileStream != nil {
				defer file.Close()
			}
			if r, ok := file.FileStream.(backend.Redirector); ok && req.Method == "GET" {
				http.Redirect(w, req, r.RedirectURL(), http.StatusFound)
				return
			}
			w.Header().Set("Content-Length", strconv.FormatInt(file.Size, 10))
			w.Header().Set("Content-Type", file.Type)
			w.Header().Set("Etag", file.ETag)
			http.ServeContent(w, req, path, file.ModTime, file)
		case "PUT":
			var err error
			if src := req.Header.Get("Blobstore-Copy-From"); src != "" {
				err = r.Copy(path, src)
			} else {
				var offset int64
				if s := req.Header.Get("Blobstore-Offset"); s != "" {
					offset, err = strconv.ParseInt(s, 10, 64)
					if err != nil {
						errorResponse(w, err)
						return
					}
				}
				err = r.Put(path, req.Body, offset, req.Header.Get("Content-Type"))
			}
			if err != nil {
				errorResponse(w, err)
				return
			}
			w.WriteHeader(200)
		case "DELETE":
			err := r.Delete(path)
			if err != nil {
				errorResponse(w, err)
				return
			}
			w.WriteHeader(200)
		default:
			w.WriteHeader(http.StatusMethodNotAllowed)
		}
	})
}