mirror of
https://github.com/caddyserver/caddy.git
synced 2025-03-24 12:24:46 +03:00
* caddyhttp: Implement handler abort; new 'abort' directive (close #3871) * Move abort directive ordering; clean up redirects Seems logical for the end-all of handlers to go at the... end. The Connection header no longer needs to be set there, since Close is true, and the static_response handler now does that.
This commit is contained in:
parent
ab80ff4fd2
commit
e2c5c28597
4 changed files with 27 additions and 4 deletions
|
@ -40,6 +40,7 @@ func init() {
|
||||||
RegisterHandlerDirective("root", parseRoot)
|
RegisterHandlerDirective("root", parseRoot)
|
||||||
RegisterHandlerDirective("redir", parseRedir)
|
RegisterHandlerDirective("redir", parseRedir)
|
||||||
RegisterHandlerDirective("respond", parseRespond)
|
RegisterHandlerDirective("respond", parseRespond)
|
||||||
|
RegisterHandlerDirective("abort", parseAbort)
|
||||||
RegisterHandlerDirective("route", parseRoute)
|
RegisterHandlerDirective("route", parseRoute)
|
||||||
RegisterHandlerDirective("handle", parseHandle)
|
RegisterHandlerDirective("handle", parseHandle)
|
||||||
RegisterDirective("handle_errors", parseHandleErrors)
|
RegisterDirective("handle_errors", parseHandleErrors)
|
||||||
|
@ -502,6 +503,15 @@ func parseRespond(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
||||||
return sr, nil
|
return sr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseAbort parses the abort directive.
|
||||||
|
func parseAbort(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
||||||
|
h.Next() // consume directive
|
||||||
|
for h.Next() || h.NextBlock(0) {
|
||||||
|
return nil, h.ArgErr()
|
||||||
|
}
|
||||||
|
return &caddyhttp.StaticResponse{Abort: true}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// parseRoute parses the route directive.
|
// parseRoute parses the route directive.
|
||||||
func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
||||||
sr := new(caddyhttp.Subroute)
|
sr := new(caddyhttp.Subroute)
|
||||||
|
|
|
@ -69,6 +69,7 @@ var directiveOrder = []string{
|
||||||
"php_fastcgi",
|
"php_fastcgi",
|
||||||
"file_server",
|
"file_server",
|
||||||
"acme_server",
|
"acme_server",
|
||||||
|
"abort",
|
||||||
}
|
}
|
||||||
|
|
||||||
// directiveIsOrdered returns true if dir is
|
// directiveIsOrdered returns true if dir is
|
||||||
|
|
|
@ -409,8 +409,7 @@ func (app *App) makeRedirRoute(redirToPort uint, matcherSet MatcherSet) Route {
|
||||||
StaticResponse{
|
StaticResponse{
|
||||||
StatusCode: WeakString(strconv.Itoa(http.StatusPermanentRedirect)),
|
StatusCode: WeakString(strconv.Itoa(http.StatusPermanentRedirect)),
|
||||||
Headers: http.Header{
|
Headers: http.Header{
|
||||||
"Location": []string{redirTo},
|
"Location": []string{redirTo},
|
||||||
"Connection": []string{"close"},
|
|
||||||
},
|
},
|
||||||
Close: true,
|
Close: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,6 +42,11 @@ type StaticResponse struct {
|
||||||
// If true, the server will close the client's connection
|
// If true, the server will close the client's connection
|
||||||
// after writing the response.
|
// after writing the response.
|
||||||
Close bool `json:"close,omitempty"`
|
Close bool `json:"close,omitempty"`
|
||||||
|
|
||||||
|
// Immediately and forcefully closes the connection without
|
||||||
|
// writing a response. Interrupts any other HTTP streams on
|
||||||
|
// the same connection.
|
||||||
|
Abort bool `json:"abort,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CaddyModule returns the Caddy module information.
|
// CaddyModule returns the Caddy module information.
|
||||||
|
@ -101,10 +106,18 @@ func (s *StaticResponse) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StaticResponse) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error {
|
func (s StaticResponse) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error {
|
||||||
repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
|
// close the connection immediately
|
||||||
|
if s.Abort {
|
||||||
|
panic(http.ErrAbortHandler)
|
||||||
|
}
|
||||||
|
|
||||||
// close the connection after responding
|
// close the connection after responding
|
||||||
r.Close = s.Close
|
if s.Close {
|
||||||
|
r.Close = true
|
||||||
|
w.Header().Set("Connection", "close")
|
||||||
|
}
|
||||||
|
|
||||||
|
repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
|
||||||
|
|
||||||
// set all headers
|
// set all headers
|
||||||
for field, vals := range s.Headers {
|
for field, vals := range s.Headers {
|
||||||
|
|
Loading…
Reference in a new issue