diff options
author | xengineering <me@xengineering.eu> | 2023-07-04 13:48:34 +0200 |
---|---|---|
committer | xengineering <me@xengineering.eu> | 2023-07-04 13:48:34 +0200 |
commit | 92534f5af88b42665ad44f2495fe5dfb116d3406 (patch) | |
tree | 53fe906edb6ce70f22e6602469b9ce4da5d55675 | |
parent | 45b04ef092a99d0d3f355e27896c82f1dbf15d28 (diff) | |
download | limox-92534f5af88b42665ad44f2495fe5dfb116d3406.tar limox-92534f5af88b42665ad44f2495fe5dfb116d3406.tar.zst limox-92534f5af88b42665ad44f2495fe5dfb116d3406.zip |
First working version of new RX concept
This uses xml.Decoder.DecodeElement() which makes parsing way easier.
This first step is just able to parse stream features partially.
-rw-r--r-- | xmpp/router.go | 38 | ||||
-rw-r--r-- | xmpp/session.go | 4 | ||||
-rw-r--r-- | xmpp/streams.go | 33 | ||||
-rw-r--r-- | xmpp/xml.go | 4 |
4 files changed, 31 insertions, 48 deletions
diff --git a/xmpp/router.go b/xmpp/router.go index 1e21c9b..d437b28 100644 --- a/xmpp/router.go +++ b/xmpp/router.go @@ -2,7 +2,6 @@ package xmpp import ( "encoding/xml" - "log" ) // routingTable is a data structure which contains routing information for XML @@ -12,7 +11,7 @@ import ( // entry of the routingTable. type routingTable []struct { name xml.Name - handler func(*session, []xml.Token) + handler func(s *xml.StartElement, d *xml.Decoder, c chan<- any) } // getRoutingTable returns the routing table used in @@ -23,40 +22,19 @@ type routingTable []struct { func getRoutingTable() routingTable { return routingTable{ {xml.Name{`http://etherx.jabber.org/streams`, `features`}, streamFeaturesHandler}, - {xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `success`}, saslSuccessHandler}, - {xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `failure`}, saslFailureHandler}, - {xml.Name{`jabber:client`, `iq`}, iqHandler}, +// {xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `success`}, saslSuccessHandler}, +// {xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `failure`}, saslFailureHandler}, +// {xml.Name{`jabber:client`, `iq`}, iqHandler}, } } // route determines the correct handler function for the given XML element by a // given routingTable. In addition it executes the determined handler function. // If no handler function is found an error message is send via the log module. -func route(s *session, e []xml.Token, t routingTable) { - var name xml.Name - - // TODO a stronger definition of an XML element (as here - // https://www.w3schools.com/xml/xml_elements.asp) would define that the - // first Token of an element is a StartElement token. This would make this - // code easier. - escape := false - for _, token := range e { - switch s := token.(type) { - case xml.StartElement: - name = s.Name - escape = true - } - if escape { - break - } - } - - for _, r := range t { - if name == r.name { - r.handler(s, e) - return +func route(s *xml.StartElement, d *xml.Decoder, c chan<- any, t routingTable) { + for _, v := range t { + if v.name == (*s).Name { + v.handler(s, d, c) } } - - log.Println("Could not route XML element") } diff --git a/xmpp/session.go b/xmpp/session.go index 4be3386..6abc343 100644 --- a/xmpp/session.go +++ b/xmpp/session.go @@ -20,7 +20,7 @@ type session struct { out chan<- any transport *tls.Conn tx *xml.Encoder - rx chan xml.Token + rx chan any resourceReq string } @@ -31,7 +31,7 @@ func StartSession(out chan<- any, jid string, pwd string) (in chan<- any) { s.pwd = pwd s.in = make(chan any) s.out = out - s.rx = make(chan xml.Token, 0) + s.rx = make(chan any, 0) go s.run() diff --git a/xmpp/streams.go b/xmpp/streams.go index b9c0cb7..9c90554 100644 --- a/xmpp/streams.go +++ b/xmpp/streams.go @@ -40,20 +40,6 @@ func closeStream(e *xml.Encoder) { } } -func streamFeaturesHandler(s *session, e []xml.Token) { - if hasSaslPlain(e) { - s.sasl() - return - } - - if hasBind(e) { - s.sendBind() - return - } - - log.Println("Stream has no implemented features!") -} - func iqHandler(s *session, e []xml.Token) { isResult := false idMatches := false @@ -77,3 +63,22 @@ func iqHandler(s *session, e []xml.Token) { } } } + +type streamFeatures struct { + Mechanisms struct { + Items []struct { + Type string `xml:",innerxml"` + } `xml:"mechanism"` + } `xml:"mechanisms"` +} + +func streamFeaturesHandler(s *xml.StartElement, d *xml.Decoder, c chan<- any) { + e := streamFeatures{} + + err := d.DecodeElement(&e, s) + if err != nil { + log.Printf("Could not decode stream features: %v\n", err) + } + + c <- e +} diff --git a/xmpp/xml.go b/xmpp/xml.go index 36d7eb1..470a2ef 100644 --- a/xmpp/xml.go +++ b/xmpp/xml.go @@ -9,7 +9,7 @@ import ( "log" ) -func runRx(ctx context.Context, chn chan xml.Token, conn *tls.Conn) { +func runRx(ctx context.Context, chn chan<- any, conn *tls.Conn) { l := logger{"[RX] "} r := io.TeeReader(conn, l) @@ -27,7 +27,7 @@ func runRx(ctx context.Context, chn chan xml.Token, conn *tls.Conn) { if e.Name.Local == "stream" { // new server-side stream TODO what to do with this info? } else { -// route(&e, &d, chn, getRoutingTable()) + route(&e, d, chn, getRoutingTable()) } case xml.EndElement: if e.Name.Local == "stream" { |