~samwhited/xmpp

xmpp/doc.go -rw-r--r-- 6.0 KiB
81420f0eSam Whited xmpp: always set "from" on s2s stanzas 2 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2014 The Mellium Contributors.
// Use of this source code is governed by the BSD 2-clause
// license that can be found in the LICENSE file.

// Package xmpp provides functionality from the Extensible Messaging and
// Presence Protocol, sometimes known as "Jabber".
//
// It is subdivided into several packages; this package provides functionality
// for establishing an XMPP session, feature negotiation (including an API for
// defining your own stream features), and low-level connection and stream
// manipulation.
// Other important packages include the jid package, which provides an
// implementation of the XMPP address format, and the mux package which provides
// an XMPP handler that can multiplex payloads to other handlers and
// functionality for creating your own multiplexers.
//
// Session Negotiation
//
// To create an XMPP session, most users will want to call DialClientSession or
// DialServerSession to create a client-to-server (c2s) or server-to-server
// (s2s) connection respectively.
// These methods use sane defaults to dial a TCP connection and perform stream
// negotiation.
//
//     session, err := xmpp.DialClientSession(
//         context.TODO(), addr,
//         xmpp.BindResource(),
//         xmpp.StartTLS(nil),
//         xmpp.SASL("", pass, sasl.ScramSha1Plus, sasl.ScramSha1, sasl.Plain),
//     )
//
// If control over DNS or HTTP-based service discovery is desired, the user can
// use the dial package to create a dial.Dialer or use dial.Client (c2s) or
// dial.Server (s2s).
// To use the resulting connection, or to use something other than a TCP
// connection (eg. to communicate over a Unix domain socket, an in-memory pipe,
// etc.) the connection can be passed to NewClientSession or NewServerSession.
//
//     conn, err := dial.Client(context.TODO(), "tcp", addr)
//     …
//     session, err := xmpp.NewClientSession(
//         context.TODO(), addr, conn, false,
//         xmpp.BindResource(),
//         xmpp.StartTLS(nil),
//         xmpp.SASL("", pass, sasl.ScramSha1Plus, sasl.ScramSha1, sasl.Plain),
//     )
//
//
// If complete control over the session establishment process is needed the
// NegotiateSession function can be used to support custom session negotiation
// protocols or to customize options around the default negotiator by using the
// NewNegotiator function.
//
//     session, err := xmpp.NegotiateSession(
//         context.TODO(), addr.Domain(), addr, conn, false,
//         xmpp.NewNegotiator(xmpp.StreamConfig{
//             Lang: "en",
//             …
//         }),
//     )
//
// The default Negotiator and related functions use a list of StreamFeature's to
// negotiate the state of the session.
// Implementations of the most common features (StartTLS, SASL-based
// authentication, and resource binding) are provided.
// Custom stream features may be created using the StreamFeature struct.
// Stream features defined in this module are safe for concurrent use by
// multiple goroutines and for efficiency should only be created once and
// re-used.
//
// Handling Stanzas
//
// Unlike HTTP, the XMPP protocol is asynchronous, meaning that both clients and
// servers can accept and send requests at any time and responses are not
// required or may be received out of order.
// This is accomplished with two XML streams: an input stream and an output
// stream.
// To receive XML on the input stream, Session implements the xml.TokenReader
// interface defined in encoding/xml; this allows session to be wrapped with
// xml.NewTokenDecoder.
// To send XML on the output stream, Session has a TokenEncoder method that
// returns a token encoder that holds a lock on the output stream until it is
// closed.
// The session may also buffer writes and has a Flush method which will write
// any buffered XML to the underlying connection.
//
// Writing individual XML tokens can be tedious and error prone.
// The stanza package contains functions and structs that aid in the
// construction of message, presence and info/query (IQ) elements which have
// special semantics in XMPP and are known as "stanzas".
// These can be sent with the Send, SendElement, SendIQ, and SendIQElement
// methods.
//
//     // Send initial presence to let the server know we want to receive messages.
//     _, err = session.Send(context.TODO(), stanza.WrapPresence(jid.JID{}, stanza.AvailablePresence, nil))
//
// For SendIQ to correctly handle IQ responses, and to make the common case of
// polling for incoming XML on the input stream—and possibly writing to the
// output stream in response—easier, we need a long running goroutine.
// Session includes the Serve method for starting this processing.
//
// Serve provides a Handler with access to the stream but prevents it from
// advancing the stream beyond the current element and always advances the
// stream to the end of the element when the handler returns (even if the
// handler did not consume the entire element).
//
//     err := session.Serve(xmpp.HandlerFunc(func(t xmlstream.TokenReadEncoder, start *xml.StartElement) error {
//         d := xml.NewTokenDecoder(t)
//
//         // Ignore anything that's not a message.
//         if start.Name.Local != "message" {
//             return nil
//         }
//
//         msg := struct {
//             stanza.Message
//             Body string `xml:"body"`
//         }{}
//         err := d.DecodeElement(&msg, start)
//         …
//         if msg.Body != "" {
//             log.Println("Got message: %q", msg.Body)
//         }
//     }))
//
// It isn't always practical to put all of your logic for handling elements into
// a single function or method, so the mux package contains an XML multiplexer
// that can be used to match incoming payloads against a pattern and delegate
// them to individual handlers.
// Packages that implement extensions to the core XMPP protocol will often
// provide handlers that are compatible with types defined in the mux package,
// and options for registering them with the multiplexer.
//
//
// Be Advised
//
// This API is unstable and subject to change.
package xmpp // import "mellium.im/xmpp"