http: Error template documents are supported
This commit is contained in:
parent
62885b2e37
commit
a7b360cc09
@ -11,11 +11,18 @@ import "path/filepath"
|
|||||||
import "git.tebibyte.media/sashakoshka/step"
|
import "git.tebibyte.media/sashakoshka/step"
|
||||||
import "git.tebibyte.media/sashakoshka/goutil/container"
|
import "git.tebibyte.media/sashakoshka/goutil/container"
|
||||||
|
|
||||||
|
type ErrorData struct {
|
||||||
|
Status int
|
||||||
|
Message any
|
||||||
|
}
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
Environment *step.Environment
|
Environment *step.Environment
|
||||||
Directories bool
|
Directories bool
|
||||||
StepExt ucontainer.Set[string]
|
StepExt ucontainer.Set[string]
|
||||||
Index []string
|
Index []string
|
||||||
|
ErrorDocument string
|
||||||
|
DirectoryDocument string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Handler) ServeHTTP (res http.ResponseWriter, req *http.Request) {
|
func (this *Handler) ServeHTTP (res http.ResponseWriter, req *http.Request) {
|
||||||
@ -39,9 +46,7 @@ func (this *Handler) ServeHTTP (res http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
info, err := statFile(filesystem, pathToName(pat))
|
info, err := statFile(filesystem, pathToName(pat))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO need more detailed error, should allow specifying error
|
this.serveError(res, req, http.StatusNotFound, req.URL, false)
|
||||||
// documents
|
|
||||||
this.serveError(res, req, http.StatusNotFound, req.URL)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
@ -57,12 +62,12 @@ func (this *Handler) ServeHTTP (res http.ResponseWriter, req *http.Request) {
|
|||||||
info, err := statFile(filesystem, pathToName(currentPath))
|
info, err := statFile(filesystem, pathToName(currentPath))
|
||||||
if err != nil { continue }
|
if err != nil { continue }
|
||||||
if info.IsDir() { continue }
|
if info.IsDir() { continue }
|
||||||
this.serveFile(res, req, filesystem, currentPath)
|
this.serveFile(res, req, currentPath)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !this.Directories {
|
if !this.Directories {
|
||||||
this.serveError(res, req, http.StatusForbidden, req.URL)
|
this.serveError(res, req, http.StatusForbidden, req.URL, false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,21 +77,32 @@ func (this *Handler) ServeHTTP (res http.ResponseWriter, req *http.Request) {
|
|||||||
// as data
|
// as data
|
||||||
}
|
}
|
||||||
|
|
||||||
this.serveFile(res, req, filesystem, pat)
|
this.serveFile(res, req, pat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Handler) serveFile (res http.ResponseWriter, req *http.Request, filesystem fs.FS, pat string) {
|
func (this *Handler) serveFile (
|
||||||
|
res http.ResponseWriter,
|
||||||
|
req *http.Request,
|
||||||
|
pat string,
|
||||||
|
) {
|
||||||
name := pathToName(pat)
|
name := pathToName(pat)
|
||||||
if !this.StepExt.Has(filepath.Ext(name)) {
|
if !this.StepExt.Has(filepath.Ext(name)) {
|
||||||
// just a normal file
|
// just a normal file
|
||||||
http.ServeFileFS(res, req, this.Environment.GetFS(), name)
|
http.ServeFileFS(res, req, this.Environment.GetFS(), name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.serveDocument(res, req, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Handler) serveDocument (
|
||||||
|
res http.ResponseWriter,
|
||||||
|
req *http.Request,
|
||||||
|
name string,
|
||||||
|
) {
|
||||||
// parse
|
// parse
|
||||||
document, err := this.Environment.Parse(name)
|
document, err := this.Environment.Parse(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.serveError(res, req, http.StatusInternalServerError, err)
|
this.serveError(res, req, http.StatusInternalServerError, err, false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +131,7 @@ func (this *Handler) serveFile (res http.ResponseWriter, req *http.Request, file
|
|||||||
Data: data,
|
Data: data,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.serveError(res, req, http.StatusInternalServerError, err)
|
this.serveError(res, req, http.StatusInternalServerError, err, false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,16 +142,41 @@ func (this *Handler) serveFile (res http.ResponseWriter, req *http.Request, file
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Handler) serveError (res http.ResponseWriter, req *http.Request, status int, message any) {
|
func (this *Handler) serveError (
|
||||||
res.Header().Add("Content-Type", "text/plain")
|
res http.ResponseWriter,
|
||||||
res.WriteHeader(status)
|
req *http.Request,
|
||||||
// TODO: allow customization with templates
|
status int,
|
||||||
if message == nil {
|
message any,
|
||||||
fmt.Fprintf(res, "%d %s\n", status, http.StatusText(status))
|
safeMode bool,
|
||||||
} else {
|
) {
|
||||||
fmt.Fprintf(res, "%d %s: %v\n", status, http.StatusText(status), message)
|
|
||||||
}
|
|
||||||
log.Printf("ERR %d %s: %v\n", status, http.StatusText(status), message)
|
log.Printf("ERR %d %s: %v\n", status, http.StatusText(status), message)
|
||||||
|
if safeMode || this.ErrorDocument == "" {
|
||||||
|
res.Header().Add("Content-Type", "text/plain")
|
||||||
|
res.WriteHeader(status)
|
||||||
|
// TODO: allow customization with templates
|
||||||
|
if message == nil {
|
||||||
|
fmt.Fprintf(res, "%d %s\n", status, http.StatusText(status))
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(res, "%d %s: %v\n", status, http.StatusText(status), message)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
document, err := this.Environment.Parse(this.ErrorDocument)
|
||||||
|
if err != nil {
|
||||||
|
this.serveError(res, req, http.StatusInternalServerError, err, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = document.Execute(res, step.ExecutionData {
|
||||||
|
Data: ErrorData {
|
||||||
|
Status: status,
|
||||||
|
Message: message,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.serveError(res, req, http.StatusInternalServerError, err, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Handler) logErr (name string, err error) {
|
func (this *Handler) logErr (name string, err error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user