我正在创建一个网络API,并希望人们能够使用ServeMux将请求路由到特定端点。我需要使用自己的低级Server,而不是使用ServerConn实例。这是因为我从同一个端口接收传入的HTTP请求和纯文本数据。
但问题是,如果我想使用我的ServeMux转发请求,我会使用它的ServeHTTP方法。为此,我需要提供一个ResponseWriter,我不知道如何创建一个实例,因为它是一个接口,而不是一个struct。我应该创建自己的ResponseWriter结构吗?是否有Golang标准图书馆给出的一个?或者是否有另一种解决方案?
答案 0 :(得分:4)
如果可能的话,我会完全避免这样做。在同一连接上混合协议必然会导致难以跟踪的错误和意外行为。如果你真的想这样做,并且所有的http / 1.1机制都能正常工作,请尽可能多地留给http包。
由于ResponseWriter是一个接口,您可以实现自己的类型来满足它。查看http包中未导出的response
类型以获取完整示例。有很多东西要做对,将它与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
。