Skip to content

Commit 94d2054

Browse files
committed
Ensure responses are context.ResponseWriters (go-gitea#19843)
Backport go-gitea#19843 In order for web.Wrap to be able to detect if a response has been written we need to wrap any non-context.ResponseWriters as a such. Otherwise responses will be incorrectly detected as non-written to and handlers can double run. In the case of GZip this handler will change the response to a non-context.RW and this failure to correctly detect response writing causes fallthrough and a NPE. Fix go-gitea#19839 Signed-off-by: Andrew Thornton <art27@cantab.net>
1 parent 0e9499a commit 94d2054

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

modules/web/route.go

+24-18
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,17 @@ func Wrap(handlers ...interface{}) http.HandlerFunc {
4242
handler := handlers[i]
4343
switch t := handler.(type) {
4444
case http.HandlerFunc:
45+
if _, ok := resp.(context.ResponseWriter); !ok {
46+
resp = context.NewResponse(resp)
47+
}
4548
t(resp, req)
4649
if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 {
4750
return
4851
}
4952
case func(http.ResponseWriter, *http.Request):
53+
if _, ok := resp.(context.ResponseWriter); !ok {
54+
resp = context.NewResponse(resp)
55+
}
5056
t(resp, req)
5157
if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 {
5258
return
@@ -88,7 +94,7 @@ func Wrap(handlers ...interface{}) http.HandlerFunc {
8894
return
8995
}
9096
case func(http.Handler) http.Handler:
91-
var next = http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})
97+
next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})
9298
if len(handlers) > i+1 {
9399
next = Wrap(handlers[i+1:]...)
94100
}
@@ -148,15 +154,15 @@ func MiddleAPI(f func(ctx *context.APIContext)) func(netx http.Handler) http.Han
148154

149155
// Bind binding an obj to a handler
150156
func Bind(obj interface{}) http.HandlerFunc {
151-
var tp = reflect.TypeOf(obj)
157+
tp := reflect.TypeOf(obj)
152158
if tp.Kind() == reflect.Ptr {
153159
tp = tp.Elem()
154160
}
155161
if tp.Kind() != reflect.Struct {
156162
panic("Only structs are allowed to bind")
157163
}
158164
return Wrap(func(ctx *context.Context) {
159-
var theObj = reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly
165+
theObj := reflect.New(tp).Interface() // create a new form obj for every request but not use obj directly
160166
binding.Bind(ctx.Req, theObj)
161167
SetForm(ctx, theObj)
162168
middleware.AssignForm(theObj, ctx.Data)
@@ -214,8 +220,8 @@ func (r *Route) Use(middlewares ...interface{}) {
214220

215221
// Group mounts a sub-Router along a `pattern` string.
216222
func (r *Route) Group(pattern string, fn func(), middlewares ...interface{}) {
217-
var previousGroupPrefix = r.curGroupPrefix
218-
var previousMiddlewares = r.curMiddlewares
223+
previousGroupPrefix := r.curGroupPrefix
224+
previousMiddlewares := r.curMiddlewares
219225
r.curGroupPrefix += pattern
220226
r.curMiddlewares = append(r.curMiddlewares, middlewares...)
221227

@@ -238,88 +244,88 @@ func (r *Route) getPattern(pattern string) string {
238244

239245
// Mount attaches another Route along ./pattern/*
240246
func (r *Route) Mount(pattern string, subR *Route) {
241-
var middlewares = make([]interface{}, len(r.curMiddlewares))
247+
middlewares := make([]interface{}, len(r.curMiddlewares))
242248
copy(middlewares, r.curMiddlewares)
243249
subR.Use(middlewares...)
244250
r.R.Mount(r.getPattern(pattern), subR.R)
245251
}
246252

247253
// Any delegate requests for all methods
248254
func (r *Route) Any(pattern string, h ...interface{}) {
249-
var middlewares = r.getMiddlewares(h)
255+
middlewares := r.getMiddlewares(h)
250256
r.R.HandleFunc(r.getPattern(pattern), Wrap(middlewares...))
251257
}
252258

253259
// Route delegate special methods
254260
func (r *Route) Route(pattern, methods string, h ...interface{}) {
255261
p := r.getPattern(pattern)
256262
ms := strings.Split(methods, ",")
257-
var middlewares = r.getMiddlewares(h)
263+
middlewares := r.getMiddlewares(h)
258264
for _, method := range ms {
259265
r.R.MethodFunc(strings.TrimSpace(method), p, Wrap(middlewares...))
260266
}
261267
}
262268

263269
// Delete delegate delete method
264270
func (r *Route) Delete(pattern string, h ...interface{}) {
265-
var middlewares = r.getMiddlewares(h)
271+
middlewares := r.getMiddlewares(h)
266272
r.R.Delete(r.getPattern(pattern), Wrap(middlewares...))
267273
}
268274

269275
func (r *Route) getMiddlewares(h []interface{}) []interface{} {
270-
var middlewares = make([]interface{}, len(r.curMiddlewares), len(r.curMiddlewares)+len(h))
276+
middlewares := make([]interface{}, len(r.curMiddlewares), len(r.curMiddlewares)+len(h))
271277
copy(middlewares, r.curMiddlewares)
272278
middlewares = append(middlewares, h...)
273279
return middlewares
274280
}
275281

276282
// Get delegate get method
277283
func (r *Route) Get(pattern string, h ...interface{}) {
278-
var middlewares = r.getMiddlewares(h)
284+
middlewares := r.getMiddlewares(h)
279285
r.R.Get(r.getPattern(pattern), Wrap(middlewares...))
280286
}
281287

282288
// Options delegate options method
283289
func (r *Route) Options(pattern string, h ...interface{}) {
284-
var middlewares = r.getMiddlewares(h)
290+
middlewares := r.getMiddlewares(h)
285291
r.R.Options(r.getPattern(pattern), Wrap(middlewares...))
286292
}
287293

288294
// GetOptions delegate get and options method
289295
func (r *Route) GetOptions(pattern string, h ...interface{}) {
290-
var middlewares = r.getMiddlewares(h)
296+
middlewares := r.getMiddlewares(h)
291297
r.R.Get(r.getPattern(pattern), Wrap(middlewares...))
292298
r.R.Options(r.getPattern(pattern), Wrap(middlewares...))
293299
}
294300

295301
// PostOptions delegate post and options method
296302
func (r *Route) PostOptions(pattern string, h ...interface{}) {
297-
var middlewares = r.getMiddlewares(h)
303+
middlewares := r.getMiddlewares(h)
298304
r.R.Post(r.getPattern(pattern), Wrap(middlewares...))
299305
r.R.Options(r.getPattern(pattern), Wrap(middlewares...))
300306
}
301307

302308
// Head delegate head method
303309
func (r *Route) Head(pattern string, h ...interface{}) {
304-
var middlewares = r.getMiddlewares(h)
310+
middlewares := r.getMiddlewares(h)
305311
r.R.Head(r.getPattern(pattern), Wrap(middlewares...))
306312
}
307313

308314
// Post delegate post method
309315
func (r *Route) Post(pattern string, h ...interface{}) {
310-
var middlewares = r.getMiddlewares(h)
316+
middlewares := r.getMiddlewares(h)
311317
r.R.Post(r.getPattern(pattern), Wrap(middlewares...))
312318
}
313319

314320
// Put delegate put method
315321
func (r *Route) Put(pattern string, h ...interface{}) {
316-
var middlewares = r.getMiddlewares(h)
322+
middlewares := r.getMiddlewares(h)
317323
r.R.Put(r.getPattern(pattern), Wrap(middlewares...))
318324
}
319325

320326
// Patch delegate patch method
321327
func (r *Route) Patch(pattern string, h ...interface{}) {
322-
var middlewares = r.getMiddlewares(h)
328+
middlewares := r.getMiddlewares(h)
323329
r.R.Patch(r.getPattern(pattern), Wrap(middlewares...))
324330
}
325331

0 commit comments

Comments
 (0)