Ryanhub - file viewer
filename: server/http.go
branch: main
back to repo
package server

import (
	"fmt"
	"io/fs"
	"net/http"

	"assistant/config"
)

// Run listens until the server stops (blocking).
func Run(cfg *config.ServerConfig, api *API) error {
	mux := http.NewServeMux()

	sub, err := fs.Sub(staticRoot, "static")
	if err != nil {
		return fmt.Errorf("static assets: %w", err)
	}
	mux.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.FS(sub))))

	mux.HandleFunc("/api/status", api.handleStatus)
	mux.HandleFunc("/ask/stream", api.handleAskStream)
	mux.HandleFunc("/ask", api.handleAsk)
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		path := r.URL.Path
		if path == "/" || path == "/index.html" {
			if r.Method != http.MethodGet {
				http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
				return
			}
			serveStaticHTML(w, "static/index.html")
			return
		}
		api.handleNotFound(w, r)
	})

	addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
	srv := &http.Server{
		Addr:    addr,
		Handler: mux,
	}
	return srv.ListenAndServe()
}

func serveStaticHTML(w http.ResponseWriter, name string) {
	b, err := staticRoot.ReadFile(name)
	if err != nil {
		http.Error(w, "not found", http.StatusNotFound)
		return
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	_, _ = w.Write(b)
}