add PUT method for raw file writes, open a/m/t for writes

This commit is contained in:
Levi Neely 2026-04-26 15:22:59 +02:00
parent 4338acd2df
commit ed0cce92f1
1 changed files with 26 additions and 3 deletions

29
main.go
View File

@ -3,7 +3,7 @@
// Maps HTTP methods to 9P file operations:
//
// GET /path - read file content or list directory entries
// PUT /path - write request body to file
// PUT /path - write request body to file (truncate)
// POST /path - create file (name = last path element)
// DELETE /path - remove file
// HEAD /path - stat file (metadata in headers)
@ -210,7 +210,7 @@ func handler(w http.ResponseWriter, r *http.Request) {
}
// Read-only paths — only GET and HEAD allowed.
switch first {
case "", "a", "m", "t", "sk":
case "", "sk":
if r.Method != http.MethodGet && r.Method != http.MethodHead {
writeJSON(w, http.StatusMethodNotAllowed, map[string]string{"error": "read-only"})
return
@ -241,6 +241,8 @@ func handler(w http.ResponseWriter, r *http.Request) {
return
}
handleWrite(w, r, fsys, p)
case http.MethodPut:
handlePut(w, r, fsys, p)
case http.MethodDelete:
handleRemove(w, fsys, p)
case http.MethodPatch:
@ -252,11 +254,12 @@ func handler(w http.ResponseWriter, r *http.Request) {
}
}
var allowedMethods = "GET, HEAD, POST, DELETE, PATCH, OPTIONS"
var allowedMethods = "GET, HEAD, PUT, POST, DELETE, PATCH, OPTIONS"
var methodDescriptions = map[string]string{
"GET": "read file content or list directory entries",
"HEAD": "stat file (metadata in response headers)",
"PUT": "write raw body to file (truncate)",
"POST": "write to file or trigger action",
"DELETE": "remove file or session",
"PATCH": "rename via JSON {\"name\": \"newname\"}",
@ -421,6 +424,26 @@ func handleStat(w http.ResponseWriter, fsys *client.Fsys, p string) {
w.Header().Set("Content-Type", "application/json")
}
func handlePut(w http.ResponseWriter, r *http.Request, fsys *client.Fsys, p string) {
body, err := io.ReadAll(r.Body)
if err != nil {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
return
}
fid, err := fsys.Open(p, plan9.OWRITE|plan9.OTRUNC)
if err != nil {
writeJSON(w, http.StatusNotFound, map[string]string{"error": err.Error()})
return
}
n, err := fid.Write(body)
fid.Close()
if err != nil {
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
return
}
writeJSON(w, http.StatusOK, map[string]int{"bytes_written": n})
}
func handleWrite(w http.ResponseWriter, r *http.Request, fsys *client.Fsys, p string) {
var m map[string]any
if err := json.NewDecoder(r.Body).Decode(&m); err != nil {