1

我正在创建一个网络 API,并希望人们能够使用ServeMux将请求路由到特定端点。我需要使用我自己的低级ServerConn ,而不是使用Server实例。这是因为我从同一个端口接收传入的 HTTP 请求和纯文本数据。

然而,问题是,如果我想使用我的 ServeMux 转发请求,我会使用它的ServeHTTP方法。为此,我需要提供一个 ResponseWriter,我不知道如何创建它的实例,因为它是一个接口,而不是一个结构。我应该创建自己的 ResponseWriter 结构吗?Golang 标准库是否提供了一个?还是完全有替代解决方案?

4

1 回答 1

4

如果可能的话,我会完全避免这样做。在同一连接上混合协议必然会导致难以追踪的错误和意外行为。如果你真的想这样做,并且让所有的 http/1.1 机制正常工作,请尽可能多地留给 http 包。

由于 ResponseWriter 是一个接口,您将实现自己的类型来满足它。查看responsehttp 包中未导出的类型以获取完整示例。有很多事情要做,并且将它与 ServerConn(记录为“不使用”)结合使用可能不是一个好主意。

在较低级别执行此操作的位置将在Accept服务器的net.Listener. 由于您将不得不两次解析每个请求的开头,因此您需要一个net.Conn可以部分“倒带”的。

让自己成为一个 net.Listener,它检查新连接上流的开始,如果它看起来像一个 http 请求,则返回一个net.Conn重放你在第一次读取时从线路中读取的第一个块。就像是:

type replayConn struct {
    net.Conn
    buf []byte
    pos int
}

func (c *replayConn) Read(b []byte) (int, error) {
    if c.pos < len(c.buf) {
        n := copy(b, c.buf[c.pos:])
        c.pos += n
        return n, nil
    }
    return c.Conn.Read(b)
}

如果连接不是 http,则将连接发送到您的其他类型的处理程序,并继续阻止Accept.

于 2015-04-30T13:52:44.610 回答