-2

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

我的问题如下:

  • respondBadRequest()即使我从不使用,也总是记录WriteHeader
    • http: superfluous response.WriteHeader call from main.(*HttpHandler).respondBadRequest
  • API响应总是200 OK即使respondBadRequest()被调用
  • API 响应总是有一个空的正文

我对 Go 完全陌生。下面是我的代码结构。

type HttpHandler struct {
  gateway Gateway
}

func (h *HttpHandler) respondSuccess(w http.ResponseWriter, text string) {
  w.Write([]byte(text))
}

func (h *HttpHandler) respondBadRequest(w http.ResponseWriter, text string) {
  http.Error(w, text, http.StatusBadRequest)
}

func (h *HttpHandler) respondError(w http.ResponseWriter, text string) {
  http.Error(w, text, http.StatusInternalServerError)
}

func (h *HttpHandler) OnFoobar(w http.ResponseWriter, r *http.Request) {
  f := func(success bool, e error) {
    if e != nil {
      h.respondError(w, e.Error())
    } else if success {
      h.respondSuccess(w, "Foobar Accepted")
    } else {
      h.respondBadRequest(w, "Unknown Foobar")
    }
  }
  //...
  e := h.gateway.Foobar(f)
  if e != nil {
    log.Println(e)
  }
}

//...

httpHandler := &HttpHandler{
  gateway: gateway,
}

r := mux.NewRouter()

r.HandleFunc("/foobar", httpHandler.OnFoobar)

http.ListenAndServe(":8000", r)
4

1 回答 1

1

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

func (h *HttpHandler) OnFoobar(w http.ResponseWriter, r *http.Request) {
  wg := new(sync.WaitGroup)
  wg.Add(1)
  f := func(success bool, e error) {
    if e != nil {
      h.respondError(w, e.Error())
    } else if success {
      h.respondSuccess(w, "Foobar Accepted")
    } else {
      h.respondBadRequest(w, "Unknown Foobar")
    }
    wg.Done()
  }
  //...
  e := h.gateway.Foobar(f)
  if e != nil {
    log.Println(e)
  }
  wg.Wait()
}
于 2021-03-16T17:53:41.737 回答