如果可能的话,我会完全避免这样做。在同一连接上混合协议必然会导致难以追踪的错误和意外行为。如果你真的想这样做,并且让所有的 http/1.1 机制正常工作,请尽可能多地留给 http 包。
由于 ResponseWriter 是一个接口,您将实现自己的类型来满足它。查看response
http 包中未导出的类型以获取完整示例。有很多事情要做,并且将它与 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
.