使用 http.server 访问上下文

为了测试我正在编写的服务器,我希望能够在测试框架中启动和停止它。


为此,我希望可以将上下文包与 http.Server 结构集成。我希望能够在调用Done函数并且ctx.Done()通道返回某些内容时停止服务器。


我想做的就是修改http.Server.Serve() 方法,接受一个 context.Context 并检查它是否完成,在 for 循环的每次迭代中,如下所示:


func (srv *server) Serve(ctx context.Context, l net.Listener) error {

    defer l.Close()

    var tempDelay time.Duration // how long to sleep on accept failure

    for {

        select {

        case <-ctx.Done():

            return nil

        default:

        }

        ... rest is same as original

但是,如果我想在 for 循环中添加该检查,我将不得不重写很多方法,因为此方法调用其他私有方法(如 http.server.srv),而后者又调用其他私有方法。 ...


我还注意到,当侦听器上的 Accept() 方法返回错误时,for 循环将停止。


但是,我似乎无法找到一种方法,让侦听器在不访问其私有方法的情况下从其接受方法输出错误。


如果我必须复制和粘贴一半的 http 库只是为了让服务器停止使用上下文包,那么我似乎在做一些非常愚蠢和错误的事情。


我知道有很多解决方案可以支持 ServeHTTP 函数的上下文取消,但这不是我要讨论的内容。我想将上下文传递给整个服务器,而不仅仅是每个传入的请求。


这是不可能的吗?


慕哥9229398
浏览 166回答 1
1回答

拉丁的传说

使用httptest.Server创建一个可以在测试中启动和停止的服务器。如果你直接使用http.Server,你可以通过关闭net.Listener来打破 Serve 循环。当 net.Listener 关闭时,任何被阻塞的 Accept 操作都会被解除阻塞并返回错误。如果 Accept 返回永久错误,则 Serve 函数返回。
打开App,查看更多内容
随时随地看视频慕课网APP