This commit is contained in:
61
pkg/middlewares/fallback.go
Normal file
61
pkg/middlewares/fallback.go
Normal file
@ -0,0 +1,61 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/fs"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// FallbackFile serves a fallback file if the next handler returns a 404.
|
||||
// fs: The file system to serve the fallback file from.
|
||||
// name: The name of the fallback file.
|
||||
// next: The next handler to serve.
|
||||
func FallbackFile(fs fs.FS, name string, next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
bw := &buffedResponseWriter{
|
||||
w,
|
||||
0,
|
||||
bytes.NewBuffer([]byte{}),
|
||||
}
|
||||
next.ServeHTTP(bw, r)
|
||||
|
||||
if bw.statusCode == http.StatusNotFound {
|
||||
bw.Clear()
|
||||
|
||||
http.ServeFileFS(bw, r, fs, name)
|
||||
bw.WriteHeader(http.StatusOK)
|
||||
bw.Header().Add("Content-Type", "text/html; charset=utf-8")
|
||||
}
|
||||
bw.Apply()
|
||||
})
|
||||
}
|
||||
|
||||
type buffedResponseWriter struct {
|
||||
http.ResponseWriter
|
||||
statusCode int
|
||||
buff *bytes.Buffer
|
||||
}
|
||||
|
||||
func (b *buffedResponseWriter) WriteHeader(code int) {
|
||||
b.statusCode = code
|
||||
}
|
||||
|
||||
func (b *buffedResponseWriter) Write(p []byte) (int, error) {
|
||||
return b.buff.Write(p)
|
||||
}
|
||||
|
||||
func (b *buffedResponseWriter) Clear() {
|
||||
b.buff.Reset()
|
||||
}
|
||||
|
||||
func (b *buffedResponseWriter) Apply() {
|
||||
_, err := b.ResponseWriter.Write(b.buff.Bytes())
|
||||
if err != nil {
|
||||
log.Println("Error while applying buffedResponseWriter: ", err)
|
||||
b.ResponseWriter.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
if b.statusCode != 200 {
|
||||
b.ResponseWriter.WriteHeader(b.statusCode)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user