在Http中间件中使用http.Client会导致原始的HttpRequest.Body处于关闭状态。

huangapple go评论108阅读模式
英文:

Using http.Client in Http Middleware causes the original HttpRequest.Body to be in a closed state

问题

当我使用GoLand工具进行调试时,在使用HttpClient请求中间件中的地址后,原始的r *http.Request.Body的状态变为关闭,导致在处理程序中解析时出现异常:错误:http:无效的关闭Body上的读取。

中间件:

func (m *AuthorizeHandlerMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		token := r.Header.Get("Authorization")
		if token == "" {
			res := types.Base{
				Code:    401,
				Message: "error",
			}
			logc.Error(r.Context(), "token is empty")
			httpx.OkJsonCtx(r.Context(), w, res)
			return
		}
		hReq, err := http.NewRequest("GET", "http://localhost:801/admin/member/info", nil)
		if err != nil {
			logc.Error(r.Context(), err)
			return
		}
		c := http.Client{}
		_, _ = c.Do(hReq)  //执行此步骤后,r.Body的Close变为True。
		next(w, r)
	}
}

处理程序:

func MyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var req types.MyReq
		if err := httpx.Parse(r, &req); err != nil {
            // 错误:http:无效的关闭Body上的读取。
			httpx.ErrorCtx(r.Context(), w, err)  
			return
		}

		l := logic.NewAnaliysisPnrLogic(r.Context(), svcCtx)
		resp, err := l.AnaliysisPnr(&req)
		if err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
		} else {
			httpx.OkJsonCtx(r.Context(), w, resp)
		}
	}
}

请帮我检查问题的原因。谢谢。

英文:

When I use the GoLand tool for debugging,After using HttpClient to request an address in Middleware, the status of the original r *http.Request.Body becomes closed, resulting in an exception during parsing in the Handler: error: http: invalid Read on closed Body.

Middleware:

func (m *AuthorizeHandlerMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		token := r.Header.Get("Authorization")
		if token == "" {
			res := types.Base{
				Code:    401,
				Message: "error",
			}
			logc.Error(r.Context(), "token is empty")
			httpx.OkJsonCtx(r.Context(), w, res)
			return
		}
		hReq, err := http.NewRequest("GET", "http://localhost:801/admin/member/info", nil)
		if err != nil {
			logc.Error(r.Context(), err)
			return
		}
		c := http.Client{}
		_, _ = c.Do(hReq)  //After executing this step, r.Body's Close becomes True.
		next(w, r)
	}
}

Handler

func MyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var req types.MyReq
		if err := httpx.Parse(r, &req); err != nil {
            // error : http: invalid Read on closed Body.
			httpx.ErrorCtx(r.Context(), w, err)  
			return
		}

		l := logic.NewAnaliysisPnrLogic(r.Context(), svcCtx)
		resp, err := l.AnaliysisPnr(&req)
		if err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
		} else {
			httpx.OkJsonCtx(r.Context(), w, resp)
		}
	}
}

Please help me check the reason for the problem. Thank you.

答案1

得分: 1

原因是Go-zero中HTTP服务器的超时时间默认为3秒,在调试模式下会导致超时。

英文:

The reason is that the HTTP server's Timeout in Go-zero defaults to 3 seconds, causing a timeout in Debug mode.

huangapple
  • 本文由 发表于 2023年8月8日 22:58:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76860790.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定