Go HTTP Server无法发送100 Continue响应,返回200的问题求助
解决Go HTTP Server返回100-continue后自动返回200的问题
问题原因
你遇到的核心问题是:Go的HTTP服务器在handler返回时,若未发送最终状态码(如200、401等),会自动补一个200 OK响应。http.StatusContinue属于中间响应,不被视为最终状态,所以即使你发送了100-continue,handler返回后服务器仍会自动发送200。
解决方案
要避免服务器自动发送200,需按以下方式处理:
方案1:发送100-continue后保持handler运行或发送最终状态码
发送100-continue后,调用Flush()确保响应头立即送达客户端,之后不要让handler立即返回——要么等待客户端的认证请求,要么明确发送一个最终状态码(比如401 Unauthorized提示客户端需要认证)。
修改后的服务端代码示例:
func Handle(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Expect") == "100-continue" { // 发送100-continue响应头 w.WriteHeader(http.StatusContinue) // 强制刷新响应,确保客户端立即收到100信号 if flusher, ok := w.(http.Flusher); ok { flusher.Flush() } // 模拟等待客户端发送认证请求的逻辑 time.Sleep(3 * time.Second) // 发送401提示客户端需要提供认证凭据 w.WriteHeader(http.StatusUnauthorized) return } // 处理已认证的请求 w.WriteHeader(http.StatusOK) w.Write([]byte("Authenticated")) }
方案2:使用Hijack直接控制连接(适合自定义HTTP流程)
如果需要完全控制连接,绕过Go HTTP服务器的自动响应逻辑,可以使用http.Hijacker获取底层TCP连接,手动处理后续的请求和响应:
func Handle(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Expect") == "100-continue" { // 发送100-continue响应 w.WriteHeader(http.StatusContinue) if flusher, ok := w.(http.Flusher); ok { flusher.Flush() } // Hijack连接,手动处理后续数据 hijacker, ok := w.(http.Hijacker) if !ok { http.Error(w, "Hijack not supported", http.StatusInternalServerError) return } conn, buf, err := hijacker.Hijack() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer conn.Close() // 读取客户端发送的认证请求数据(示例:读取请求行) line, err := buf.ReadString('\n') if err != nil { return } fmt.Println("Received auth request line:", line) // 发送响应 buf.WriteString("HTTP/1.1 200 OK\r\nContent-Length: 13\r\n\r\nAuthenticated") buf.Flush() return } }
注意:使用Hijack需要手动处理HTTP协议的细节,仅适合对HTTP流程有明确自定义需求的场景。
内容的提问来源于stack exchange,提问作者kwaul
相关产品推荐
相关产品推荐

