コード例 #1
0
ファイル: iq.go プロジェクト: skriptble/nine
// 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{}
}
コード例 #2
0
ファイル: element.go プロジェクト: skriptble/nine
// 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
}
コード例 #3
0
ファイル: handler.go プロジェクト: skriptble/nine
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
}
コード例 #4
0
ファイル: stanza.go プロジェクト: skriptble/nine
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
}
コード例 #5
0
ファイル: stanza.go プロジェクト: skriptble/nine
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
}
コード例 #6
0
ファイル: stanza.go プロジェクト: skriptble/nine
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
}
コード例 #7
0
ファイル: iq.go プロジェクト: skriptble/nine
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
}
コード例 #8
0
ファイル: features.go プロジェクト: skriptble/nine
// 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)
}
コード例 #9
0
ファイル: tcp.go プロジェクト: skriptble/nine
// 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
}
コード例 #10
0
ファイル: tcp_test.go プロジェクト: skriptble/nine
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)
	}
}