summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2023-05-20 22:33:56 +0200
committerxengineering <me@xengineering.eu>2023-05-21 10:47:58 +0200
commite386931283f3752d581530665a9c6616851aa536 (patch)
tree845d67f68bfff039827e008041858ebcac2805c7
parent7b29491f10ee31d0c275fa69d96c3ac6af8fa7a7 (diff)
downloadlimox-e386931283f3752d581530665a9c6616851aa536.tar
limox-e386931283f3752d581530665a9c6616851aa536.tar.zst
limox-e386931283f3752d581530665a9c6616851aa536.zip
Implement xengineering.eu/xmpp.tokenRouter
This will collect XML tokens until a full XML element is received and can be routed by a to-implement elementRouter.
-rw-r--r--xmpp/routing.go51
-rw-r--r--xmpp/xmpp.go11
2 files changed, 56 insertions, 6 deletions
diff --git a/xmpp/routing.go b/xmpp/routing.go
new file mode 100644
index 0000000..8af3190
--- /dev/null
+++ b/xmpp/routing.go
@@ -0,0 +1,51 @@
+package xmpp
+
+import (
+ "encoding/xml"
+ "errors"
+ "log"
+)
+
+type tokenRouter struct {
+ start xml.StartElement
+ end xml.EndElement
+ buffer []xml.Token
+ level uint16 // XML nesting level
+ enc *encoder
+}
+
+func newTokenRouter(e *encoder) tokenRouter {
+ return tokenRouter{
+ buffer: make([]xml.Token, 0),
+ level: 0,
+ enc: e,
+ }
+}
+
+func (r *tokenRouter) route(t xml.Token) error {
+ r.buffer = append(r.buffer, t)
+
+ switch unwrapped := t.(type) {
+ case xml.StartElement:
+ r.level += 1
+ if r.level == 1 {
+ r.start = unwrapped
+ // call start handler
+ }
+ case xml.EndElement:
+ if r.level == 0 {
+ log.Println("Ignoring XML end element on nesting level zero")
+ return nil
+ }
+ r.level -= 1
+ switch r.level {
+ case 0:
+ return errors.New("Stream was closed by server")
+ case 1:
+ // call elementRouter
+ r.buffer = r.buffer[:1]
+ }
+ }
+
+ return nil
+}
diff --git a/xmpp/xmpp.go b/xmpp/xmpp.go
index 5c6e3e9..c0a52a0 100644
--- a/xmpp/xmpp.go
+++ b/xmpp/xmpp.go
@@ -30,6 +30,8 @@ func Run(ch chan Event, jid string, pwd string) {
enc := newEncoder(conn)
defer enc.Close()
+ tr := newTokenRouter(&enc)
+
end := sendStreamStart(&enc, jid)
defer sendStreamEnd(&enc, end)
@@ -46,12 +48,9 @@ func Run(ch chan Event, jid string, pwd string) {
log.Printf("Unknown Event '%d'!\n", ev)
}
case token := <-decoder.data:
- switch element := token.(type) {
- case xml.EndElement:
- if element.Name.Local == "error" {
- log.Println("Received stream error!")
- return
- }
+ err = tr.route(token)
+ if err != nil {
+ return
}
}
}