Go 多余的写头和无响应

Go 多余的写头和无响应,go,gorilla,go-http,Go,Gorilla,Go Http,我正在编写一个向WebSocket网关发送请求的HTTP API。我使用的是go1.14.7和gorilla/muxv1.8.0。代码将使用GOOS=linuxGOARCH=armGOARM=7进行交叉编译 我的问题如下: respondBadRequest()始终记录此操作,即使我从未使用WriteHeader: http:多余的response.WriteHeader调用来自main。(*HttpHandler)。respondBadRequest 即使调用了respondBadRe

我正在编写一个向WebSocket网关发送请求的HTTP API。我使用的是
go1.14.7
gorilla/mux
v1.8.0
。代码将使用
GOOS=linux
GOARCH=arm
GOARM=7
进行交叉编译

我的问题如下:

  • respondBadRequest()
    始终记录此操作,即使我从未使用
    WriteHeader
    • http:多余的response.WriteHeader调用来自main。(*HttpHandler)。respondBadRequest
  • 即使调用了
    respondBadRequest()
    ,API响应始终是
    200OK
  • API响应总是有一个空的主体
我是新来的。下面是我的代码结构

类型HttpHandler结构{
网关
}
func(h*HttpHandler)respondSuccess(w http.ResponseWriter,文本字符串){
w、 写入([]字节(文本))
}
func(h*HttpHandler)respondBadRequest(w http.ResponseWriter,文本字符串){
http.Error(w,text,http.StatusBadRequest)
}
func(h*HttpHandler)响应错误(w http.ResponseWriter,文本字符串){
http.Error(w,text,http.StatusInternalServerError)
}
func(h*HttpHandler)OnFoobar(w http.ResponseWriter,r*http.Request){
f:=func(成功布尔,e错误){
如果e!=nil{
h、 响应错误(w,e.Error())
}否则,如果成功的话{
h、 响应成功(w,“Foobar接受”)
}否则{
h、 respondBadRequest(w,“未知Foobar”)
}
}
//...
e:=h.gateway.Foobar(f)
如果e!=nil{
log.Println(e)
}
}
//...
httpHandler:=&httpHandler{
网关:网关,
}
r:=mux.NewRouter()
r、 HandleFunc(“/foobar”,httpHandler.OnFoobar)
http.listendServe(“:8000”,r)

正如@mkopriva指出的,
f
显然是在
OnFoobar
已经完成并编写了一个隐式空响应之后调用的。使用
sync.WaitGroup
修复His:

foobar上的func(h*HttpHandler)(w http.ResponseWriter,r*http.Request){ wg:=新建(sync.WaitGroup) 工作组.添加(1) f:=func(成功布尔,e错误){ 如果e!=nil{ h、 响应错误(w,e.Error()) }否则,如果成功的话{ h、 响应成功(w,“Foobar接受”) }否则{ h、 respondBadRequest(w,“未知Foobar”) } wg.Done() } //... e:=h.gateway.Foobar(f) 如果e!=nil{ log.Println(e) } wg.Wait() }
如果编写响应的任何部分,则已调用
WriteHeader
。在已经编写响应之后,您不能发送其他标头。您不是直接调用
WriteHeader
,而是在多个地方间接调用它;如果您调用
Write
且尚未调用
WriteHeader
Write
将调用
WriteHeader(200)
(如文档中所述)
http.Error
还调用
WriteHeader
。如果您希望以错误进行响应,则必须在调用
Write
发送任何正文内容之前执行此操作(在HTTP响应中,状态和标题必须位于响应正文之前)。
f
看起来像一个回调,所以我想
Foobar
是异步的吗?它是不是在一个社交场合做它的工作?如果处理程序
OnFoobar
没有等待
Foobar
完成,当它退出时,如果
w
尚未写入,Go的serve mux将默认写入200ok,然后,当
Foobar
完成并调用回调时,您会得到您得到的错误。@Steffen在这种情况下,使用
sync.WaitGroup
@Steffen这样做应该可以,我相信:在OnFoobar返回后调用f并不明显,因为Go中的最佳实践是提供同步api。