Skip to content

Commit 53f9bb6

Browse files
committed
Rework the order of ResponseWriter.Header and ResponseWriter.WriteHeader
1 parent d529a96 commit 53f9bb6

File tree

6 files changed

+23
-15
lines changed

6 files changed

+23
-15
lines changed

cors/cors.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,18 @@ type corsHandler struct {
3131
// ServeHTTP adds CORS headers.
3232
func (c corsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
3333
if r.Method == http.MethodOptions {
34-
w.WriteHeader(http.StatusNoContent)
34+
// According to the documentation for ResponseWriter.WriteHeader and
35+
// ResponseWriter.Header, modifications to the Header must happen BEFORE
36+
// any call to WriteHeader. That means it should be, in order:
37+
// 1. Write all your Headers
38+
// 2. Call WriteHeader to set your status
39+
// 3. Write to the body
3540
c.addCORSHeaders(w, r)
41+
w.WriteHeader(http.StatusNoContent)
3642
return
3743
}
38-
c.next.ServeHTTP(w, r)
3944
c.addCORSHeaders(w, r)
45+
c.next.ServeHTTP(w, r)
4046
}
4147

4248
func (c corsHandler) addCORSHeaders(w http.ResponseWriter, r *http.Request) {

dnt/do_not_track.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ type dntMiddleware struct {
2525

2626
func (d dntMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
2727
if RequestsDoNotTrack(r) {
28-
w.WriteHeader(http.StatusNoContent)
2928
SetDoNotTrack(w)
29+
// Note: All w.Header() modifications must be made BEFORE this call.
30+
w.WriteHeader(http.StatusNoContent)
3031
return
3132
}
3233
d.nextHandler.ServeHTTP(w, r)

jsv1/version1.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@ const returnedJavaScript = "(function(){})();"
1010
const lengthOfJavaScript = "17"
1111

1212
func Write(w http.ResponseWriter, code int) {
13-
w.WriteHeader(code)
1413
w.Header().Set("Content-Type", "application/javascript")
1514
w.Header().Set("Content-Length", lengthOfJavaScript)
15+
1616
fmt.Fprintf(w, returnedJavaScript)
1717
}
1818

1919
func Error(w http.ResponseWriter, code int, err string) {
20-
w.WriteHeader(code)
2120
content := fmt.Sprintf(`(function(){console.error("%s")})();`, err)
2221
w.Header().Set("Content-Type", "application/javascript")
2322
w.Header().Set("Content-Length", strconv.Itoa(len(content)))
23+
// Note: All w.Header() modifications must be made BEFORE this call.
24+
w.WriteHeader(code)
2425
fmt.Fprintf(w, content)
2526
}

jsv2/version2.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ function logVisit(document) {
3737
`
3838

3939
func Write(w http.ResponseWriter, code int) {
40-
w.WriteHeader(code)
4140
w.Header().Set("Content-Type", "application/javascript")
4241
w.Header().Set("Content-Length", strconv.Itoa(len(returnedJavaScript)))
42+
// Note: All w.Header() modifications must be made BEFORE this call.
43+
w.WriteHeader(code)
4344
fmt.Fprintf(w, returnedJavaScript)
4445
}

ping.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package ping
22

33
import (
4-
"encoding/json"
54
"errors"
65
"fmt"
76
"log"
@@ -36,12 +35,6 @@ func parseReferer(referer string) (*url.URL, error) {
3635
return url.Parse(referer)
3736
}
3837

39-
func jsonError(w http.ResponseWriter, statusCode int, message string) {
40-
w.WriteHeader(statusCode)
41-
w.Header().Set("Content-Type", "application/json")
42-
json.NewEncoder(w).Encode(map[string]string{"error": message})
43-
}
44-
4538
// ping routes to pingv1 or pingv2 depending on the version code in the form.
4639
func ping(w http.ResponseWriter, r *http.Request) {
4740
version := r.FormValue("v")

utils.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package ping
22

33
import (
44
"encoding/json"
5-
"fmt"
65
"net/http"
76
"strings"
87
)
@@ -11,12 +10,19 @@ func writeJsonResponse(w http.ResponseWriter, input interface{}) {
1110
w.Header().Set("Content-Type", "application/json")
1211
data, err := json.Marshal(input)
1312
if err != nil {
14-
fmt.Fprintf(w, `{"error":"json, `+err.Error()+`"}`)
13+
jsonError(w, http.StatusInternalServerError, err.Error())
1514
} else {
1615
w.Write(data)
1716
}
1817
}
1918

19+
func jsonError(w http.ResponseWriter, statusCode int, message string) {
20+
w.Header().Set("Content-Type", "application/json")
21+
// Note: All w.Header() modifications must be made BEFORE this call.
22+
w.WriteHeader(statusCode)
23+
json.NewEncoder(w).Encode(map[string]string{"error": message})
24+
}
25+
2026
func sanitizeUserInput(input string) string {
2127
escapedInput := strings.ReplaceAll(input, "\n", "")
2228
escapedInput = strings.ReplaceAll(escapedInput, "\r", "")

0 commit comments

Comments
 (0)