44 "bytes"
55 "errors"
66 "fmt"
7+ "io"
78 "net/http"
89 "os"
910 "path"
@@ -305,31 +306,35 @@ func (s *Server) serveFile(statusCode int, location string, w http.ResponseWrite
305306 }
306307
307308 var data [512 ]byte
308- if _ , err := f .Read (data [:]); err != nil {
309+ n , err := f .Read (data [:])
310+ if err != nil && ! errors .Is (err , io .EOF ) {
309311 http .Error (w , err .Error (), http .StatusInternalServerError )
310312 return
311313 }
312314
313- if contentType == "" {
314- if local := http .DetectContentType (data [:]); local != "application/octet-stream" {
315+ // Only detect content type if we have content to examine
316+ if contentType == "" && n > 0 {
317+ if local := http .DetectContentType (data [:n ]); local != "application/octet-stream" {
315318 contentType = local
316319 }
317320 }
318321
322+ // Only attempt charset detection if we have content to examine
319323 charset := ""
320- if utf8 . Valid ( data [:] ) {
321- charset = "utf-8"
322- }
323-
324- if charset == "" {
325- res , err := chardet . NewTextDetector (). DetectBest ( data [:])
326- if err == nil && res .Confidence > 50 && res . Charset != "" {
327- charset = res . Charset
324+ if n > 0 && contentType != "" && ! strings . HasPrefix ( contentType , "application/octet-stream" ) {
325+ if utf8 . Valid ( data [: n ]) {
326+ charset = "utf-8"
327+ } else {
328+ res , err := chardet . NewTextDetector (). DetectBest ( data [: n ])
329+ if err == nil && res . Confidence > 50 && res . Charset != "" {
330+ charset = res .Charset
331+ }
328332 }
329333 }
330334
331- if contentType != "" && contentType != "application/octet-stream" {
332- if charset != "" {
335+ if contentType != "" {
336+ // Add charset for text-based content types only
337+ if charset != "" && contentType != "application/octet-stream" {
333338 contentType += "; charset=" + charset
334339 }
335340
@@ -342,6 +347,12 @@ func (s *Server) serveFile(statusCode int, location string, w http.ResponseWrite
342347 w .Header ().Set ("Content-Disposition" , fmt .Sprintf ("attachment; filename=%q" , filename ))
343348 }
344349
350+ // Reset file position to beginning after reading first bytes for content detection
351+ if _ , err := f .Seek (0 , io .SeekStart ); err != nil {
352+ http .Error (w , err .Error (), http .StatusInternalServerError )
353+ return
354+ }
355+
345356 // Check if the caller changed the status code, if not, simply call
346357 // the appropriate handler/
347358 if statusCode == 0 {
0 commit comments