summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2023-07-04 13:48:34 +0200
committerxengineering <me@xengineering.eu>2023-07-04 13:48:34 +0200
commit92534f5af88b42665ad44f2495fe5dfb116d3406 (patch)
tree53fe906edb6ce70f22e6602469b9ce4da5d55675
parent45b04ef092a99d0d3f355e27896c82f1dbf15d28 (diff)
downloadlimox-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.go38
-rw-r--r--xmpp/session.go4
-rw-r--r--xmpp/streams.go33
-rw-r--r--xmpp/xml.go4
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" {