2024-05-06 21:08:56 +03:00
|
|
|
package httpx
|
2024-04-25 22:38:04 +03:00
|
|
|
|
|
|
|
import (
|
2024-05-17 20:46:34 +03:00
|
|
|
"surdeus.su/util/tpp"
|
2024-05-06 14:24:28 +03:00
|
|
|
"path/filepath"
|
2024-04-25 22:38:04 +03:00
|
|
|
"net/http"
|
2024-05-06 21:08:56 +03:00
|
|
|
"context"
|
2024-04-25 22:38:04 +03:00
|
|
|
"path"
|
2024-05-06 14:24:28 +03:00
|
|
|
"mime"
|
|
|
|
"log"
|
2024-04-25 22:38:04 +03:00
|
|
|
"os"
|
2024-05-06 14:24:28 +03:00
|
|
|
"io"
|
2024-04-25 22:38:04 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
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.
|
2024-05-17 20:46:34 +03:00
|
|
|
sourcePath string
|
2024-05-06 14:24:28 +03:00
|
|
|
// Preprocessor must be set by user
|
|
|
|
// to be able to bring custom features in.
|
2024-05-17 20:46:34 +03:00
|
|
|
pp *tpp.Preprocessor
|
2024-05-06 14:24:28 +03:00
|
|
|
// Aditional extension. ".tpp" by default.
|
|
|
|
// For example "file.html.tpp" will be
|
|
|
|
// first preprocessed TPP and sent back as simple HTML.
|
2024-05-17 20:46:34 +03:00
|
|
|
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
|
2024-04-25 22:38:04 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handler) ServeHTTP(
|
|
|
|
w http.ResponseWriter,
|
|
|
|
r *http.Request,
|
|
|
|
) {
|
2024-05-06 14:24:28 +03:00
|
|
|
urlPath := r.URL.Path
|
|
|
|
// Cleaning URL path to prevent injections.
|
|
|
|
urlPath = path.Clean(urlPath)
|
|
|
|
urlExt := path.Ext(urlPath)
|
|
|
|
|
|
|
|
filePath := filepath.Join(
|
2024-05-17 20:46:34 +03:00
|
|
|
filepath.FromSlash(h.sourcePath),
|
2024-05-06 14:24:28 +03:00
|
|
|
filepath.FromSlash(urlPath),
|
|
|
|
)
|
2024-05-17 20:46:34 +03:00
|
|
|
filePathTpp := filePath + h.ext
|
2024-05-06 14:24:28 +03:00
|
|
|
|
|
|
|
//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
|
|
|
|
}
|
|
|
|
|
2024-05-06 21:08:56 +03:00
|
|
|
ctx := context.WithValue(r.Context(), KeyRequest, &Request{
|
|
|
|
Request: r,
|
|
|
|
})
|
2024-05-17 20:46:34 +03:00
|
|
|
|
|
|
|
// 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(
|
2024-05-06 21:08:56 +03:00
|
|
|
ctx,
|
2024-05-06 14:24:28 +03:00
|
|
|
true,
|
|
|
|
filePathTpp,
|
|
|
|
fileData,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
http.NotFound(w, r)
|
|
|
|
log.Printf("Error: pp.Process(...): %s\n", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Write(processedData)
|
2024-04-25 22:38:04 +03:00
|
|
|
}
|