Skip to content

Commit 6f70e67

Browse files
committed
Add file upload support
1 parent a355fc4 commit 6f70e67

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

main.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ package main
2222

2323
import (
2424
"fmt"
25+
"io"
2526
"net/http"
2627
"os"
28+
"path/filepath"
2729
"strings"
2830
"text/tabwriter"
2931
"time"
@@ -54,6 +56,7 @@ func main() {
5456
version := pflag.BoolP("version", "v", false, "prints the version")
5557
dontDump := pflag.BoolP("dont-dump", "V", false, "don't be verbose and do not dump requests")
5658
dontServe := pflag.BoolP("dont-serve", "D", false, "don't serve any directy (ignores --directory)")
59+
enableUpload := pflag.BoolP("enable-upload", "u", os.Getenv("LAMA_UPLOAD") == "true", "enable support for file uploads")
5760
pflag.Parse()
5861

5962
if *version {
@@ -72,6 +75,11 @@ func main() {
7275
if !*dontServe {
7376
handler.Delegate = http.FileServer(http.Dir(*dir))
7477
fileStatement = fmt.Sprintf("files from %s ", *dir)
78+
79+
if *enableUpload {
80+
handler.Delegate = handleUploads(*dir, handler.Delegate)
81+
fileStatement += "(with upload support) "
82+
}
7583
}
7684
http.Handle("/", handler)
7785

@@ -145,3 +153,51 @@ func (h *debugHandler) logRequests() {
145153
fmt.Println()
146154
}
147155
}
156+
157+
func handleUploads(dir string, handler http.Handler) http.Handler {
158+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
159+
var (
160+
filename string
161+
filebody io.Reader
162+
)
163+
switch {
164+
case r.Method == http.MethodPut:
165+
defer r.Body.Close()
166+
filename = r.URL.Path
167+
filebody = r.Body
168+
case r.Method == http.MethodPost && r.Header.Get("Content-Type") == "multipart/form-data":
169+
defer r.Body.Close()
170+
file, fileHeader, err := r.FormFile("file")
171+
if err != nil {
172+
http.Error(w, err.Error(), http.StatusBadRequest)
173+
return
174+
}
175+
defer file.Close()
176+
filename = fileHeader.Filename
177+
filebody = file
178+
default:
179+
handler.ServeHTTP(w, r)
180+
return
181+
}
182+
183+
tmpfile, err := os.CreateTemp(dir, "lama-upload-*")
184+
if err != nil {
185+
http.Error(w, err.Error(), http.StatusInternalServerError)
186+
return
187+
}
188+
defer tmpfile.Close()
189+
defer os.Remove(tmpfile.Name())
190+
191+
_, err = io.Copy(tmpfile, filebody)
192+
if err != nil {
193+
http.Error(w, fmt.Sprintf("failed to write file body: %v", err), http.StatusInternalServerError)
194+
return
195+
}
196+
197+
err = os.Rename(tmpfile.Name(), filepath.Join(dir, filename))
198+
if err != nil {
199+
http.Error(w, fmt.Sprintf("failed to rename file: %v", err), http.StatusInternalServerError)
200+
return
201+
}
202+
})
203+
}

0 commit comments

Comments
 (0)