store: upload support
This commit is contained in:
parent
daa919e953
commit
a7158e9e56
@ -21,12 +21,13 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
http.HandleFunc("/", handleHTTP)
|
http.HandleFunc("/", handleHTTP)
|
||||||
|
|
||||||
log.Print("listening on ", *bind)
|
log.Print("listening on ", *bind)
|
||||||
http.ListenAndServe(*bind, nil)
|
log.Fatal(http.ListenAndServe(*bind, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleHTTP(w http.ResponseWriter, req *http.Request) {
|
func handleHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
@ -37,12 +38,10 @@ func handleHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
defer log.Print(l, " done")
|
defer log.Print(l, " done")
|
||||||
|
|
||||||
stat, err := os.Stat(filePath)
|
stat, err := os.Stat(filePath)
|
||||||
if err != nil {
|
if err != nil && !os.IsNotExist(err) {
|
||||||
writeErr(err, w)
|
writeErr(err, w)
|
||||||
return
|
return
|
||||||
}
|
} else if err == nil && stat.Mode().IsDir() {
|
||||||
|
|
||||||
if stat.Mode().IsDir() {
|
|
||||||
http.NotFound(w, req)
|
http.NotFound(w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -59,8 +58,51 @@ func handleHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
http.ServeFile(w, req, filePath)
|
http.ServeFile(w, req, filePath)
|
||||||
|
|
||||||
case "POST":
|
case "POST":
|
||||||
// TODO upload
|
tmpOut := filepath.Join(filepath.Dir(filePath), "."+filepath.Base(filePath))
|
||||||
http.Error(w, "not implemented", http.StatusNotImplemented)
|
|
||||||
|
if err := os.MkdirAll(filepath.Dir(filePath), 0755); err != nil {
|
||||||
|
writeErr(err, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := os.Create(tmpOut)
|
||||||
|
if err != nil {
|
||||||
|
writeErr(err, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
h := sha1.New()
|
||||||
|
mw := io.MultiWriter(out, h)
|
||||||
|
|
||||||
|
_, err = io.Copy(mw, req.Body)
|
||||||
|
out.Close()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
os.Remove(tmpOut)
|
||||||
|
|
||||||
|
writeErr(err, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sha1Hex := hex.EncodeToString(h.Sum(nil))
|
||||||
|
log.Print("upload SHA1: ", sha1Hex)
|
||||||
|
|
||||||
|
reqSHA1 := req.Header.Get("X-Content-SHA1")
|
||||||
|
if reqSHA1 != "" && reqSHA1 != sha1Hex {
|
||||||
|
err = fmt.Errorf("upload SHA1 does not match given SHA1: %s", reqSHA1)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error() + "\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Rename(tmpOut, filePath)
|
||||||
|
|
||||||
|
if err := ioutil.WriteFile(filePath+".sha1", []byte(sha1Hex), 0644); err != nil {
|
||||||
|
writeErr(err, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
http.NotFound(w, req)
|
http.NotFound(w, req)
|
||||||
@ -75,7 +117,7 @@ func writeErr(err error, w http.ResponseWriter) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("internal error: ", err)
|
log.Output(2, fmt.Sprint("internal error: ", err))
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
w.Write([]byte("Internal error\n"))
|
w.Write([]byte("Internal error\n"))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user