Nil checks and a greatly simplified filter manager which is less buggy.
--- a/stream.go Mon Jan 02 10:01:41 2012 -0700
+++ b/stream.go Mon Jan 02 13:18:48 2012 -0700
@@ -286,6 +286,10 @@
break
}
case x := <- input:
+ if x == nil {
+ log.Println("Refusing to send nil stanza")
+ continue
+ }
srvOut <- x
}
}
@@ -293,50 +297,32 @@
// Stanzas from the remote go up through a stack of filters to the
// app. This function manages the filters.
-func filter(srvIn2 <-chan Stanza, cliOut2 chan<- Stanza,
- filterOut <-chan <-chan Stanza, filterIn chan<- <-chan Stanza) {
- defer close(cliOut2)
- var srvIn1, topFilterOut1, topFilterOut2 <-chan Stanza
- var cliOut1, botFilterIn1, botFilterIn2 chan<- Stanza
- ch := make(chan Stanza, 1)
- topFilterOut2 = ch
- botFilterIn2 = ch
- topFilterOut1 = topFilterOut2
- srvIn1 = srvIn2
- var botItem Stanza
- var topItem Stanza
- var ok bool
+func filterTop(filterOut <-chan <-chan Stanza, filterIn chan<- <-chan Stanza,
+ topFilter <-chan Stanza, app chan<- Stanza) {
+ defer close(app)
for {
select {
case newFilterOut := <- filterOut:
- filterIn <- topFilterOut2
- topFilterOut2 = newFilterOut
- if topFilterOut1 != nil {
- topFilterOut1 = topFilterOut2
+ if newFilterOut == nil {
+ log.Println("Received nil filter")
+ filterIn <- nil
+ continue
}
+ filterIn <- topFilter
- case topItem, ok = <-topFilterOut1:
+ case data, ok := <-topFilter:
if !ok {
break
}
- topFilterOut1 = nil
- cliOut1 = cliOut2
- case cliOut1 <- topItem:
- topFilterOut1 = topFilterOut2
- cliOut1 = nil
+ app <- data
+ }
+ }
+}
- case botItem, ok = <-srvIn1:
- if !ok {
- close(botFilterIn2)
- srvIn1 = nil
- continue
- }
- srvIn1 = nil
- botFilterIn1 = botFilterIn2
- case botFilterIn1 <- botItem:
- srvIn1 = srvIn2
- botFilterIn1 = nil
- }
+func filterBottom(from <-chan Stanza, to chan<- Stanza) {
+ defer close(to)
+ for data := range(from) {
+ to <- data
}
}
--- a/structs.go Mon Jan 02 10:01:41 2012 -0700
+++ b/structs.go Mon Jan 02 13:18:48 2012 -0700
@@ -271,6 +271,9 @@
}
func (u *Generic) String() string {
+ if u == nil {
+ return "nil"
+ }
var sub string
if u.Any != nil {
sub = u.Any.String()
--- a/xmpp.go Mon Jan 02 10:01:41 2012 -0700
+++ b/xmpp.go Mon Jan 02 13:18:48 2012 -0700
@@ -200,7 +200,9 @@
cliOut := make(chan Stanza)
filterOut := make(chan (<-chan Stanza))
filterIn := make(chan (<-chan Stanza))
- go filter(srvIn, cliOut, filterOut, filterIn)
+ nullFilter := make(chan Stanza)
+ go filterBottom(srvIn, nullFilter)
+ go filterTop(filterOut, filterIn, nullFilter, cliOut)
cl.filterOut = filterOut
cl.filterIn = filterIn
return cliOut