// Handler returns the IQHandler for the given space, tag, and type combo. // Handler will always return a non-nil IQHandler. // // TODO: Handler should return ServiceUnavailable for get and set IQs and // should do nothing if the type is result or error. func (im IQMux) Handler(el element.Element, sType string) IQHandler { for _, entry := range im.handlers { if el.MatchNamespace(entry.space) && el.Tag == entry.tag && sType == entry.stanzaType { return entry.h } } return ServiceUnavailable{} }
// Handler returns the ElementHandler for the given space and tag pair. Handler // will always return a non-nil ElementHandler. func (em ElementMux) Handler(el element.Element) ElementHandler { for _, entry := range em.m { if el.MatchNamespace(entry.space) && el.Tag == entry.tag { return entry.h } } Trace.Printf("No handlers for %s:%s", el.Space, el.Tag) if em.DefaultHandler == nil { return UnsupportedStanza{} } return em.DefaultHandler }
func (h *Handler) HandleElement(el element.Element, props stream.Properties) ( []element.Element, stream.Properties) { var elems []element.Element var challenge bool switch el.Tag { case "auth": mechName := el.SelectAttrValue("mechanism", "") mech, ok := h.mechs[mechName] if !ok { elems = append(elems, element.SASLFailure.InvalidMechanism) break } data := el.Text() log.Println("Authenticating") elems, props, challenge = mech.Authenticate(data, props) if challenge { h.current = mech } case "response": if h.current == nil { el := element.SASLFailure.NotAuthorized. AddChild(element.New("text").SetText("Out of order SASL element")) elems = append(elems, el) } data := el.Text() elems, props, challenge = h.current.Authenticate(data, props) if !challenge { h.current = nil } } return elems, props }
func (s Stanza) TransformElement() element.Element { attrs := []element.Attr{} if s.To != "" { attrs = append(attrs, element.Attr{Key: "to", Value: s.To}) } if s.From != "" { attrs = append(attrs, element.Attr{Key: "from", Value: s.From}) } if s.ID != "" { attrs = append(attrs, element.Attr{Key: "id", Value: s.ID}) } if s.Type != "" { attrs = append(attrs, element.Attr{Key: "type", Value: s.Type}) } if s.Lang != "" { attrs = append(attrs, element.Attr{Key: "lang", Space: "xml", Value: s.Lang}) } if s.Namespaces != nil { for alias, ns := range s.Namespaces { // Handle top level namespace if alias == "" { attrs = append(attrs, element.Attr{Key: "xmlns", Value: ns}) continue } attrs = append(attrs, element.Attr{Key: alias, Space: "xmlns", Value: ns}) } } el := element.Element{Tag: s.Tag, Space: s.Space, Attr: attrs} if s.Data != "" { el = el.SetText(s.Data) } for _, child := range s.Children { el.Child = append(el.Child, child) } return el }
func TransformPresence(el element.Element) (Presence, error) { if el.Tag != "presence" { return Presence{}, ErrNotPresence } presence := Presence{} presence.To = el.SelectAttrValue("to", "") presence.From = el.SelectAttrValue("from", "") presence.ID = el.SelectAttrValue("id", "") presence.Type = el.SelectAttrValue("type", "") presence.Lang = el.SelectAttrValue("xml:lang", "") presence.Data = el.Text() presence.Children = el.ChildElements() presence.Tag, presence.Space = el.Tag, el.Space return presence, nil }
func TransformMessage(el element.Element) (Message, error) { if el.Tag != "message" { return Message{}, ErrNotMessage } message := Message{} message.To = el.SelectAttrValue("to", "") message.From = el.SelectAttrValue("from", "") message.ID = el.SelectAttrValue("id", "") message.Type = el.SelectAttrValue("type", "") message.Lang = el.SelectAttrValue("xml:lang", "") message.Data = el.Text() message.Children = el.ChildElements() message.Tag, message.Space = el.Tag, el.Space return message, nil }
func TransformIQ(el element.Element) IQ { if el.Tag != "iq" { return IQEmpty } iq := IQ{} iq.To = el.SelectAttrValue("to", "") iq.From = el.SelectAttrValue("from", "") iq.ID = el.SelectAttrValue("id", "") iq.Type = el.SelectAttrValue("type", "") iq.Lang = el.SelectAttrValue("xml:lang", "") iq.Data = el.Text() iq.Children = el.ChildElements() iq.Tag, iq.Space = el.Tag, el.Space return iq }
// HandleElement handles the stream:features element. It finds the // FeatureHandler to call for the given feature children elements invokes it. func (fm FeaturesMux) HandleElement(el element.Element, p Properties) ([]element.Element, Properties) { children := el.ChildElements() h, elem := fm.Handler(children) return h.HandleFeature(elem, p) }
// WriteElement converts the element to bytes and writes to the underlying // tcp connection. This method should generally be used for basic elements such // as those used during SASL negotiation. WriteStanzas should be used when // sending stanzas. func (t *TCP) WriteElement(el element.Element) error { var b []byte b = el.WriteBytes() _, err := t.Write(b) return err }
func TestNext(t *testing.T) { t.Parallel() var want, got interface{} var err error var el element.Element pipe1, pipe2 := net.Pipe() el = element.New("testing").AddAttr("foo", "bar"). SetText("random text"). AddChild(element.New("baz-quux")) tcpTsp := NewTCP(pipe1, stream.Receiving, nil, true) // Should be able to get a token from the transport go func() { _, err := pipe2.Write(el.WriteBytes()) if err != nil { t.Errorf("An unexpected error occurred: %s", err) } }() want = el got, err = tcpTsp.Next() if err != nil { t.Errorf("An unexpected error occurred: %s", err) } if !reflect.DeepEqual(want, got) { t.Error("Should be able to get a token from the transport.") t.Errorf("\nWant:%+v\nGot :%+v", want, got) } // Stream element should return token and not attempt to read the entire stream. pipe1, pipe2 = net.Pipe() tcpTsp = NewTCP(pipe1, stream.Receiving, nil, true) go func() { _, err := pipe2.Write(stream.Header{}.WriteBytes()) if err != nil { t.Errorf("An unexpected error occurred: %s", err) } _, err = pipe2.Write([]byte("<foo/></stream:stream>")) if err != nil { t.Errorf("An unexpected error occurred: %s", err) } }() el, err = tcpTsp.Next() if err != nil { t.Errorf("An unexpected error occurred: %s", err) } if el.Space != namespace.Stream || el.Tag != "stream" { t.Error("Stream element should return token and not attempt to read the entire stream.") } got, err = tcpTsp.Next() if err != nil { t.Errorf("An unexpected error occurred: %s", err) } want = element.New("foo") if !reflect.DeepEqual(want, got) { t.Error("Stream element should return token and not attempt to read the entire stream.") t.Errorf("\nWant:%+v\nGot :%+v", want, got) } }