diff options
Diffstat (limited to 'deprecated-webircgateway/pkg/webircgateway/transport_kiwiirc.go')
| -rw-r--r-- | deprecated-webircgateway/pkg/webircgateway/transport_kiwiirc.go | 206 |
1 files changed, 0 insertions, 206 deletions
diff --git a/deprecated-webircgateway/pkg/webircgateway/transport_kiwiirc.go b/deprecated-webircgateway/pkg/webircgateway/transport_kiwiirc.go deleted file mode 100644 index e5247e8..0000000 --- a/deprecated-webircgateway/pkg/webircgateway/transport_kiwiirc.go +++ /dev/null @@ -1,206 +0,0 @@ -package webircgateway - -import ( - "fmt" - "log" - "net" - "net/http" - "runtime/debug" - "strings" - "sync" - - "github.com/gorilla/websocket" - "github.com/igm/sockjs-go/v3/sockjs" - cmap "github.com/orcaman/concurrent-map" -) - -type TransportKiwiirc struct { - gateway *Gateway -} - -func (t *TransportKiwiirc) Init(g *Gateway) { - t.gateway = g - sockjsOptions := sockjs.DefaultOptions - sockjsOptions.WebsocketUpgrader = &websocket.Upgrader{ - // Origin is checked within the session handler - CheckOrigin: func(_ *http.Request) bool { return true }, - } - handler := sockjs.NewHandler("/webirc/kiwiirc", sockjsOptions, t.sessionHandler) - t.gateway.HttpRouter.Handle("/webirc/kiwiirc/", handler) -} - -func (t *TransportKiwiirc) makeChannel(chanID string, ws sockjs.Session) *TransportKiwiircChannel { - client := t.gateway.NewClient() - - originHeader := strings.ToLower(ws.Request().Header.Get("Origin")) - if !t.gateway.IsClientOriginAllowed(originHeader) { - client.Log(2, "Origin %s not allowed. Closing connection", originHeader) - ws.Close(0, "Origin not allowed") - return nil - } - - client.RemoteAddr = t.gateway.GetRemoteAddressFromRequest(ws.Request()).String() - - clientHostnames, err := net.LookupAddr(client.RemoteAddr) - if err != nil || len(clientHostnames) == 0 { - client.RemoteHostname = client.RemoteAddr - } else { - // FQDNs include a . at the end. Strip it out - potentialHostname := strings.Trim(clientHostnames[0], ".") - - // Must check that the resolved hostname also resolves back to the users IP - addr, err := net.LookupIP(potentialHostname) - if err == nil && len(addr) == 1 && addr[0].String() == client.RemoteAddr { - client.RemoteHostname = potentialHostname - } else { - client.RemoteHostname = client.RemoteAddr - } - } - - if t.gateway.isRequestSecure(ws.Request()) { - client.Tags["secure"] = "" - } - - // This doesn't make sense to have since the remote port may change between requests. Only - // here for testing purposes for now. - _, remoteAddrPort, _ := net.SplitHostPort(ws.Request().RemoteAddr) - client.Tags["remote-port"] = remoteAddrPort - - client.Log(2, "New kiwiirc channel on %s from %s %s", ws.Request().Host, client.RemoteAddr, client.RemoteHostname) - client.Ready() - - channel := &TransportKiwiircChannel{ - Id: chanID, - Client: client, - Conn: ws, - waitForClose: make(chan bool), - Closed: false, - } - - go channel.listenForSignals() - - return channel -} - -func (t *TransportKiwiirc) sessionHandler(session sockjs.Session) { - // Don't let a single users error kill the entire service for everyone - defer func() { - if r := recover(); r != nil { - log.Printf("[ERROR] Recovered from %s\n%s", r, debug.Stack()) - } - }() - - channels := cmap.New() - - // Read from sockjs - go func() { - for { - msg, err := session.Recv() - if err == nil && len(msg) > 0 { - idEnd := strings.Index(msg, " ") - if idEnd == -1 { - // msg is in the form of ":chanId" - chanID := msg[1:] - - c, channelExists := channels.Get(chanID) - if channelExists { - channel := c.(*TransportKiwiircChannel) - channel.close() - } - - if !channelExists { - channel := t.makeChannel(chanID, session) - if channel == nil { - continue - } - channels.Set(chanID, channel) - - // When the channel closes, remove it from the map again - go func() { - <-channel.waitForClose - channel.Client.Log(2, "Removing channel from connection") - channels.Remove(chanID) - }() - } - - session.Send(":" + chanID) - - } else { - // msg is in the form of ":chanId data" - chanID := msg[1:idEnd] - data := msg[idEnd+1:] - - channel, channelExists := channels.Get(chanID) - if channelExists { - c := channel.(*TransportKiwiircChannel) - c.handleIncomingLine(data) - } - } - } else if err != nil { - t.gateway.Log(1, "kiwi connection closed (%s)", err.Error()) - break - } - } - - for channel := range channels.IterBuffered() { - c := channel.Val.(*TransportKiwiircChannel) - c.Closed = true - c.Client.StartShutdown("client_closed") - } - }() -} - -type TransportKiwiircChannel struct { - Conn sockjs.Session - Client *Client - Id string - waitForClose chan bool - ClosedLock sync.Mutex - Closed bool -} - -func (c *TransportKiwiircChannel) listenForSignals() { - for { - signal, ok := <-c.Client.Signals - if !ok { - break - } - c.Client.Log(1, "signal:%s %s", signal[0], signal[1]) - if signal[0] == "state" { - if signal[1] == "connected" { - c.Conn.Send(fmt.Sprintf(":%s control connected", c.Id)) - } else if signal[1] == "closed" { - c.Conn.Send(fmt.Sprintf(":%s control closed %s", c.Id, signal[2])) - } - } - - if signal[0] == "data" { - toSend := strings.Trim(signal[1], "\r\n") - c.Conn.Send(fmt.Sprintf(":%s %s", c.Id, toSend)) - } - } - - c.ClosedLock.Lock() - - c.Closed = true - close(c.Client.Recv) - close(c.waitForClose) - - c.ClosedLock.Unlock() -} - -func (c *TransportKiwiircChannel) handleIncomingLine(line string) { - c.ClosedLock.Lock() - - if !c.Closed { - c.Client.Recv <- line - } - - c.ClosedLock.Unlock() -} - -func (c *TransportKiwiircChannel) close() { - if c.Client.upstream != nil { - c.Client.upstream.Close() - } -} |
