@@ -593,13 +593,35 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
593
593
serveContent (w , r , d .Name (), d .ModTime (), sizeFunc , f )
594
594
}
595
595
596
+ // errIsNotExist determines if an error represents a missing file. It's
597
+ // important that this is only used to check errors from a context of
598
+ // opening or otherwise "accessing" a file. This is because errors like
599
+ // "not a directory" mean something different for a call to Open() compared
600
+ // to something like Readdirnames().
601
+ func errIsNotExist (err error ) bool {
602
+ if os .IsNotExist (err ) {
603
+ return true
604
+ }
605
+
606
+ // doing string comparison so we don't need to
607
+ // pull in `syscall` and the associated build flags
608
+ //
609
+ // this check is necessary on unix systems that return syscall.ENOTDIR
610
+ // on Open() in some cases for a missing file
611
+ if perr , ok := err .(* os.PathError ); ok && perr .Op == "open" && strings .Contains (perr .Err .Error (), "not a directory" ) {
612
+ return true
613
+ }
614
+
615
+ return false
616
+ }
617
+
596
618
// toHTTPError returns a non-specific HTTP error message and status code
597
619
// for a given non-nil error value. It's important that toHTTPError does not
598
620
// actually return err.Error(), since msg and httpStatus are returned to users,
599
621
// and historically Go's ServeContent always returned just "404 Not Found" for
600
622
// all errors. We don't want to start leaking information in error messages.
601
623
func toHTTPError (err error ) (msg string , httpStatus int ) {
602
- if os . IsNotExist (err ) {
624
+ if errIsNotExist (err ) {
603
625
return "404 page not found" , StatusNotFound
604
626
}
605
627
if os .IsPermission (err ) {
0 commit comments