为了账号安全,请及时绑定邮箱和手机立即绑定

如果请求在 http.Server 中超时,为什么在 Firefox 中会无限期地重复?

如果请求在 http.Server 中超时,为什么在 Firefox 中会无限期地重复?

Go
守着星空守着你 2023-07-31 17:31:05
我正在 golang 中设置一个带有超时的简单服务器。当运行的处理程序花费的时间超过超时时间时,如果我使用 Firefox 请求,该请求将无限期地重复。但是,如果我使用 Postman 或curl,则 reuqest 不会重复。我想防止浏览器中出现重复循环。我尝试手动关闭请求正文或检查上下文是否已取消,但是这些方法都不起作用。package mainimport (    "fmt"    "net/http"    "time")func main() {    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {        defer r.Body.Close()        fmt.Printf("Hello, you've requested: %s\n", r.URL.Path)        time.Sleep(time.Second * 2)        fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)    })    s := http.Server{        Addr:         ":8080",        Handler:      http.DefaultServeMux,        ReadTimeout:  1 * time.Second,        WriteTimeout: 1 * time.Second,    }    s.ListenAndServe()}我希望处理程序退出并且不再重复。
查看完整描述

1 回答

?
大话西游666

TA贡献1817条经验 获得超14个赞

根据我的理解,您面临的问题是服务器超时突然关闭底层 tcp conn 而没有编写正确的 http 响应,同时,当 firefox 检测到 conn 突然关闭时,它似乎决定重试 N 次,可能是因为它假设它遇到连接问题。

我相信解决方案是使用http.Handler来控制处理程序处理持续时间,并在超时到期时返回正确的 HTTP 响应。

服务器超时应该更长,并用于防止异常的客户端行为,而不是处理程序的缓慢。

标准 HTTP 包为此目的提供了TimeoutHandler函数。

package main


import (

    "fmt"

    "net/http"

    "time"

)


func main() {

    slowHandler := func(w http.ResponseWriter, r *http.Request) {

        defer r.Body.Close()

        fmt.Printf("Hello, you've requested: %s\n", r.URL.Path)

        time.Sleep(time.Second * 2)

        fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)

    }

    http.HandleFunc("/", slowHandler)


    var handler http.Handler = http.DefaultServeMux

    handler = http.TimeoutHandler(handler, time.Second, "processing timeout")


    s := http.Server{

        Addr:    ":8080",

        Handler: handler,

        // ReadTimeout:  1 * time.Second,

        // WriteTimeout: 1 * time.Second,

    }

    s.ListenAndServe()

}


查看完整回答
反对 回复 2023-07-31
  • 1 回答
  • 0 关注
  • 96 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信