mirror of https://github.com/caddyserver/caddy.git
fileserver: Better handling of HTTP status override (#4132)
This commit is contained in:
parent
a8d45277ca
commit
3a1e81dbf6
|
@ -18,7 +18,6 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
weakrand "math/rand"
|
||||
"mime"
|
||||
"net/http"
|
||||
|
@ -333,32 +332,33 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c
|
|||
}
|
||||
}
|
||||
|
||||
// if this handler exists in an error context (i.e. is
|
||||
// part of a handler chain that is supposed to handle
|
||||
// a previous error), we have to serve the content
|
||||
// manually in order to write the correct status code
|
||||
var statusCodeOverride int
|
||||
|
||||
// if this handler exists in an error context (i.e. is part of a
|
||||
// handler chain that is supposed to handle a previous error),
|
||||
// we should set status code to the one from the error instead
|
||||
// of letting http.ServeContent set the default (usually 200)
|
||||
if reqErr, ok := r.Context().Value(caddyhttp.ErrorCtxKey).(error); ok {
|
||||
statusCode := http.StatusInternalServerError
|
||||
statusCodeOverride = http.StatusInternalServerError
|
||||
if handlerErr, ok := reqErr.(caddyhttp.HandlerError); ok {
|
||||
if handlerErr.StatusCode > 0 {
|
||||
statusCode = handlerErr.StatusCode
|
||||
statusCodeOverride = handlerErr.StatusCode
|
||||
}
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
if r.Method != http.MethodHead {
|
||||
_, _ = io.Copy(w, file)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// if a status code override is configured, write the status code
|
||||
// before serving the file
|
||||
// if a status code override is configured, run the replacer on it
|
||||
if codeStr := fsrv.StatusCode.String(); codeStr != "" {
|
||||
intVal, err := strconv.Atoi(repl.ReplaceAll(codeStr, ""))
|
||||
statusCodeOverride, err = strconv.Atoi(repl.ReplaceAll(codeStr, ""))
|
||||
if err != nil {
|
||||
return caddyhttp.Error(http.StatusInternalServerError, err)
|
||||
}
|
||||
w.WriteHeader(intVal)
|
||||
}
|
||||
|
||||
// if we do have an override from the previous two parts, then
|
||||
// we wrap the response writer to intercept the WriteHeader call
|
||||
if statusCodeOverride > 0 {
|
||||
w = statusOverrideResponseWriter{ResponseWriter: w, code: statusCodeOverride}
|
||||
}
|
||||
|
||||
// let the standard library do what it does best; note, however,
|
||||
|
@ -557,6 +557,20 @@ func redirect(w http.ResponseWriter, r *http.Request, to string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// statusOverrideResponseWriter intercepts WriteHeader calls
|
||||
// to instead write the HTTP status code we want instead
|
||||
// of the one http.ServeContent will use by default (usually 200)
|
||||
type statusOverrideResponseWriter struct {
|
||||
http.ResponseWriter
|
||||
code int
|
||||
}
|
||||
|
||||
// WriteHeader intercepts calls by the stdlib to WriteHeader
|
||||
// to instead write the HTTP status code we want.
|
||||
func (wr statusOverrideResponseWriter) WriteHeader(int) {
|
||||
wr.ResponseWriter.WriteHeader(wr.code)
|
||||
}
|
||||
|
||||
var defaultIndexNames = []string{"index.html", "index.txt"}
|
||||
|
||||
var bufPool = sync.Pool{
|
||||
|
|
Loading…
Reference in New Issue