Repository: google/go-safeweb
Pull request #218 (2020-11-12 10:04:55)

ResponseWriter is now an interface.
This is needed for further refactorings of the ResponseWriter where we plan to handle errors due to double-writing, panicking and so on better.

kele: @bsiegert Done!

Patch:
diff --git a/safehttp/handler.go b/safehttp/handler.go
index a49e9ff..46c9665 100644
--- a/safehttp/handler.go
+++ b/safehttp/handler.go
@@ -21,13 +21,13 @@ type Handler interface {
 	// Except for reading the body, handlers should not modify the provided Request.
 	//
 	// TODO: Add documentation about error handling when properly implemented.
-	ServeHTTP(*ResponseWriter, *IncomingRequest) Result
+	ServeHTTP(ResponseWriter, *IncomingRequest) Result
 }
 
 // HandlerFunc is used to convert a function into a Handler.
-type HandlerFunc func(*ResponseWriter, *IncomingRequest) Result
+type HandlerFunc func(ResponseWriter, *IncomingRequest) Result
 
 // ServeHTTP calls f(w, r).
-func (f HandlerFunc) ServeHTTP(w *ResponseWriter, r *IncomingRequest) Result {
+func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *IncomingRequest) Result {
 	return f(w, r)
 }
diff --git a/safehttp/interceptor.go b/safehttp/interceptor.go
index 96f730b..ce8cbbe 100644
--- a/safehttp/interceptor.go
+++ b/safehttp/interceptor.go
@@ -24,17 +24,17 @@ type Interceptor interface {
 	// response is written to the ResponseWriter, then the remaining
 	// interceptors and the handler won't execute. If Before panics, it will be
 	// recovered and the ServeMux will respond with 500 Internal Server Error.
-	Before(w *ResponseWriter, r *IncomingRequest, cfg InterceptorConfig) Result
+	Before(w ResponseWriter, r *IncomingRequest, cfg InterceptorConfig) Result
 
 	// Commit runs before the response is written by the Dispatcher. If an error
 	// is written to the ResponseWriter, then the Commit phases from the
 	// remaining interceptors won't execute.
-	Commit(w *ResponseWriter, r *IncomingRequest, resp Response, cfg InterceptorConfig) Result
+	Commit(w ResponseWriter, r *IncomingRequest, resp Response, cfg InterceptorConfig) Result
 
 	// OnError runs when ResponseWriter.WriteError is called, before the
 	// actual error response is written. An attempt to write to the
 	// ResponseWriter in this phase will result in an irrecoverable error.
-	OnError(w *ResponseWriter, r *IncomingRequest, resp Response, cfg InterceptorConfig) Result
+	OnError(w ResponseWriter, r *IncomingRequest, resp Response, cfg InterceptorConfig) Result
 }
 
 // InterceptorConfig is a configuration of an interceptor.
@@ -54,20 +54,20 @@ type ConfiguredInterceptor struct {
 // response is written to the ResponseWriter, then the remaining
 // interceptors and the handler won't execute. If Before panics, it will be
 // recovered and the ServeMux will respond with 500 Internal Server Error.
-func (ci *ConfiguredInterceptor) Before(w *ResponseWriter, r *IncomingRequest) Result {
+func (ci *ConfiguredInterceptor) Before(w ResponseWriter, r *IncomingRequest) Result {
 	return ci.interceptor.Before(w, r, ci.config)
 }
 
 // Commit runs before the response is written by the Dispatcher. If an error
 // is written to the ResponseWriter, then the Commit phases from the
 // remaining interceptors won't execute.
-func (ci *ConfiguredInterceptor) Commit(w *ResponseWriter, r *IncomingRequest, resp Response) Result {
+func (ci *ConfiguredInterceptor) Commit(w ResponseWriter, r *IncomingRequest, resp Response) Result {
 	return ci.interceptor.Commit(w, r, resp, ci.config)
 }
 
 // OnError runs when ResponseWriter.WriteError is called, before the
 // actual error response is written. An attempt to write to the
 // ResponseWriter in this phase will result in an irrecoverable error.
-func (ci *ConfiguredInterceptor) OnError(w *ResponseWriter, r *IncomingRequest, resp Response) Result {
+func (ci *ConfiguredInterceptor) OnError(w ResponseWriter, r *IncomingRequest, resp Response) Result {
 	return ci.interceptor.OnError(w, r, resp, ci.config)
 }
diff --git a/safehttp/mux.go b/safehttp/mux.go
index 7da5309..bd8cf7c 100644
--- a/safehttp/mux.go
+++ b/safehttp/mux.go
@@ -246,7 +246,7 @@ type handler struct {
 // Error response is sent.
 func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	ir := NewIncomingRequest(r)
-	rw := NewResponseWriter(h.disp, w, ir)
+	rw := newResponseWriter(h.disp, w, ir)
 	rw.handler = h
 
 	// The `net/http` package recovers handler panics, but we cannot rely on that behavior here.
@@ -280,7 +280,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 // are called in Commit then this will recurse. CommitResponseWriter was an
 // attempt to prevent this by not giving access to Write and WriteTemplate in
 // the Commit phase.
-func (h handler) commitPhase(w *ResponseWriter, resp Response) {
+func (h handler) commitPhase(w *responseWriter, resp Response) {
 	for i := len(h.interceps) - 1; i >= 0; i-- {
 		it := h.interceps[i]
 		it.Commit(w, w.req, resp)
@@ -296,7 +296,7 @@ func (h handler) commitPhase(w *ResponseWriter, resp Response) {
 //
 // TODO: BIG WARNING, if an interceptor attempts to write to the ResponseWriter
 // in the OnError phase will result in an irrecoverable error.
-func (h handler) errorPhase(w *ResponseWriter, resp Response) {
+func (h handler) errorPhase(w *responseWriter, resp Response) {
 	for i := len(h.interceps) - 1; i >= 0; i-- {
 		it := h.interceps[i]
 		it.OnError(w, w.req, resp)
diff --git a/safehttp/plugins/collector/collector.go b/safehttp/plugins/collector/collector.go
index ec58045..3b2595e 100644
--- a/safehttp/plugins/collector/collector.go
+++ b/safehttp/plugins/collector/collector.go
@@ -89,7 +89,7 @@ type CSPReport struct {
 // requests. If the handler recieves anything other than POST requests it will
 // respond with a 405 Method Not Allowed.
 func Handler(handler func(Report), cspHandler func(CSPReport)) safehttp.Handler {
-	return safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+	return safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		if r.Method() != safehttp.MethodPost {
 			return w.WriteError(safehttp.StatusMethodNotAllowed)
 		}
@@ -110,7 +110,7 @@ func Handler(handler func(Report), cspHandler func(CSPReport)) safehttp.Handler
 	})
 }
 
-func handleDeprecatedCSPReports(h func(CSPReport), w *safehttp.ResponseWriter, b []byte) safehttp.Result {
+func handleDeprecatedCSPReports(h func(CSPReport), w safehttp.ResponseWriter, b []byte) safehttp.Result {
 	// In CSP2 it is clearly stated that a report has a single key 'csp-report'
 	// which holds the report object. Like this:
 	// {
@@ -187,7 +187,7 @@ var reportHandlers = map[string]func(json.RawMessage) (body interface{}, ok bool
 	"csp-violation": cspViolationHandler,
 }
 
-func handleReport(h func(Report), w *safehttp.ResponseWriter, b []byte) safehttp.Result {
+func handleReport(h func(Report), w safehttp.ResponseWriter, b []byte) safehttp.Result {
 	var rList []struct {
 		Type      string          `json:"type"`
 		Age       uint64          `json:"age"`
diff --git a/safehttp/plugins/coop/coop.go b/safehttp/plugins/coop/coop.go
index cf5e175..e460c53 100644
--- a/safehttp/plugins/coop/coop.go
+++ b/safehttp/plugins/coop/coop.go
@@ -80,7 +80,7 @@ func Default(reportGroup string) Interceptor {
 type Interceptor serializedPolicies
 
 // Before claims and sets the Report-Only and Enforcement headers for COOP.
-func (it Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	if cfg != nil {
 		// We got an override, run its Before phase instead.
 		return Interceptor(cfg.(Overrider)).Before(w, r, nil)
@@ -91,7 +91,7 @@ func (it Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingReq
 }
 
 // Commit is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (it Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
@@ -99,7 +99,7 @@ func (it Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingReq
 //
 // TODO: should OnError take as argument something that notifies it the commit
 // phase was already called?
-func (it Interceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
diff --git a/safehttp/plugins/cors/cors.go b/safehttp/plugins/cors/cors.go
index b0b0f6a..3f00fc0 100644
--- a/safehttp/plugins/cors/cors.go
+++ b/safehttp/plugins/cors/cors.go
@@ -111,7 +111,7 @@ func (it *Interceptor) SetAllowedHeaders(headers ...string) {
 //  - Access-Control-Expose-Headers
 //  - Access-Control-Max-Age
 //  - Vary
-func (it *Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it *Interceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
 	origin := r.Header.Get("Origin")
 	if origin != "" && !it.AllowedOrigins[origin] {
 		return w.WriteError(safehttp.StatusForbidden)
@@ -155,11 +155,11 @@ func (it *Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRe
 }
 
 // Commit is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (it *Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (it *Interceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
-func appendToVary(w *safehttp.ResponseWriter, val string) {
+func appendToVary(w safehttp.ResponseWriter, val string) {
 	h := w.Header()
 	if curr := h.Get("Vary"); curr != "" {
 		h.Set("Vary", curr+", "+val)
@@ -169,12 +169,12 @@ func appendToVary(w *safehttp.ResponseWriter, val string) {
 }
 
 // OnError is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (it Interceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 // preflight handles requests that have the method OPTIONS.
-func (it *Interceptor) preflight(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.StatusCode {
+func (it *Interceptor) preflight(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.StatusCode {
 	rh := r.Header
 	if rh.Get("Origin") == "" {
 		return safehttp.StatusForbidden
@@ -213,7 +213,7 @@ func (it *Interceptor) preflight(w *safehttp.ResponseWriter, r *safehttp.Incomin
 }
 
 // request handles all requests that are not preflight requests.
-func (it *Interceptor) request(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.StatusCode {
+func (it *Interceptor) request(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.StatusCode {
 	h := r.Header
 	if h.Get(requiredHeader) != "1" {
 		return safehttp.StatusPreconditionFailed
diff --git a/safehttp/plugins/csp/csp.go b/safehttp/plugins/csp/csp.go
index 790532e..47065a3 100644
--- a/safehttp/plugins/csp/csp.go
+++ b/safehttp/plugins/csp/csp.go
@@ -193,7 +193,7 @@ func Default(reportURI string) Interceptor {
 
 // Before claims and sets the Content-Security-Policy header and the
 // Content-Security-Policy-Report-Only header.
-func (it Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
 	nonce := generateNonce()
 	r.SetContext(context.WithValue(r.Context(), ctxKey{}, nonce))
 
@@ -219,7 +219,7 @@ func (it Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingReq
 // Commit adds the nonce to the safehttp.TemplateResponse which is going to be
 // injected as the value of the nonce attribute in <script> and <link> tags. The
 // nonce is going to be unique for each safehttp.IncomingRequest.
-func (it Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	tmplResp, ok := resp.(safehttp.TemplateResponse)
 	if !ok {
 		return safehttp.NotWritten()
@@ -241,6 +241,6 @@ func (it Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingReq
 }
 
 // OnError is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (it Interceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
diff --git a/safehttp/plugins/fetch_metadata/fetch_metadata.go b/safehttp/plugins/fetch_metadata/fetch_metadata.go
index ca3233e..b1779ec 100644
--- a/safehttp/plugins/fetch_metadata/fetch_metadata.go
+++ b/safehttp/plugins/fetch_metadata/fetch_metadata.go
@@ -138,7 +138,7 @@ func (p *Plugin) SetEnforce() {
 // the  violation is reported. If a redirectURL was provided and the Navigation
 // Isolation Policy is enabled and fails, the IncomingRequest will be
 // redirected to redirectURL.
-func (p *Plugin) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
+func (p *Plugin) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
 	// TODO(mihalimara22): Remove and disable using configurations when those
 	// have been implemented
 	if p.corsProtected[r.URL.Path()] {
@@ -170,11 +170,11 @@ func (p *Plugin) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest,
 }
 
 // Commit is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (p *Plugin) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (p *Plugin) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 // OnError is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (p *Plugin) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (p *Plugin) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
diff --git a/safehttp/plugins/hostcheck/hostcheck.go b/safehttp/plugins/hostcheck/hostcheck.go
index 75e1978..eaa373e 100644
--- a/safehttp/plugins/hostcheck/hostcheck.go
+++ b/safehttp/plugins/hostcheck/hostcheck.go
@@ -43,7 +43,7 @@ func New(hosts ...string) Interceptor {
 
 // Before checks whether the request's Host header is in the list of allowed
 // hosts. If it's not, it responds with 404 Not Found.
-func (it Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
 	if !it.hosts[r.Host()] {
 		return w.WriteError(safehttp.StatusNotFound)
 	}
@@ -51,11 +51,11 @@ func (it Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingReq
 }
 
 // Commit is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (Interceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 // OnError is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (Interceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (Interceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
diff --git a/safehttp/plugins/hsts/hsts.go b/safehttp/plugins/hsts/hsts.go
index c1d3322..f69d725 100644
--- a/safehttp/plugins/hsts/hsts.go
+++ b/safehttp/plugins/hsts/hsts.go
@@ -84,7 +84,7 @@ func Default() Interceptor {
 // The function redirects HTTP requests to HTTPS. When HTTPS traffic
 // is received the Strict-Transport-Security header is applied to the
 // response.
-func (it Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
 	if it.MaxAge < 0 {
 		return w.WriteError(safehttp.StatusInternalServerError)
 	}
@@ -113,11 +113,11 @@ func (it Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingReq
 }
 
 // Commit is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (it Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 // OnError is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (it Interceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it Interceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
diff --git a/safehttp/plugins/staticheaders/staticheaders.go b/safehttp/plugins/staticheaders/staticheaders.go
index c904162..39afd22 100644
--- a/safehttp/plugins/staticheaders/staticheaders.go
+++ b/safehttp/plugins/staticheaders/staticheaders.go
@@ -40,7 +40,7 @@ var _ safehttp.Interceptor = Interceptor{}
 // Before claims and sets the following headers:
 //  - X-Content-Type-Options: nosniff
 //  - X-XSS-Protection: 0
-func (Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
+func (Interceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
 	h := w.Header()
 	setXCTO := h.Claim("X-Content-Type-Options")
 	setXXP := h.Claim("X-XSS-Protection")
@@ -51,11 +51,11 @@ func (Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingReques
 }
 
 // Commit is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (Interceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 // OnError is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (Interceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (Interceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
diff --git a/safehttp/plugins/xsrf/angular/xsrf.go b/safehttp/plugins/xsrf/angular/xsrf.go
index 29d6e64..f8428bf 100644
--- a/safehttp/plugins/xsrf/angular/xsrf.go
+++ b/safehttp/plugins/xsrf/angular/xsrf.go
@@ -52,7 +52,7 @@ func Default() *Interceptor {
 // Before checks for the presence of a matching XSRF token, generated on the
 // first page access, in both a cookie and a header. Their names should be set
 // when the Interceptor is created.
-func (it *Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it *Interceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
 	if xsrf.StatePreserving(r) {
 		return safehttp.NotWritten()
 	}
@@ -73,7 +73,7 @@ func (it *Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRe
 	return safehttp.NotWritten()
 }
 
-func (it *Interceptor) addTokenCookie(w *safehttp.ResponseWriter) error {
+func (it *Interceptor) addTokenCookie(w safehttp.ResponseWriter) error {
 	tok := make([]byte, 20)
 	if _, err := rand.Read(tok); err != nil {
 		return fmt.Errorf("crypto/rand.Read: %v", err)
@@ -95,7 +95,7 @@ func (it *Interceptor) addTokenCookie(w *safehttp.ResponseWriter) error {
 // preserving request (GET, HEAD or OPTION) and sets it in the response. On
 // every subsequent request the cookie is expected alongside a header that
 // matches its value.
-func (it *Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it *Interceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	if c, err := r.Cookie(it.TokenCookieName); err == nil && c.Value() != "" {
 		// The XSRF cookie is there so we don't need to do anything else.
 		return safehttp.NotWritten()
@@ -115,6 +115,6 @@ func (it *Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRe
 }
 
 // OnError is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (it *Interceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it *Interceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
diff --git a/safehttp/plugins/xsrf/html/xsrf.go b/safehttp/plugins/xsrf/html/xsrf.go
index af67e33..a65fdb5 100644
--- a/safehttp/plugins/xsrf/html/xsrf.go
+++ b/safehttp/plugins/xsrf/html/xsrf.go
@@ -40,7 +40,7 @@ type Interceptor struct {
 
 var _ safehttp.Interceptor = &Interceptor{}
 
-func addCookieID(w *safehttp.ResponseWriter) (*safehttp.Cookie, error) {
+func addCookieID(w safehttp.ResponseWriter) (*safehttp.Cookie, error) {
 	buf := make([]byte, 20)
 	if _, err := rand.Read(buf); err != nil {
 		return nil, fmt.Errorf("crypto/rand.Read: %v", err)
@@ -56,7 +56,7 @@ func addCookieID(w *safehttp.ResponseWriter) (*safehttp.Cookie, error) {
 
 // Before checks for the presence of a XSRF token in the body of state changing
 // requests (all except GET, HEAD and OPTIONS) and validates it.
-func (it *Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it *Interceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
 	if xsrf.StatePreserving(r) {
 		return safehttp.NotWritten()
 	}
@@ -103,7 +103,7 @@ func (it *Interceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRe
 // For every authorized request, the interceptor also generates a
 // cryptographically-safe XSRF token using the appKey, the cookie and the path
 // visited. This is then injected as a hidden input field in HTML forms.
-func (it *Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it *Interceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	cookieID, err := r.Cookie(cookieIDKey)
 	if err != nil {
 		if !xsrf.StatePreserving(r) {
@@ -130,6 +130,6 @@ func (it *Interceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRe
 }
 
 // OnError is a no-op, required to satisfy the safehttp.Interceptor interface.
-func (it *Interceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (it *Interceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
diff --git a/safehttp/response.go b/safehttp/response.go
index 2c7719b..0b0f751 100644
--- a/safehttp/response.go
+++ b/safehttp/response.go
@@ -32,7 +32,7 @@ type JSONResponse struct {
 // WriteJSON creates a JSONResponse from the data object and calls the Write
 // function of the ResponseWriter, passing the response. The data object should
 // be valid JSON, otherwise an error will occur.
-func WriteJSON(w *ResponseWriter, data interface{}) Result {
+func WriteJSON(w ResponseWriter, data interface{}) Result {
 	return w.Write(JSONResponse{data})
 }
 
@@ -58,14 +58,14 @@ type TemplateResponse struct {
 // ExecuteTemplate creates a TemplateResponse from the provided Template and its
 // data and calls the Write function of the ResponseWriter, passing the
 // response.
-func ExecuteTemplate(w *ResponseWriter, t Template, data interface{}) Result {
+func ExecuteTemplate(w ResponseWriter, t Template, data interface{}) Result {
 	return w.Write(TemplateResponse{t, data, nil})
 }
 
 // ExecuteTemplateWithFuncs creates a TemplateResponse from the provided
 // Template, its data and the name to function mappings and calls the Write
 // function of the ResponseWriter, passing the response.
-func ExecuteTemplateWithFuncs(w *ResponseWriter, t Template, data interface{}, fm map[string]interface{}) Result {
+func ExecuteTemplateWithFuncs(w ResponseWriter, t Template, data interface{}, fm map[string]interface{}) Result {
 	return w.Write(TemplateResponse{t, data, fm})
 }
 
diff --git a/safehttp/response_writer.go b/safehttp/response_writer.go
index a306061..529ebc4 100644
--- a/safehttp/response_writer.go
+++ b/safehttp/response_writer.go
@@ -24,7 +24,45 @@ import (
 // cause a panic.
 //
 // A ResponseWriter may not be used after the Handler.ServeHTTP method has returned.
-type ResponseWriter struct {
+type ResponseWriter interface {
+	// Write writes a safe response.
+	Write(resp Response) Result
+
+	// NoContent responds with a 204 No Content response.
+	//
+	// If the ResponseWriter has already been written to, then this method panics.
+	NoContent() Result
+
+	// WriteError writes an error response (400-599) according to the provided status code.
+	//
+	// If the ResponseWriter has already been written to, then this method panics.
+	WriteError(code StatusCode) Result
+
+	// Redirect responds with a redirect to the given url, using code as the status code.
+	//
+	// If the ResponseWriter has already been written to, then this method panics.
+	Redirect(r *IncomingRequest, url string, code StatusCode) Result
+
+	// Header returns the collection of headers that will be set
+	// on the response. Headers must be set before writing a
+	// response (e.g. Write, WriteTemplate).
+	Header() Header
+
+	// SetCookie adds a Set-Cookie header to the provided ResponseWriter's headers.
+	// The provided cookie must have a valid Name, otherwise an error will be
+	// returned.
+	SetCookie(c *Cookie) error
+
+	// SetCode allows setting a response status. If the response was already
+	// written, trying to set the status code will have no effect. This method will
+	// panic if an invalid status code is passed (i.e. not in the range 1XX-5XX).
+	//
+	// If SetCode was called before NoContent, Redirect or WriteError, the status
+	// code set by the latter will be the actual response status.
+	SetCode(code StatusCode)
+}
+
+type responseWriter struct {
 	d  Dispatcher
 	rw http.ResponseWriter
 
@@ -42,9 +80,13 @@ type ResponseWriter struct {
 // The IncomingRequest will only be used by the commit phase, which only runs when
 // the ServeMux is used, and can be passed as nil in tests.
 // TODO: remove the IncomingRequest parameter.
-func NewResponseWriter(d Dispatcher, rw http.ResponseWriter, req *IncomingRequest) *ResponseWriter {
+func NewResponseWriter(d Dispatcher, rw http.ResponseWriter, req *IncomingRequest) ResponseWriter {
+	return newResponseWriter(d, rw, req)
+}
+
+func newResponseWriter(d Dispatcher, rw http.ResponseWriter, req *IncomingRequest) *responseWriter {
 	header := newHeader(rw.Header())
-	return &ResponseWriter{
+	return &responseWriter{
 		d:      d,
 		rw:     rw,
 		header: header,
@@ -71,7 +113,7 @@ func NotWritten() Result {
 // underlying http.ResponseWriter if the Dispatcher decides it's safe to do so.
 //
 // TODO: replace panics with proper error handling when writing the response fails.
-func (w *ResponseWriter) Write(resp Response) Result {
+func (w *responseWriter) Write(resp Response) Result {
 	if w.written {
 		panic("ResponseWriter was already written to")
 	}
@@ -103,7 +145,7 @@ func (w *ResponseWriter) Write(resp Response) Result {
 // NoContent responds with a 204 No Content response.
 //
 // If the ResponseWriter has already been written to, then this method will panic.
-func (w *ResponseWriter) NoContent() Result {
+func (w *responseWriter) NoContent() Result {
 	if w.written {
 		panic("ResponseWriter was already written to")
 	}
@@ -120,7 +162,7 @@ func (w *ResponseWriter) NoContent() Result {
 // status code.
 //
 // If the ResponseWriter has already been written to, then this method will panic.
-func (w *ResponseWriter) WriteError(code StatusCode) Result {
+func (w *responseWriter) WriteError(code StatusCode) Result {
 	w.markWritten()
 	resp := &ErrorResponse{Code: code}
 	w.handler.errorPhase(w, resp)
@@ -131,7 +173,7 @@ func (w *ResponseWriter) WriteError(code StatusCode) Result {
 // Redirect responds with a redirect to the given url, using code as the status code.
 //
 // If the ResponseWriter has already been written to, then this method will panic.
-func (w *ResponseWriter) Redirect(r *IncomingRequest, url string, code StatusCode) Result {
+func (w *responseWriter) Redirect(r *IncomingRequest, url string, code StatusCode) Result {
 	if code < 300 || code >= 400 {
 		panic("wrong method called")
 	}
@@ -142,7 +184,7 @@ func (w *ResponseWriter) Redirect(r *IncomingRequest, url string, code StatusCod
 
 // markWritten ensures that the ResponseWriter is only written to once by panicking
 // if it is written more than once.
-func (w *ResponseWriter) markWritten() {
+func (w *responseWriter) markWritten() {
 	if w.written {
 		panic("ResponseWriter was already written to")
 	}
@@ -152,14 +194,14 @@ func (w *ResponseWriter) markWritten() {
 // Header returns the collection of headers that will be set
 // on the response. Headers must be set before writing a
 // response (e.g. Write, WriteTemplate).
-func (w ResponseWriter) Header() Header {
+func (w responseWriter) Header() Header {
 	return w.header
 }
 
 // SetCookie adds a Set-Cookie header to the provided ResponseWriter's headers.
 // The provided cookie must have a valid Name, otherwise an error will be
 // returned.
-func (w *ResponseWriter) SetCookie(c *Cookie) error {
+func (w *responseWriter) SetCookie(c *Cookie) error {
 	return w.header.addCookie(c)
 }
 
@@ -172,7 +214,7 @@ func (w *ResponseWriter) SetCookie(c *Cookie) error {
 //
 // TODO(empijei@, kele@, maramihali@): decide what should be done if the
 // code passed is either 3XX (redirect) or 4XX-5XX (client/server error).
-func (w *ResponseWriter) SetCode(code StatusCode) {
+func (w *responseWriter) SetCode(code StatusCode) {
 	if w.written {
 		return
 	}


Test patch:
diff --git a/safehttp/mux_test.go b/safehttp/mux_test.go
index 4bda01e..373ec6b 100644
--- a/safehttp/mux_test.go
+++ b/safehttp/mux_test.go
@@ -61,7 +61,7 @@ func TestMuxOneHandlerOneRequest(t *testing.T) {
 		t.Run(tt.name, func(t *testing.T) {
 			mb := &safehttp.ServeMuxConfig{}
 
-			h := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			h := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 			})
 			mb.Handle("/", safehttp.MethodGet, h)
@@ -99,7 +99,7 @@ func TestMuxServeTwoHandlers(t *testing.T) {
 		{
 			name: "GET Handler",
 			req:  httptest.NewRequest(safehttp.MethodGet, "http://foo.com/bar", nil),
-			hf: safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			hf: safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write(safehtml.HTMLEscaped("<h1>Hello World! GET</h1>"))
 			}),
 			wantStatus: safehttp.StatusOK,
@@ -111,7 +111,7 @@ func TestMuxServeTwoHandlers(t *testing.T) {
 		{
 			name: "POST Handler",
 			req:  httptest.NewRequest(safehttp.MethodPost, "http://foo.com/bar", nil),
-			hf: safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			hf: safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write(safehtml.HTMLEscaped("<h1>Hello World! POST</h1>"))
 			}),
 			wantStatus: safehttp.StatusOK,
@@ -148,7 +148,7 @@ func TestMuxServeTwoHandlers(t *testing.T) {
 func TestMuxHandleSameMethodTwice(t *testing.T) {
 	mb := &safehttp.ServeMuxConfig{}
 
-	registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+	registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 	})
 	mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
@@ -169,31 +169,31 @@ type setHeaderInterceptor struct {
 	value string
 }
 
-func (p setHeaderInterceptor) Before(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (p setHeaderInterceptor) Before(w safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	w.Header().Set(p.name, p.value)
 	return safehttp.NotWritten()
 }
 
-func (p setHeaderInterceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (p setHeaderInterceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
-func (p setHeaderInterceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (p setHeaderInterceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 type internalErrorInterceptor struct{}
 
-func (internalErrorInterceptor) Before(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (internalErrorInterceptor) Before(w safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return w.WriteError(safehttp.StatusInternalServerError)
 }
 
-func (internalErrorInterceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (internalErrorInterceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	w.Header().Set("Foo", "this should not be reached")
 	return safehttp.NotWritten()
 }
 
-func (internalErrorInterceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (internalErrorInterceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
@@ -203,66 +203,66 @@ type claimHeaderInterceptor struct {
 
 type claimCtxKey struct{}
 
-func (p *claimHeaderInterceptor) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (p *claimHeaderInterceptor) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	f := w.Header().Claim(p.headerToClaim)
 	r.SetContext(context.WithValue(r.Context(), claimCtxKey{}, f))
 	return safehttp.NotWritten()
 }
 
-func (p *claimHeaderInterceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (p *claimHeaderInterceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
-func (p *claimHeaderInterceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (p *claimHeaderInterceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
-func claimInterceptorSetHeader(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, value string) {
+func claimInterceptorSetHeader(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, value string) {
 	f := r.Context().Value(claimCtxKey{}).(func([]string))
 	f([]string{value})
 }
 
 type panickingInterceptor struct{}
 
-func (panickingInterceptor) Before(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (panickingInterceptor) Before(w safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	panic("bad")
 }
 
-func (panickingInterceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (panickingInterceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
-func (panickingInterceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (panickingInterceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 type committerInterceptor struct{}
 
-func (committerInterceptor) Before(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (committerInterceptor) Before(w safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
-func (committerInterceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (committerInterceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	w.Header().Set("foo", "bar")
 	return safehttp.NotWritten()
 }
 
-func (committerInterceptor) OnError(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, _ safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (committerInterceptor) OnError(w safehttp.ResponseWriter, _ *safehttp.IncomingRequest, _ safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 type setHeaderErroringInterceptor struct{}
 
-func (setHeaderErroringInterceptor) Before(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (setHeaderErroringInterceptor) Before(w safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return w.WriteError(safehttp.StatusForbidden)
 }
 
-func (setHeaderErroringInterceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (setHeaderErroringInterceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	w.Header().Set("name", "foo")
 	return safehttp.Result{}
 }
 
-func (setHeaderErroringInterceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (setHeaderErroringInterceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	w.Header().Set("name", "bar")
 	return safehttp.Result{}
 }
@@ -284,7 +284,7 @@ func TestMuxInterceptors(t *testing.T) {
 					value: "bar",
 				})
 
-				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+				registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
@@ -303,7 +303,7 @@ func TestMuxInterceptors(t *testing.T) {
 				mb := &safehttp.ServeMuxConfig{}
 				mb.Intercept(internalErrorInterceptor{})
 
-				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+				registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
@@ -323,7 +323,7 @@ func TestMuxInterceptors(t *testing.T) {
 				mb := &safehttp.ServeMuxConfig{}
 				mb.Intercept(&claimHeaderInterceptor{headerToClaim: "Foo"})
 
-				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+				registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					claimInterceptorSetHeader(w, r, "bar")
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
@@ -344,7 +344,7 @@ func TestMuxInterceptors(t *testing.T) {
 				mb := &safehttp.ServeMuxConfig{}
 				mb.Intercept(panickingInterceptor{})
 
-				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+				registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
@@ -364,7 +364,7 @@ func TestMuxInterceptors(t *testing.T) {
 				mb := &safehttp.ServeMuxConfig{}
 				mb.Intercept(committerInterceptor{})
 
-				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+				registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
@@ -384,7 +384,7 @@ func TestMuxInterceptors(t *testing.T) {
 				mb := &safehttp.ServeMuxConfig{}
 				mb.Intercept(setHeaderErroringInterceptor{})
 
-				registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+				registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 					return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 				})
 				mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
@@ -437,7 +437,7 @@ func (setHeaderConfig) Match(i safehttp.Interceptor) bool {
 
 type setHeaderConfigInterceptor struct{}
 
-func (p setHeaderConfigInterceptor) Before(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (p setHeaderConfigInterceptor) Before(w safehttp.ResponseWriter, _ *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	name := "Pizza"
 	value := "Hawaii"
 	if c, ok := cfg.(setHeaderConfig); ok {
@@ -448,7 +448,7 @@ func (p setHeaderConfigInterceptor) Before(w *safehttp.ResponseWriter, _ *safeht
 	return safehttp.NotWritten()
 }
 
-func (p setHeaderConfigInterceptor) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (p setHeaderConfigInterceptor) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	name := "Commit-Pizza"
 	value := "Hawaii"
 	if c, ok := cfg.(setHeaderConfig); ok {
@@ -459,7 +459,7 @@ func (p setHeaderConfigInterceptor) Commit(w *safehttp.ResponseWriter, r *safeht
 	return safehttp.NotWritten()
 }
 
-func (p setHeaderConfigInterceptor) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (p setHeaderConfigInterceptor) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
@@ -506,7 +506,7 @@ func TestMuxInterceptorConfigs(t *testing.T) {
 			mb := &safehttp.ServeMuxConfig{}
 			mb.Intercept(setHeaderConfigInterceptor{})
 
-			registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 			})
 			mb.Handle("/bar", safehttp.MethodGet, registeredHandler, tt.config)
@@ -536,12 +536,12 @@ func TestMuxInterceptorConfigs(t *testing.T) {
 
 type interceptorOne struct{}
 
-func (interceptorOne) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (interceptorOne) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	w.Header().Set("pizza", "diavola")
 	return safehttp.NotWritten()
 }
 
-func (interceptorOne) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (interceptorOne) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	if w.Header().Get("Commit2") != "b" {
 		w.WriteError(safehttp.StatusInternalServerError)
 	}
@@ -549,13 +549,13 @@ func (interceptorOne) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingReq
 	return safehttp.NotWritten()
 }
 
-func (interceptorOne) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (interceptorOne) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 type interceptorTwo struct{}
 
-func (interceptorTwo) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (interceptorTwo) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	if w.Header().Get("pizza") != "diavola" {
 		w.WriteError(safehttp.StatusInternalServerError)
 	}
@@ -563,7 +563,7 @@ func (interceptorTwo) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingReq
 	return safehttp.NotWritten()
 }
 
-func (interceptorTwo) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (interceptorTwo) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	if w.Header().Get("Commit3") != "c" {
 		w.WriteError(safehttp.StatusInternalServerError)
 	}
@@ -571,13 +571,13 @@ func (interceptorTwo) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingReq
 	return safehttp.NotWritten()
 }
 
-func (interceptorTwo) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (interceptorTwo) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
 type interceptorThree struct{}
 
-func (interceptorThree) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (interceptorThree) Before(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, cfg safehttp.InterceptorConfig) safehttp.Result {
 	if w.Header().Get("spaghetti") != "bolognese" {
 		w.WriteError(safehttp.StatusInternalServerError)
 	}
@@ -585,7 +585,7 @@ func (interceptorThree) Before(w *safehttp.ResponseWriter, r *safehttp.IncomingR
 	return safehttp.NotWritten()
 }
 
-func (interceptorThree) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (interceptorThree) Commit(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	if w.Header().Get("Dessert") != "tiramisu" {
 		w.WriteError(safehttp.StatusInternalServerError)
 	}
@@ -593,7 +593,7 @@ func (interceptorThree) Commit(w *safehttp.ResponseWriter, r *safehttp.IncomingR
 	return safehttp.NotWritten()
 }
 
-func (interceptorThree) OnError(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
+func (interceptorThree) OnError(w safehttp.ResponseWriter, r *safehttp.IncomingRequest, resp safehttp.Response, cfg safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.NotWritten()
 }
 
@@ -603,7 +603,7 @@ func TestMuxDeterministicInterceptorOrder(t *testing.T) {
 	mb.Intercept(interceptorTwo{})
 	mb.Intercept(interceptorThree{})
 
-	registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+	registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 	})
 	mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
@@ -638,7 +638,7 @@ func TestMuxDeterministicInterceptorOrder(t *testing.T) {
 
 func TestMuxHandlerReturnsNotWritten(t *testing.T) {
 	mb := &safehttp.ServeMuxConfig{}
-	h := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+	h := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return safehttp.NotWritten()
 	})
 	mb.Handle("/bar", safehttp.MethodGet, h)
@@ -663,15 +663,15 @@ func TestMuxHandlerReturnsNotWritten(t *testing.T) {
 
 type onErrorWriteInterceptor struct{}
 
-func (onErrorWriteInterceptor) Before(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
+func (onErrorWriteInterceptor) Before(w safehttp.ResponseWriter, _ *safehttp.IncomingRequest, _ safehttp.InterceptorConfig) safehttp.Result {
 	return w.WriteError(safehttp.StatusBadRequest)
 }
 
-func (onErrorWriteInterceptor) Commit(_ *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, _ safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (onErrorWriteInterceptor) Commit(_ safehttp.ResponseWriter, _ *safehttp.IncomingRequest, _ safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	return safehttp.Result{}
 }
 
-func (onErrorWriteInterceptor) OnError(w *safehttp.ResponseWriter, _ *safehttp.IncomingRequest, _ safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
+func (onErrorWriteInterceptor) OnError(w safehttp.ResponseWriter, _ *safehttp.IncomingRequest, _ safehttp.Response, _ safehttp.InterceptorConfig) safehttp.Result {
 	w.Header().Set("header", "bad")
 	return w.WriteError(safehttp.StatusInsufficientStorage)
 }
@@ -685,7 +685,7 @@ func TestMuxInterceptorWriteInOnError(t *testing.T) {
 	mb := &safehttp.ServeMuxConfig{}
 	mb.Intercept(onErrorWriteInterceptor{})
 
-	registeredHandler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+	registeredHandler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 	})
 	mb.Handle("/bar", safehttp.MethodGet, registeredHandler)
diff --git a/safehttp/plugins/hostcheck/hostcheck_test.go b/safehttp/plugins/hostcheck/hostcheck_test.go
index 5fb968f..9b36a3c 100644
--- a/safehttp/plugins/hostcheck/hostcheck_test.go
+++ b/safehttp/plugins/hostcheck/hostcheck_test.go
@@ -49,7 +49,7 @@ func TestInterceptor(t *testing.T) {
 			mb := &safehttp.ServeMuxConfig{}
 			mb.Intercept(hostcheck.New("foo.com"))
 
-			h := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			h := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 			})
 			mb.Handle("/", safehttp.MethodGet, h)
diff --git a/safehttp/plugins/xsrf/html/xsrf_test.go b/safehttp/plugins/xsrf/html/xsrf_test.go
index 08a5169..e50238a 100644
--- a/safehttp/plugins/xsrf/html/xsrf_test.go
+++ b/safehttp/plugins/xsrf/html/xsrf_test.go
@@ -245,12 +245,12 @@ func TestMissingCookieInGetRequest(t *testing.T) {
 func TestMissingCookieInPostRequest(t *testing.T) {
 	tests := []struct {
 		name       string
-		stage      func(it *Interceptor, rw *safehttp.ResponseWriter, req *safehttp.IncomingRequest)
+		stage      func(it *Interceptor, rw safehttp.ResponseWriter, req *safehttp.IncomingRequest)
 		wantStatus safehttp.StatusCode
 	}{
 		{
 			name: "In Before stage",
-			stage: func(it *Interceptor, rw *safehttp.ResponseWriter, req *safehttp.IncomingRequest) {
+			stage: func(it *Interceptor, rw safehttp.ResponseWriter, req *safehttp.IncomingRequest) {
 
 				it.Before(rw, req, nil)
 			},
@@ -258,7 +258,7 @@ func TestMissingCookieInPostRequest(t *testing.T) {
 		},
 		{
 			name: "In Commit stage",
-			stage: func(it *Interceptor, rw *safehttp.ResponseWriter, req *safehttp.IncomingRequest) {
+			stage: func(it *Interceptor, rw safehttp.ResponseWriter, req *safehttp.IncomingRequest) {
 				it.Commit(rw, req, nil, nil)
 			},
 			wantStatus: safehttp.StatusInternalServerError,
diff --git a/safehttp/response_writer_test.go b/safehttp/response_writer_test.go
index 7c781a5..76ea225 100644
--- a/safehttp/response_writer_test.go
+++ b/safehttp/response_writer_test.go
@@ -58,32 +58,32 @@ func TestResponseWriterSetInvalidCookie(t *testing.T) {
 func TestResponseWriterWriteTwicePanic(t *testing.T) {
 	tests := []struct {
 		name  string
-		write func(w *safehttp.ResponseWriter)
+		write func(w safehttp.ResponseWriter)
 	}{
 		{
 			name: "Call Write twice",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
 				w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
 			},
 		},
 		{
 			name: "Call NoContent twice",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.NoContent()
 				w.NoContent()
 			},
 		},
 		{
 			name: "Call WriteError twice",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.WriteError(safehttp.StatusInternalServerError)
 				w.WriteError(safehttp.StatusInternalServerError)
 			},
 		},
 		{
 			name: "Call Redirect twice",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				ir := safehttptest.NewRequest(safehttp.MethodGet, "/", nil)
 				w.Redirect(ir, "/asdf", safehttp.StatusMovedPermanently)
 				w.Redirect(ir, "/asdf", safehttp.StatusMovedPermanently)
@@ -108,23 +108,23 @@ func TestResponseWriterWriteTwicePanic(t *testing.T) {
 func TestResponseWriterUnsafeResponse(t *testing.T) {
 	tests := []struct {
 		name  string
-		write func(w *safehttp.ResponseWriter)
+		write func(w safehttp.ResponseWriter)
 	}{
 		{
 			name: "Unsafe HTML Response",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.Write("<h1>Hello World!</h1>")
 			},
 		},
 		{
 			name: "Invalid JSON Response",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				safehttp.WriteJSON(w, math.Inf(1))
 			},
 		},
 		{
 			name: "Unsafe Template Response",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				safehttp.ExecuteTemplate(w, template.
 					Must(template.New("name").
 						Parse("<h1>{{ . }}</h1>")), "This is an actual heading, though.")
@@ -148,19 +148,19 @@ func TestResponseWriterUnsafeResponse(t *testing.T) {
 func TestResponseWriterStatusCode(t *testing.T) {
 	tests := []struct {
 		name       string
-		write      func(w *safehttp.ResponseWriter)
+		write      func(w safehttp.ResponseWriter)
 		wantStatus safehttp.StatusCode
 	}{
 		{
 			name: "Default status code",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
 			},
 			wantStatus: safehttp.StatusOK,
 		},
 		{
 			name: "Custom status code",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.SetCode(safehttp.StatusPartialContent)
 				w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
 			},
@@ -168,7 +168,7 @@ func TestResponseWriterStatusCode(t *testing.T) {
 		},
 		{
 			name: "Status code set after Write",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
 				w.SetCode(safehttp.StatusPartialContent)
 			},
@@ -176,7 +176,7 @@ func TestResponseWriterStatusCode(t *testing.T) {
 		},
 		{
 			name: "SetCode then NoContent",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.SetCode(safehttp.StatusPartialContent)
 				w.NoContent()
 			},
@@ -184,7 +184,7 @@ func TestResponseWriterStatusCode(t *testing.T) {
 		},
 		{
 			name: "SetCode then Redirect",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.SetCode(safehttp.StatusPartialContent)
 				w.Redirect(safehttptest.NewRequest(safehttp.MethodGet, "/", nil), "", safehttp.StatusTemporaryRedirect)
 			},
@@ -192,7 +192,7 @@ func TestResponseWriterStatusCode(t *testing.T) {
 		},
 		{
 			name: "SetCode then WriteError",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.SetCode(safehttp.StatusPartialContent)
 				w.WriteError(safehttp.StatusInsufficientStorage)
 			},
@@ -214,18 +214,18 @@ func TestResponseWriterStatusCode(t *testing.T) {
 func TestResponseWriterInvalidStatusCode(t *testing.T) {
 	tests := []struct {
 		name  string
-		write func(w *safehttp.ResponseWriter)
+		write func(w safehttp.ResponseWriter)
 	}{
 		{
 			name: "Status code smaller than 100",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.SetCode(50)
 				w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
 			},
 		},
 		{
 			name: "Status code bigger than 599",
-			write: func(w *safehttp.ResponseWriter) {
+			write: func(w safehttp.ResponseWriter) {
 				w.SetCode(1000)
 				w.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
 			},
diff --git a/safehttp/safehttptest/recorder.go b/safehttp/safehttptest/recorder.go
index 06bf53b..8cf2fb1 100644
--- a/safehttp/safehttptest/recorder.go
+++ b/safehttp/safehttptest/recorder.go
@@ -26,7 +26,7 @@ import (
 // mutations for later inspection in tests. The safehttp.ResponseWriter
 // should be passed as part of the handler function in tests.
 type ResponseRecorder struct {
-	*safehttp.ResponseWriter
+	safehttp.ResponseWriter
 	rw *TestResponseWriter
 	b  *strings.Builder
 }
diff --git a/tests/integration/csp/csp_test.go b/tests/integration/csp/csp_test.go
index fbe409a..0f3dc7e 100644
--- a/tests/integration/csp/csp_test.go
+++ b/tests/integration/csp/csp_test.go
@@ -33,7 +33,7 @@ func TestServeMuxInstallCSP(t *testing.T) {
 
 	var nonce string
 	var err error
-	handler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+	handler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		fns := map[string]interface{}{
 			"CSPNonce": func() string { return "WrongNonce" },
 		}
diff --git a/tests/integration/header/header_test.go b/tests/integration/header/header_test.go
index 68f16ad..e913ea5 100644
--- a/tests/integration/header/header_test.go
+++ b/tests/integration/header/header_test.go
@@ -30,7 +30,7 @@ import (
 
 func TestAccessIncomingHeaders(t *testing.T) {
 	mb := &safehttp.ServeMuxConfig{}
-	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw *safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
+	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
 		if got, want := ir.Header.Get("A"), "B"; got != want {
 			t.Errorf(`ir.Header.Get("A") got: %v want: %v`, got, want)
 		}
@@ -54,7 +54,7 @@ func TestAccessIncomingHeaders(t *testing.T) {
 
 func TestChangingResponseHeaders(t *testing.T) {
 	mb := &safehttp.ServeMuxConfig{}
-	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw *safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
+	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
 		rw.Header().Set("pIZZA", "Pasta")
 		return rw.Write(safehtml.HTMLEscaped("hello"))
 	}))
diff --git a/tests/integration/hsts/hsts_test.go b/tests/integration/hsts/hsts_test.go
index 9dd46b3..581eea7 100644
--- a/tests/integration/hsts/hsts_test.go
+++ b/tests/integration/hsts/hsts_test.go
@@ -32,7 +32,7 @@ func TestHSTSServeMuxInstall(t *testing.T) {
 	mb := &safehttp.ServeMuxConfig{}
 
 	mb.Intercept(hsts.Default())
-	handler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+	handler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 	})
 	mb.Handle("/asdf", safehttp.MethodGet, handler)
diff --git a/tests/integration/mux/mux_test.go b/tests/integration/mux/mux_test.go
index 13eed03..da072f3 100644
--- a/tests/integration/mux/mux_test.go
+++ b/tests/integration/mux/mux_test.go
@@ -37,7 +37,7 @@ func TestMuxDefaultDispatcher(t *testing.T) {
 	}{
 		{
 			name: "Safe HTML Response",
-			handler: safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			handler: safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 			}),
 			wantHeaders: map[string][]string{
@@ -47,7 +47,7 @@ func TestMuxDefaultDispatcher(t *testing.T) {
 		},
 		{
 			name: "Safe HTML Template Response",
-			handler: safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			handler: safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return safehttp.ExecuteTemplate(w, safetemplate.
 					Must(safetemplate.New("name").
 						Parse("<h1>{{ . }}</h1>")), "This is an actual heading, though.")
@@ -59,7 +59,7 @@ func TestMuxDefaultDispatcher(t *testing.T) {
 		},
 		{
 			name: "Valid JSON Response",
-			handler: safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			handler: safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				data := struct {
 					Field string `json:"field"`
 				}{Field: "myField"}
@@ -103,13 +103,13 @@ func TestMuxDefaultDispatcherUnsafeResponses(t *testing.T) {
 	}{
 		{
 			name: "Unsafe HTML Response",
-			handler: safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			handler: safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return w.Write("<h1>Hello World!</h1>")
 			}),
 		},
 		{
 			name: "Unsafe Template Response",
-			handler: safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			handler: safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return safehttp.ExecuteTemplate(w, template.
 					Must(template.New("name").
 						Parse("<h1>{{ . }}</h1>")), "This is an actual heading, though.")
@@ -117,7 +117,7 @@ func TestMuxDefaultDispatcherUnsafeResponses(t *testing.T) {
 		},
 		{
 			name: "Invalid JSON Response",
-			handler: safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+			handler: safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 				return safehttp.WriteJSON(w, math.Inf(1))
 			}),
 		},
diff --git a/tests/integration/safehtml/safehtml_test.go b/tests/integration/safehtml/safehtml_test.go
index 1a0f79b..0889fa3 100644
--- a/tests/integration/safehtml/safehtml_test.go
+++ b/tests/integration/safehtml/safehtml_test.go
@@ -28,7 +28,7 @@ import (
 
 func TestHandleRequestWrite(t *testing.T) {
 	mb := &safehttp.ServeMuxConfig{}
-	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw *safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
+	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
 		return rw.Write(safehtml.HTMLEscaped("<h1>Escaped, so not really a heading</h1>"))
 	}))
 
@@ -48,7 +48,7 @@ func TestHandleRequestWrite(t *testing.T) {
 
 func TestHandleRequestWriteTemplate(t *testing.T) {
 	mb := &safehttp.ServeMuxConfig{}
-	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw *safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
+	mb.Handle("/", safehttp.MethodGet, safehttp.HandlerFunc(func(rw safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
 		return safehttp.ExecuteTemplate(rw, template.Must(template.New("name").Parse("<h1>{{ . }}</h1>")), "This is an actual heading, though.")
 	}))
 
diff --git a/tests/integration/staticheaders/staticheaders_test.go b/tests/integration/staticheaders/staticheaders_test.go
index c64950c..c83f4df 100644
--- a/tests/integration/staticheaders/staticheaders_test.go
+++ b/tests/integration/staticheaders/staticheaders_test.go
@@ -32,7 +32,7 @@ func TestServeMuxInstallStaticHeaders(t *testing.T) {
 	mb := &safehttp.ServeMuxConfig{}
 
 	mb.Intercept(staticheaders.Interceptor{})
-	handler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+	handler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		return w.Write(safehtml.HTMLEscaped("<h1>Hello World!</h1>"))
 	})
 	mb.Handle("/asdf", safehttp.MethodGet, handler)
diff --git a/tests/integration/xsrf/xsrf_test.go b/tests/integration/xsrf/xsrf_test.go
index 15517fe..d7a7892 100644
--- a/tests/integration/xsrf/xsrf_test.go
+++ b/tests/integration/xsrf/xsrf_test.go
@@ -30,7 +30,7 @@ func TestServeMuxInstallXSRF(t *testing.T) {
 	it := xsrfhtml.Interceptor{SecretAppKey: "testSecretAppKey"}
 	mb.Intercept(&it)
 
-	handler := safehttp.HandlerFunc(func(w *safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
+	handler := safehttp.HandlerFunc(func(w safehttp.ResponseWriter, r *safehttp.IncomingRequest) safehttp.Result {
 		fns := map[string]interface{}{
 			"XSRFToken": func() string { return "WrongToken" },
 		}