@@ -156,7 +156,10 @@ func (s *Server) OpenFile(fileUUID string) (io.ReadSeeker, error) {
156156 file , err := os .Open (fileLocation )
157157 if err != nil {
158158 if os .IsNotExist (err ) {
159- s .removeFile (nil , fileUUID )
159+ // Clean up the DB entry if the file was removed by an external program.
160+ if err := s .DB .RemoveFile (nil , fileUUID ); err != nil {
161+ s .Logger .Printf ("DB remove failure (%v): %v\n " , fileUUID , err )
162+ }
160163 return nil , ErrFileDoesntExists
161164 }
162165 return nil , err
@@ -202,9 +205,12 @@ func (s *Server) GetFile(fileUUID string) (r io.ReadSeeker, contentType string,
202205 r , err = os .Open (fileLocation )
203206 if err != nil {
204207 if os .IsNotExist (err ) {
205- s .DB .RemoveFile (tx , fileUUID )
206208 return nil , "" , ErrFileDoesntExists
207209 }
210+ // Clean up the DB entry if the file was removed by an external program.
211+ if err := s .DB .RemoveFile (tx , fileUUID ); err != nil {
212+ s .Logger .Printf ("DB remove failure (%v): %v\n " , fileUUID , err )
213+ }
208214 return nil , "" , err
209215 }
210216 if err := tx .Commit (); err != nil {
@@ -221,14 +227,14 @@ func (s *Server) GetFile(fileUUID string) (r io.ReadSeeker, contentType string,
221227
222228func (s * Server ) acceptFile (w http.ResponseWriter , r * http.Request ) {
223229 if s .Conf .UploadAuth .Callback != nil && ! s .Conf .UploadAuth .Callback (r ) {
224- w . WriteHeader ( http . StatusForbidden )
225- w . Write ([] byte ( "403 forbidden") )
230+ s . Logger . Printf ( "Authentication failure (URL %v, IP %v)" , r . URL . String (), r . RemoteAddr )
231+ s . writeErr ( w , r , http . StatusForbidden , " forbidden" )
226232 return
227233 }
228234
229235 if s .Conf .Limits .MaxFileSize != 0 && r .ContentLength > int64 (s .Conf .Limits .MaxFileSize ) {
230- w . WriteHeader ( http . StatusRequestEntityTooLarge )
231- w . Write ([] byte ( "413 request entity too large" ) )
236+ s . Logger . Printf ( "Too big file (URL %v, IP %v)" , r . URL . String (), r . RemoteAddr )
237+ s . writeErr ( w , r , http . StatusRequestEntityTooLarge , " too big file" )
232238 return
233239 }
234240
@@ -238,13 +244,13 @@ func (s *Server) acceptFile(w http.ResponseWriter, r *http.Request) {
238244 } else if r .URL .Query ().Get ("store-secs" ) != "" {
239245 secs , err := strconv .Atoi (r .URL .Query ().Get ("store-secs" ))
240246 if err != nil {
241- w . WriteHeader ( http . StatusBadRequest )
242- w . Write ([] byte ( "400 bad request ( invalid store-secs value)" ) )
247+ s . Logger . Printf ( "Invalid store-secs (URL %v, IP %v)" , r . URL . String (), r . RemoteAddr )
248+ s . writeErr ( w , r , http . StatusBadRequest , " invalid store-secs value" )
243249 return
244250 }
245251 if s .Conf .Limits .MaxStoreSecs != 0 && uint (secs ) > s .Conf .Limits .MaxStoreSecs {
246- w . WriteHeader ( http . StatusBadRequest )
247- w . Write ([] byte ( "400 bad request ( too big store-secs value)" ) )
252+ s . Logger . Printf ( "Too big store-secs (URL %v, IP %v)" , r . URL . String (), r . RemoteAddr )
253+ s . writeErr ( w , r , http . StatusBadRequest , " too big store-secs value" )
248254 return
249255 }
250256 storeUntil = time .Now ().Add (time .Duration (secs ) * time .Second )
@@ -256,22 +262,21 @@ func (s *Server) acceptFile(w http.ResponseWriter, r *http.Request) {
256262 var err error
257263 maxUses , err := strconv .Atoi (r .URL .Query ().Get ("max-uses" ))
258264 if err != nil {
259- w . WriteHeader ( http . StatusBadRequest )
260- w . Write ([] byte ( "400 bad request ( invalid max-uses value)" ) )
265+ s . Logger . Printf ( "Invalid max-uses store-secs (URL %v, IP %v)" , r . URL . String (), r . RemoteAddr )
266+ s . writeErr ( w , r , http . StatusBadRequest , " invalid max-uses value" )
261267 return
262268 }
263269 if s .Conf .Limits .MaxUses != 0 && uint (maxUses ) > s .Conf .Limits .MaxUses {
264- w . WriteHeader ( http . StatusBadRequest )
265- w . Write ([] byte ( "400 bad request ( too big max-uses value)" ) )
270+ s . Logger . Printf ( "Too big max-uses store-secs (URL %v, IP %v)" , r . URL . String (), r . RemoteAddr )
271+ s . writeErr ( w , r , http . StatusBadRequest , " too big max-uses value" )
266272 return
267273 }
268274 }
269275
270276 fileUUID , err := s .AddFile (r .Body , r .Header .Get ("Content-Type" ), maxUses , storeUntil )
271277 if err != nil {
272278 s .Logger .Println ("Error while serving" , r .RequestURI + ":" , err )
273- w .WriteHeader (http .StatusInternalServerError )
274- w .Write ([]byte (err .Error ()))
279+ s .writeErr (w , r , http .StatusInternalServerError , "internal server error" )
275280 return
276281 }
277282
@@ -296,42 +301,50 @@ func (s *Server) acceptFile(w http.ResponseWriter, r *http.Request) {
296301 splittenPath = append (splittenPath , fileUUID )
297302 resURL .Path = strings .Join (splittenPath , "/" )
298303
304+ w .Header ().Add ("Content-Type" , `text/plain; charset="us-ascii"` )
299305 w .WriteHeader (http .StatusCreated )
300- w .Write ([]byte (resURL .String ()))
306+ if _ , err := w .Write ([]byte (resURL .String ())); err != nil {
307+ s .Logger .Printf ("I/O error (URL %v, IP %v): %v" , r .URL .String (), r .RemoteAddr , err )
308+ }
309+ }
310+
311+ func (s * Server ) writeErr (w http.ResponseWriter , r * http.Request , code int , replyText string ) {
312+ w .Header ().Add ("Content-Type" , `text/plain; charset="us-ascii"` )
313+ w .WriteHeader (code )
314+ _ , err := io .WriteString (w , strconv .Itoa (code )+ " " + replyText )
315+ if err != nil {
316+ s .Logger .Printf ("I/O error (URL %v, IP %v): %v" , r .URL .String (), r .RemoteAddr , err )
317+ }
301318}
302319
303320func (s * Server ) serveFile (w http.ResponseWriter , r * http.Request ) {
304321 if s .Conf .DownloadAuth .Callback != nil && ! s .Conf .DownloadAuth .Callback (r ) {
305- w . WriteHeader ( http . StatusForbidden )
306- w . Write ([] byte ( "403 forbidden") )
322+ s . Logger . Printf ( "Authentication failure (URL %v, IP %v)" , r . URL . String (), r . RemoteAddr )
323+ s . writeErr ( w , r , http . StatusForbidden , " forbidden" )
307324 return
308325 }
309326
310327 splittenPath := strings .Split (r .URL .Path , "/" )
311328 if len (splittenPath ) < 2 {
312- w .WriteHeader (http .StatusNotFound )
313- w .Write ([]byte ("404 not found" ))
329+ s .writeErr (w , r , http .StatusNotFound , "not found" )
314330 return
315331 }
316332 fileUUID := splittenPath [len (splittenPath )- 1 ]
317333 if _ , err := uuid .FromString (fileUUID ); err != nil {
318334 // Probably last component is fake "filename".
319335 if len (splittenPath ) == 1 {
320- w .WriteHeader (http .StatusNotFound )
321- w .Write ([]byte ("404 not found" ))
336+ s .writeErr (w , r , http .StatusNotFound , "not found" )
322337 return
323338 }
324339 fileUUID = splittenPath [len (splittenPath )- 2 ]
325340 }
326341 reader , ttype , err := s .GetFile (fileUUID )
327342 if err != nil {
328343 if err == ErrFileDoesntExists {
329- w .WriteHeader (http .StatusNotFound )
330- w .Write ([]byte ("404 not found" ))
344+ s .writeErr (w , r , http .StatusNotFound , "not found" )
331345 } else {
332346 s .Logger .Println ("Error while serving" , r .RequestURI + ":" , err )
333- w .WriteHeader (http .StatusInternalServerError )
334- w .Write ([]byte (err .Error ()))
347+ s .writeErr (w , r , http .StatusInternalServerError , "internal server error" )
335348 }
336349 return
337350 }
@@ -363,8 +376,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
363376 w .Header ().Set ("Access-Control-Allow-Headers" , "Content-Type, Content-Length" )
364377 w .WriteHeader (http .StatusNoContent )
365378 } else {
366- w .WriteHeader (http .StatusMethodNotAllowed )
367- w .Write ([]byte ("405 method not allowed" ))
379+ s .writeErr (w , r , http .StatusMethodNotAllowed , "method not allowed" )
368380 }
369381}
370382
0 commit comments