get cp paste file upload gogo via multipart form
parent
34b964e0bb
commit
f24a8c2907
|
|
@ -1,2 +1,5 @@
|
|||
**/*.sw*
|
||||
spike/review/reinvent/ezmded/server/ezmded
|
||||
spike/review/reinvent/ezmded/server/ezmded/testdata/**/*
|
||||
spike/review/reinvent/ezmded/server/ezmded/testdata/media/*
|
||||
spike/review/reinvent/ezmded/server/ezmded/testdata/files/*
|
||||
|
|
|
|||
|
|
@ -3,15 +3,17 @@ module ezmded
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.3.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
local/args v0.0.0-00010101000000-000000000000
|
||||
local/notes-server v0.0.0-00010101000000-000000000000
|
||||
local/router v0.0.0-00010101000000-000000000000
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
local/simpleserve v0.0.0-00010101000000-000000000000
|
||||
local/gziphttp v0.0.0-00010101000000-000000000000
|
||||
)
|
||||
|
||||
replace local/args => ../../../../../../../../args
|
||||
|
||||
replace local/router => ../../../../../../../../router
|
||||
replace local/simpleserve => ../../../../../../../../simpleserve
|
||||
replace local/gziphttp => ../../../../../../../../gziphttp
|
||||
replace local/notes-server => ../../../../../../../../notes-server
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"local/gziphttp"
|
||||
"local/router"
|
||||
"local/simpleserve/simpleserve"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
|
|
@ -59,6 +62,11 @@ func (server *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func (server *Server) tryCatchHttpHandler(handler func(http.ResponseWriter, *http.Request) error) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if gziphttp.Can(r) {
|
||||
w2 := gziphttp.New(w)
|
||||
defer w2.Close()
|
||||
w = w2
|
||||
}
|
||||
if err := handler(w, r); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
|
@ -66,6 +74,23 @@ func (server *Server) tryCatchHttpHandler(handler func(http.ResponseWriter, *htt
|
|||
}
|
||||
|
||||
func (server *Server) apiV0TreeHandler(w http.ResponseWriter, r *http.Request) error {
|
||||
_, pretty := r.URL.Query()["pretty"]
|
||||
if pretty {
|
||||
return server.apiV0TreePrettyHandler(w, r)
|
||||
}
|
||||
return server.apiV0TreePlainHandler(w, r)
|
||||
}
|
||||
|
||||
func (server *Server) apiV0TreePrettyHandler(w http.ResponseWriter, r *http.Request) error {
|
||||
tree := server.tree()
|
||||
branches, err := tree.GetPretty()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.NewEncoder(w).Encode(branches)
|
||||
}
|
||||
|
||||
func (server *Server) apiV0TreePlainHandler(w http.ResponseWriter, r *http.Request) error {
|
||||
tree := server.tree()
|
||||
branches, err := tree.Get()
|
||||
if err != nil {
|
||||
|
|
@ -82,9 +107,8 @@ func ensureAndWrite(p string, b []byte) error {
|
|||
}
|
||||
|
||||
func (server *Server) apiV0MediaHandler(w http.ResponseWriter, r *http.Request) error {
|
||||
id := uuid.New().String()
|
||||
filePath := server.diskMediaPath(id)
|
||||
if err := server.postContentHandler(filePath, w, r); err != nil {
|
||||
id, err := server.postContentHandler(path.Dir(server.diskMediaPath("id")), w, r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.NewEncoder(w).Encode(map[string]map[string]string{
|
||||
|
|
@ -129,15 +153,49 @@ func (server *Server) getContentHandler(filePath string, w http.ResponseWriter,
|
|||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
simpleserve.SetContentTypeIfMedia(w, r)
|
||||
io.Copy(w, f)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *Server) postContentHandler(filePath string, w http.ResponseWriter, r *http.Request) error {
|
||||
func (server *Server) postContentHandler(fileDir string, w http.ResponseWriter, r *http.Request) (string, error) {
|
||||
if r.Method != http.MethodPost {
|
||||
return errors.New("not found")
|
||||
return "", errors.New("not found")
|
||||
}
|
||||
return server.putContentHandler(filePath, w, r)
|
||||
id := uuid.New().String()
|
||||
if strings.HasPrefix(r.Header.Get("Content-Type"), "multipart/form-data") {
|
||||
kb := int64(1 << 10)
|
||||
mb := kb << 10
|
||||
if err := r.ParseMultipartForm(10 * mb); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(r.MultipartForm.File) != 1 {
|
||||
return "", errors.New("not exactly 1 file found in request")
|
||||
}
|
||||
for _, infos := range r.MultipartForm.File {
|
||||
if len(infos) != 1 {
|
||||
return "", errors.New("not exactly 1 file info found in request")
|
||||
}
|
||||
ext := path.Ext(infos[0].Filename)
|
||||
if h, ok := infos[0].Header["Content-Type"]; ok {
|
||||
ext = path.Base(h[0])
|
||||
}
|
||||
id += "." + ext
|
||||
f, err := infos[0].Open()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
r.Body = f
|
||||
}
|
||||
} else if strings.HasPrefix(r.Header.Get("Content-Type"), "application/x-www-form-urlencoded") {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", fmt.Errorf("parse form: %+v", r.PostForm)
|
||||
}
|
||||
filePath := path.Join(fileDir, id)
|
||||
return id, server.putContentHandler(filePath, w, r)
|
||||
}
|
||||
|
||||
func (server *Server) putContentHandler(filePath string, w http.ResponseWriter, r *http.Request) error {
|
||||
|
|
@ -166,9 +224,8 @@ func (server *Server) diskMediaPath(id string) string {
|
|||
}
|
||||
|
||||
func (server *Server) apiV0FilesHandler(w http.ResponseWriter, r *http.Request) error {
|
||||
id := uuid.New().String()
|
||||
filePath := server.diskFilePath(id)
|
||||
if err := server.postContentHandler(filePath, w, r); err != nil {
|
||||
id, err := server.postContentHandler(path.Dir(server.diskFilePath("id")), w, r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tree := server.tree()
|
||||
|
|
|
|||
|
|
@ -42,10 +42,15 @@ func TestServerRoutes(t *testing.T) {
|
|||
method: http.MethodGet,
|
||||
want: `["getfid"]`,
|
||||
},
|
||||
"v0: tree: get pretty": {
|
||||
path: "/api/v0/tree?pretty",
|
||||
method: http.MethodGet,
|
||||
want: `{"delfid":{"Title":"delfid title","Children":[`,
|
||||
},
|
||||
"v0: tree: get": {
|
||||
path: "/api/v0/tree",
|
||||
method: http.MethodGet,
|
||||
want: `{"delfid":{"Title":"delfid title",`,
|
||||
want: `":{"Title":"getfid title",`,
|
||||
},
|
||||
"v0: media: post": {
|
||||
path: "/api/v0/media",
|
||||
|
|
|
|||
|
|
@ -20,12 +20,28 @@ type Branch struct {
|
|||
PID string
|
||||
}
|
||||
|
||||
type Pretty struct {
|
||||
Title string
|
||||
Children map[string]Pretty
|
||||
}
|
||||
|
||||
func NewTree(path string) *Tree {
|
||||
return &Tree{
|
||||
path: path,
|
||||
}
|
||||
}
|
||||
|
||||
func (tree *Tree) GetPretty() (map[string]Pretty, error) {
|
||||
branches, err := tree.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = branches
|
||||
pretty := map[string]Pretty{}
|
||||
// TODO: rm del
|
||||
return pretty, errors.New("not impl")
|
||||
}
|
||||
|
||||
func (tree *Tree) Get() (map[string]Branch, error) {
|
||||
b, err := ioutil.ReadFile(tree.path)
|
||||
if os.IsNotExist(err) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue