mirror of
https://github.com/r-smith/deceptifeed.git
synced 2025-10-23 00:12:22 +00:00
feat: controlled error responses for HTTP honeypot
Add `withCustomError` middleware that intercepts HTTP error responses and replaces them with a custom error response. This is used when the HTTP honeypot is configured to serve content from a directory. It ensures that all error responses from http.FileServerFS are controlled and predicatable.
This commit is contained in:
@@ -65,7 +65,7 @@ func determineConfig(cfg *config.Server) *responseConfig {
|
||||
return &responseConfig{
|
||||
mode: modeDirectory,
|
||||
fsRoot: root,
|
||||
fsHandler: http.FileServerFS(noDirectoryFS{root.FS()}),
|
||||
fsHandler: withCustomError(http.FileServerFS(noDirectoryFS{root.FS()}), cfg.ErrorPagePath),
|
||||
}
|
||||
}
|
||||
|
||||
|
48
internal/httpserver/middleware.go
Normal file
48
internal/httpserver/middleware.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package httpserver
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// withCustomError is a middleware that intercepts 4xx/5xx HTTP error responses
|
||||
// and replaces them with a custom error response.
|
||||
func withCustomError(next http.Handler, errorPath string) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
e := &errorInterceptor{origWriter: w, origRequest: r, errorPath: errorPath}
|
||||
next.ServeHTTP(e, r)
|
||||
})
|
||||
}
|
||||
|
||||
// errorInterceptor intercepts HTTP responses to override error status codes
|
||||
// and to serve a custom error response.
|
||||
type errorInterceptor struct {
|
||||
origWriter http.ResponseWriter
|
||||
origRequest *http.Request
|
||||
overridden bool
|
||||
errorPath string
|
||||
}
|
||||
|
||||
// WriteHeader intercepts error response codes (4xx or 5xx) to serve a custom
|
||||
// error response.
|
||||
func (e *errorInterceptor) WriteHeader(statusCode int) {
|
||||
if statusCode >= 400 && statusCode <= 599 {
|
||||
e.overridden = true
|
||||
serveErrorPage(e.origWriter, e.origRequest, e.errorPath)
|
||||
return
|
||||
}
|
||||
e.origWriter.WriteHeader(statusCode)
|
||||
}
|
||||
|
||||
// Write writes the response body only if the response code was not overridden.
|
||||
// Otherwise, the body is discarded.
|
||||
func (e *errorInterceptor) Write(b []byte) (int, error) {
|
||||
if !e.overridden {
|
||||
return e.origWriter.Write(b)
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Header returns the response headers from the original ResponseWriter.
|
||||
func (e *errorInterceptor) Header() http.Header {
|
||||
return e.origWriter.Header()
|
||||
}
|
Reference in New Issue
Block a user