|
|
|
@ -8,7 +8,6 @@ import (
|
|
|
|
|
"os" |
|
|
|
|
"path/filepath" |
|
|
|
|
"sort" |
|
|
|
|
"strings" |
|
|
|
|
|
|
|
|
|
"github.com/h2non/filetype" |
|
|
|
|
) |
|
|
|
@ -98,33 +97,35 @@ func serveFile(c net.Conn, serve *pathConfig, filePath string) {
|
|
|
|
|
file, _ := os.Open(filePath) |
|
|
|
|
defer file.Close() |
|
|
|
|
|
|
|
|
|
// Read file header
|
|
|
|
|
buf := make([]byte, 261) |
|
|
|
|
n, _ := file.Read(buf) |
|
|
|
|
|
|
|
|
|
// Write response header
|
|
|
|
|
var contentType string |
|
|
|
|
if strings.HasSuffix(filePath, ".html") && strings.HasSuffix(filePath, ".htm") { |
|
|
|
|
contentType = "text/html; charset=utf-8" |
|
|
|
|
} else if strings.HasSuffix(filePath, ".txt") && strings.HasSuffix(filePath, ".text") { |
|
|
|
|
contentType = "text/plain; charset=utf-8" |
|
|
|
|
} else if !strings.HasSuffix(filePath, ".gmi") && !strings.HasSuffix(filePath, ".gemini") { |
|
|
|
|
kind, _ := filetype.Match(buf[:n]) |
|
|
|
|
if kind != filetype.Unknown { |
|
|
|
|
// Read content type
|
|
|
|
|
var ( |
|
|
|
|
buf = make([]byte, 261) |
|
|
|
|
n int |
|
|
|
|
) |
|
|
|
|
contentType := config.Types[filepath.Ext(filePath)] |
|
|
|
|
if contentType == "" { |
|
|
|
|
n, _ = file.Read(buf) |
|
|
|
|
kind, err := filetype.Match(buf[:n]) |
|
|
|
|
if err == nil && kind != filetype.Unknown && kind.MIME.Value != "" { |
|
|
|
|
contentType = kind.MIME.Value |
|
|
|
|
} else { |
|
|
|
|
contentType = plainType |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if contentType == "" { |
|
|
|
|
contentType = geminiType |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Read file size
|
|
|
|
|
size := int64(-1) |
|
|
|
|
info, err := file.Stat() |
|
|
|
|
if err == nil { |
|
|
|
|
size = info.Size() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Write response header
|
|
|
|
|
writeSuccess(c, serve, contentType, size) |
|
|
|
|
|
|
|
|
|
// Write body
|
|
|
|
|
c.Write(buf[:n]) |
|
|
|
|
// Write file contents
|
|
|
|
|
if n > 0 { |
|
|
|
|
c.Write(buf[:n]) |
|
|
|
|
} |
|
|
|
|
io.Copy(c, file) |
|
|
|
|
} |
|
|
|
|