@@ -22,8 +22,10 @@ package main
22
22
23
23
import (
24
24
"fmt"
25
+ "io"
25
26
"net/http"
26
27
"os"
28
+ "path/filepath"
27
29
"strings"
28
30
"text/tabwriter"
29
31
"time"
@@ -54,6 +56,7 @@ func main() {
54
56
version := pflag .BoolP ("version" , "v" , false , "prints the version" )
55
57
dontDump := pflag .BoolP ("dont-dump" , "V" , false , "don't be verbose and do not dump requests" )
56
58
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" )
57
60
pflag .Parse ()
58
61
59
62
if * version {
@@ -72,6 +75,11 @@ func main() {
72
75
if ! * dontServe {
73
76
handler .Delegate = http .FileServer (http .Dir (* dir ))
74
77
fileStatement = fmt .Sprintf ("files from %s " , * dir )
78
+
79
+ if * enableUpload {
80
+ handler .Delegate = handleUploads (* dir , handler .Delegate )
81
+ fileStatement += "(with upload support) "
82
+ }
75
83
}
76
84
http .Handle ("/" , handler )
77
85
@@ -145,3 +153,51 @@ func (h *debugHandler) logRequests() {
145
153
fmt .Println ()
146
154
}
147
155
}
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