Первое: никаких оснований для использования отражения здесь. Не имеет никакого отношения к вашей проблеме, но она не нужна.
В вашей настройке контекста вы используете глобальный var для ctx.
HTTP-сервер go является параллельным, поэтому то, что вы делаете, состоит в том, что несколько goroutines обновляют один и тот же глобальный var, а затем передают это обработчику.
Это приводит к тому, что ваши обработчики иногда получают один экземпляр ResponseWriter и пытаются записать на него. Это может привести к ошибке ab
, так как вы пишете недействительные ответы HTTP, смешивая то, что отправляется на провод.
Избавьтесь от глобальной переменной CTX и использовать локальный один, как показано ниже:
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\n", ctx)
fmt.Fprint(rw, "Hello World.")
}
Рассмотрим размещение соответствующий код здесь. Здесь нам нужно [MCVE] (http://stackoverflow.com/help/mcve). –
@ J.Chomel извините за это, но код слишком длинный, stackoverflow не позволяет публиковать, если вопрос содержит большую часть кода. – HeadwindFly
Код слишком длинный: вот почему я советую вам создать MVCE. Но если у вас его нет, кто-то может занять необходимое время, чтобы помочь вам, кто знает. –