First: no reason to use reflect here. Has nothing to do with your problem, but it isn't needed.
In your setup of Context, you are using a global var for ctx.
go's http server is concurrent, so what you are doing is having multiple goroutines update the same global var and then pass that to the handler.
This causes your handlers to sometimes get the same ResponseWriter instance and attempt to write to it. This can cause ab
to fail since you are writing invalid http responses by mixing what gets sent on the wire.
Get rid of global ctx variable and use a local one, like below:
func handler(rw http.ResponseWriter, r *http.Request) {
ctx := &Context{ // notice that this is a local var now
names:make([]string, 0),
rw:rw,
r:r,
}
for i := 0; i < len(middlewareInfos); i++ {
middleware := reflect.New(middlewareInfos[i].t)
setContextMethod := middleware.MethodByName("SetContext")
setContextMethod.Call([]reflect.Value{reflect.ValueOf(ctx)})
handleMethod := middleware.MethodByName("Handle")
values := handleMethod.Call([]reflect.Value{})
if value, ok := values[0].Interface().(bool); !ok || !value {
return
}
}
// fmt.Printf("%v
", ctx)
fmt.Fprint(rw, "Hello World.")
}