diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go index 08dfa886..2de808b9 100644 --- a/caddyconfig/httpcaddyfile/builtins.go +++ b/caddyconfig/httpcaddyfile/builtins.go @@ -40,6 +40,7 @@ func init() { RegisterHandlerDirective("root", parseRoot) RegisterHandlerDirective("redir", parseRedir) RegisterHandlerDirective("respond", parseRespond) + RegisterHandlerDirective("abort", parseAbort) RegisterHandlerDirective("route", parseRoute) RegisterHandlerDirective("handle", parseHandle) RegisterDirective("handle_errors", parseHandleErrors) @@ -502,6 +503,15 @@ func parseRespond(h Helper) (caddyhttp.MiddlewareHandler, error) { 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. func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) { sr := new(caddyhttp.Subroute) diff --git a/caddyconfig/httpcaddyfile/directives.go b/caddyconfig/httpcaddyfile/directives.go index b79b8116..7f77f49f 100644 --- a/caddyconfig/httpcaddyfile/directives.go +++ b/caddyconfig/httpcaddyfile/directives.go @@ -69,6 +69,7 @@ var directiveOrder = []string{ "php_fastcgi", "file_server", "acme_server", + "abort", } // directiveIsOrdered returns true if dir is diff --git a/modules/caddyhttp/autohttps.go b/modules/caddyhttp/autohttps.go index 9d6612fa..c1d4c087 100644 --- a/modules/caddyhttp/autohttps.go +++ b/modules/caddyhttp/autohttps.go @@ -409,8 +409,7 @@ func (app *App) makeRedirRoute(redirToPort uint, matcherSet MatcherSet) Route { StaticResponse{ StatusCode: WeakString(strconv.Itoa(http.StatusPermanentRedirect)), Headers: http.Header{ - "Location": []string{redirTo}, - "Connection": []string{"close"}, + "Location": []string{redirTo}, }, Close: true, }, diff --git a/modules/caddyhttp/staticresp.go b/modules/caddyhttp/staticresp.go index 0a568fc1..4b11e0e6 100644 --- a/modules/caddyhttp/staticresp.go +++ b/modules/caddyhttp/staticresp.go @@ -42,6 +42,11 @@ type StaticResponse struct { // If true, the server will close the client's connection // after writing the response. 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. @@ -101,10 +106,18 @@ func (s *StaticResponse) UnmarshalCaddyfile(d *caddyfile.Dispenser) 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 - 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 for field, vals := range s.Headers {