http proxy: simplify session management and remove redundant cookies

- Add devid, group, destaddr, and https fields to HttpProxySession for better session tracking and logging.
- Refactor doHttpProxy to use only the rtty-http-sid cookie for session lookup, removing dependencies on group, devid, proto, and destaddr cookies.
- In httpProxyRedirect, store all necessary session info in HttpProxySession and set only the rtty-http-sid cookie.
- Unify logging to use the session string for easier debugging.

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
This commit is contained in:
Jianhui Zhao
2025-07-21 09:25:44 +08:00
parent 6787a39007
commit 7c3eb9cc99
+37 -54
View File
@@ -46,9 +46,13 @@ import (
) )
type HttpProxySession struct { type HttpProxySession struct {
expire atomic.Int64 expire atomic.Int64
ctx context.Context ctx context.Context
cancel context.CancelFunc cancel context.CancelFunc
devid string
group string
destaddr string
https bool
} }
var httpProxySessions = sync.Map{} var httpProxySessions = sync.Map{}
@@ -59,6 +63,11 @@ func (ses *HttpProxySession) Expire() {
ses.expire.Store(time.Now().Add(httpProxySessionsExpire).Unix()) ses.expire.Store(time.Now().Add(httpProxySessionsExpire).Unix())
} }
func (ses *HttpProxySession) String() string {
return fmt.Sprintf("{devid: %s, group: %s, destaddr: %s, https: %v}",
ses.devid, ses.group, ses.destaddr, ses.https)
}
func (srv *RttyServer) ListenHttpProxy() { func (srv *RttyServer) ListenHttpProxy() {
cfg := &srv.cfg cfg := &srv.cfg
@@ -121,75 +130,50 @@ func doHttpProxy(srv *RttyServer, c net.Conn) {
return return
} }
cookie, err := req.Cookie("rtty-http-devid") cookie, err := req.Cookie("rtty-http-sid")
if err != nil { if err != nil {
log.Debug().Msg(`not found cookie "rtty-http-devid"`) log.Debug().Msgf(`not found cookie "rtty-http-sid"`)
sendHTTPErrorResponse(c, "invalid")
return
}
devid := cookie.Value
group := ""
cookie, err = req.Cookie("rtty-http-group")
if err == nil {
group = cookie.Value
}
dev := srv.GetDevice(group, devid)
if dev == nil {
log.Debug().Msgf(`device "%s" offline`, devid)
sendHTTPErrorResponse(c, "offline")
return
}
cookie, err = req.Cookie("rtty-http-sid")
if err != nil {
log.Debug().Msgf(`not found cookie "rtty-http-sid", devid "%s"`, devid)
sendHTTPErrorResponse(c, "invalid") sendHTTPErrorResponse(c, "invalid")
return return
} }
sid := cookie.Value sid := cookie.Value
https := false
cookie, _ = req.Cookie("rtty-http-proto")
if cookie != nil && cookie.Value == "https" {
https = true
}
hostHeaderRewrite := "localhost"
cookie, err = req.Cookie("rtty-http-destaddr")
if err == nil {
hostHeaderRewrite, _ = url.QueryUnescape(cookie.Value)
}
destAddr := genDestAddr(hostHeaderRewrite)
srcAddr := tcpAddr2Bytes(c.RemoteAddr().(*net.TCPAddr))
sesVal, ok := httpProxySessions.Load(sid) sesVal, ok := httpProxySessions.Load(sid)
if !ok { if !ok {
log.Debug().Msgf(`not found httpProxySession "%s", devid "%s"`, sid, devid) log.Debug().Msgf(`not found httpProxySession "%s"`, sid)
sendHTTPErrorResponse(c, "unauthorized") sendHTTPErrorResponse(c, "unauthorized")
return return
} }
ses := sesVal.(*HttpProxySession) ses := sesVal.(*HttpProxySession)
dev := srv.GetDevice(ses.group, ses.devid)
if dev == nil {
log.Debug().Msgf(`device "%s" group "%s" offline`, ses.devid, ses.group)
sendHTTPErrorResponse(c, "offline")
return
}
hostHeaderRewrite := ses.destaddr
destAddr := genDestAddr(hostHeaderRewrite)
srcAddr := tcpAddr2Bytes(c.RemoteAddr().(*net.TCPAddr))
ctx, cancel := context.WithCancel(ses.ctx) ctx, cancel := context.WithCancel(ses.ctx)
defer cancel() defer cancel()
go func() { go func() {
<-ctx.Done() <-ctx.Done()
c.Close() c.Close()
log.Debug().Msgf("http proxy conn closed, devid: %s, https: %v, destaddr: %s", devid, https, hostHeaderRewrite) log.Debug().Msgf("http proxy conn closed: %s", ses)
dev.https.Delete(string(srcAddr)) dev.https.Delete(string(srcAddr))
}() }()
log.Debug().Msgf("new http proxy conn, devid: %s, https: %v, destaddr: %s", devid, https, hostHeaderRewrite) log.Debug().Msgf("new http proxy conn: %s", ses)
dev.https.Store(string(srcAddr), c) dev.https.Store(string(srcAddr), c)
hpw := &HttpProxyWriter{destAddr, srcAddr, hostHeaderRewrite, dev, https} hpw := &HttpProxyWriter{destAddr, srcAddr, hostHeaderRewrite, dev, ses.https}
req.Host = hostHeaderRewrite req.Host = hostHeaderRewrite
hpw.WriteRequest(req) hpw.WriteRequest(req)
@@ -202,7 +186,7 @@ func doHttpProxy(srv *RttyServer, c net.Conn) {
if err != nil { if err != nil {
return return
} }
sendHttpReq(dev, https, srcAddr, destAddr, b[:n]) sendHttpReq(dev, ses.https, srcAddr, destAddr, b[:n])
ses.Expire() ses.Expire()
} }
} else { } else {
@@ -296,8 +280,12 @@ func httpProxyRedirect(srv *RttyServer, c *gin.Context, group string) {
ctx, cancel := context.WithCancel(dev.ctx) ctx, cancel := context.WithCancel(dev.ctx)
ses := &HttpProxySession{ ses := &HttpProxySession{
ctx: ctx, ctx: ctx,
cancel: cancel, cancel: cancel,
devid: devid,
group: group,
destaddr: addr,
https: proto == "https",
} }
ses.Expire() ses.Expire()
httpProxySessions.Store(sid, ses) httpProxySessions.Store(sid, ses)
@@ -315,11 +303,6 @@ func httpProxyRedirect(srv *RttyServer, c *gin.Context, group string) {
} }
c.SetCookie("rtty-http-sid", sid, 0, "", domain, false, true) c.SetCookie("rtty-http-sid", sid, 0, "", domain, false, true)
c.SetCookie("rtty-http-group", group, 0, "", domain, false, true)
c.SetCookie("rtty-http-devid", devid, 0, "", domain, false, true)
c.SetCookie("rtty-http-proto", proto, 0, "", domain, false, true)
c.SetCookie("rtty-http-destaddr", addr, 0, "", domain, false, true)
c.Redirect(http.StatusFound, location) c.Redirect(http.StatusFound, location)
} }