summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/staticresp.go
diff options
context:
space:
mode:
authorMatt Holt <mholt@users.noreply.github.com>2021-01-28 12:54:55 -0700
committerGitHub <noreply@github.com>2021-01-28 12:54:55 -0700
commite2c5c28597e6a8c5e7ef48fde88f0b7d740d9586 (patch)
tree5182a73cc3aadd452b1eadce4370a05985c75c91 /modules/caddyhttp/staticresp.go
parentab80ff4fd2911afc394b9dbceeb9f71c7a0b7ec1 (diff)
caddyhttp: Implement handler abort; new 'abort' directive (close #3871) (#3983)
* 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.
Diffstat (limited to 'modules/caddyhttp/staticresp.go')
-rw-r--r--modules/caddyhttp/staticresp.go17
1 files changed, 15 insertions, 2 deletions
diff --git a/modules/caddyhttp/staticresp.go b/modules/caddyhttp/staticresp.go
index 0a568fc..4b11e0e 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 {