Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
Fix deferred header ops
Matthew Holt committed
May 20, 2019 at 22:00 UTC
b84cb058484e7900d60324da1289d319c77f5447
2 files changed
+24
-10
modules/caddyhttp/headers/headers.go
+18
-6
@@ -17,16 +17,16 @@ func init() {
17
18
// Headers is a middleware which can mutate HTTP headers.
19
type Headers struct {
20
- Request HeaderOps
21
- Response RespHeaderOps
20
+ Request HeaderOps `json:"request"`
21
+ Response RespHeaderOps `json:"response"`
22
}
23
24
// HeaderOps defines some operations to
25
// perform on HTTP headers.
26
type HeaderOps struct {
27
- Add http.Header
28
- Set http.Header
29
- Delete []string
27
+ Add http.Header `json:"add"`
28
+ Set http.Header `json:"set"`
29
+ Delete []string `json:"delete"`
30
}
31
32
// RespHeaderOps is like HeaderOps, but
@@ -67,10 +67,22 @@ func apply(ops HeaderOps, hdr http.Header) {
67
// operations until WriteHeader is called.
68
type responseWriterWrapper struct {
69
*caddyhttp.ResponseWriterWrapper
70
- headerOps HeaderOps
70
+ headerOps HeaderOps
71
+ wroteHeader bool
72
+}
73
+
74
+func (rww *responseWriterWrapper) Write(d []byte) (int, error) {
75
+ if !rww.wroteHeader {
76
+ rww.WriteHeader(http.StatusOK)
77
+ }
78
+ return rww.ResponseWriterWrapper.Write(d)
79
}
80
81
func (rww *responseWriterWrapper) WriteHeader(status int) {
82
+ if rww.wroteHeader {
83
+ return
84
+ }
85
+ rww.wroteHeader = true
86
apply(rww.headerOps, rww.ResponseWriterWrapper.Header())
87
rww.ResponseWriterWrapper.WriteHeader(status)
88
}
modules/caddyhttp/staticresp.go
+6
-4
@@ -17,7 +17,7 @@ func init() {
17
18
// Static implements a simple responder for static responses.
19
type Static struct {
20
- StatusCode int `json:"status_code"`
20
+ StatusCode int `json:"status_code"` // TODO: should we turn this into a string so that only one field is needed? (string allows replacements)
21
StatusCodeStr string `json:"status_code_str"`
22
Headers http.Header `json:"headers"`
23
Body string `json:"body"`
@@ -30,7 +30,7 @@ func (s Static) ServeHTTP(w http.ResponseWriter, r *http.Request) error {
30
// close the connection after responding
31
r.Close = s.Close
32
33
- // set all headers, with replacements
33
+ // set all headers
34
for field, vals := range s.Headers {
35
field = repl.ReplaceAll(field, "")
36
for i := range vals {
@@ -39,7 +39,7 @@ func (s Static) ServeHTTP(w http.ResponseWriter, r *http.Request) error {
39
w.Header()[field] = vals
40
}
41
42
- // write the headers with a status code
42
+ // get the status code
43
statusCode := s.StatusCode
44
if statusCode == 0 && s.StatusCodeStr != "" {
45
intVal, err := strconv.Atoi(repl.ReplaceAll(s.StatusCodeStr, ""))
@@ -50,9 +50,11 @@ func (s Static) ServeHTTP(w http.ResponseWriter, r *http.Request) error {
50
if statusCode == 0 {
51
statusCode = http.StatusOK
52
}
53
+
54
+ // write headers
55
w.WriteHeader(statusCode)
56
55
- // write the response body, with replacements
57
+ // write response body
58
if s.Body != "" {
59
fmt.Fprint(w, repl.ReplaceAll(s.Body, ""))
60
}