package httpx import ( "surdeus.su/util/tpp" "path/filepath" "net/http" "context" "path" "mime" "log" "os" "io" ) var _ = http.Handler(&Handler{}) // The type describes behaviour // of handling stuff like in PHP. type Handler struct { // THe field represents // where we store site's // source files and request handlers. sourcePath string // Preprocessor must be set by user // to be able to bring custom features in. pp *tpp.Preprocessor // Aditional extension. ".tpp" by default. // For example "file.html.tpp" will be // first preprocessed TPP and sent back as simple HTML. ext string } // Returns the new Handler with // specified preprocessor, source path and // extension. func NewHandler( pp *tpp.Preprocessor, src, ext string, ) *Handler { ret := &Handler{} ret.sourcePath = src ret.ext = ext ret.pp = pp return ret } func (h *Handler) ServeHTTP( w http.ResponseWriter, r *http.Request, ) { urlPath := r.URL.Path // Cleaning URL path to prevent injections. urlPath = path.Clean(urlPath) urlExt := path.Ext(urlPath) filePath := filepath.Join( filepath.FromSlash(h.sourcePath), filepath.FromSlash(urlPath), ) filePathTpp := filePath + h.ext //log.Println("pth:", urlPath, filePathTpp) file, err := os.Open(filePathTpp) if err != nil { http.NotFound(w, r) return } //process := true fileData, err := io.ReadAll(file) if err != nil { http.NotFound(w, r) return } ctx := context.WithValue(r.Context(), KeyRequest, &Request{ Request: r, }) // Setting before the code to let it change own // content type. contentType := mime.TypeByExtension(urlExt) w.Header().Set("Content-Type", contentType) processedData, err := h.pp.Process( ctx, true, filePathTpp, fileData, ) if err != nil { http.NotFound(w, r) log.Printf("Error: pp.Process(...): %s\n", err) return } w.Write(processedData) }