~elektito/hodhod

1898e7c2de9bb435096273a303b10ebb7b27e355 — Mostafa Razavi 1 year, 3 months ago 13087d0
Add content-type detection based on file extension
2 files changed, 38 insertions(+), 1 deletions(-)

M pkg/hodhod/config.go
M pkg/hodhod/static.go
M pkg/hodhod/config.go => pkg/hodhod/config.go +25 -0
@@ 35,6 35,11 @@ type MatchOptionsConfig struct {
	IndexFilename string   `json:"index_filename"`
}

type ContentTypeConfig struct {
	Default string            `json:"default"`
	ExtMap  map[string]string `json:"ext_map"`
}

type Config struct {
	ListenAddr   string             `json:"listen"`
	MatchOptions MatchOptionsConfig `json:"match_options"`


@@ 42,6 47,7 @@ type Config struct {
	Routes       []Route            `json:"routes"`
	Backends     []Backend          `json:"backends"`
	Certs        []Cert             `json:"certs"`
	ContentType  ContentTypeConfig  `json:"content_type"`
}

func LoadConfig(configFilePath string) (config Config, err error) {


@@ 58,6 64,25 @@ func LoadConfig(configFilePath string) (config Config, err error) {
	config.MatchOptions.DefaultExts = []string{"gmi"}
	config.MatchOptions.IndexFilename = "index.gmi"
	config.CgiTimeout = 10
	config.ContentType.Default = "text/gemini"
	config.ContentType.ExtMap = map[string]string{
		"aac":  "audio/aac",
		"csv":  "text/csv",
		"gif":  "image/gif",
		"htm":  "text/html",
		"html": "text/html",
		"jpeg": "image/jpeg",
		"jpg":  "image/jpeg",
		"md":   "text/markdown",
		"mkv":  "video/x-matroska",
		"mp3":  "audio/mpeg",
		"mp4":  "video/mp4",
		"oga":  "audio/ogg",
		"ogv":  "video/ogg",
		"png":  "image/png",
		"txt":  "text/plain",
		"wav":  "audio/wav",
	}

	decoder := json.NewDecoder(f)
	err = decoder.Decode(&config)

M pkg/hodhod/static.go => pkg/hodhod/static.go +13 -1
@@ 4,6 4,7 @@ import (
	"fmt"
	"os"
	"path"
	"path/filepath"
)

type StaticResponse struct {


@@ 48,6 49,7 @@ func NewFileResp(filename string, cfg *Config) (resp Response) {
		for _, ext := range cfg.MatchOptions.DefaultExts {
			f, err = os.Open(filename + "." + ext)
			if err == nil {
				filename = filename + "." + ext
				break
			}
		}


@@ 61,9 63,19 @@ func NewFileResp(filename string, cfg *Config) (resp Response) {
		return
	}

	ext := filepath.Ext(filename)
	if ext != "" {
		// remove leading dot
		ext = ext[1:]
	}
	contentType, ok := cfg.ContentType.ExtMap[ext]
	if !ok {
		contentType = cfg.ContentType.Default
	}

	resp = &StaticResponse{
		file:        f,
		contentType: "text/gemini", // TODO find a way of detecting content type
		contentType: contentType,
	}
	return
}