Fluux XMPP is a Go XMPP library, focusing on simplicity, simple automation, and IoT.

Fluux XMPP

GoDoc GoReportCard Coverage Status

Fluux XMPP is a Go XMPP library, focusing on simplicity, simple automation, and IoT.

The goal is to make simple to write simple XMPP clients and components:

  • For automation (like for example monitoring of an XMPP service),
  • For building connected "things" by plugging them on an XMPP server,
  • For writing simple chatbot to control a service or a thing,
  • For writing XMPP servers components.

The library is designed to have minimal dependencies. Currently it requires at least Go 1.13.

Configuration and connection

Allowing Insecure TLS connection during development

It is not recommended to disable the check for domain name and certificate chain. Doing so would open your client to man-in-the-middle attacks.

However, in development, XMPP servers often use self-signed certificates. In that situation, it is better to add the root CA that signed the certificate to your trusted list of root CA. It avoids changing the code and limit the risk of shipping an insecure client to production.

That said, if you really want to allow your client to trust any TLS certificate, you can customize Go standard tls.Config and set it in Config struct.

Here is an example code to configure a client to allow connecting to a server with self-signed certificate. Note the InsecureSkipVerify option. When using this tls.Config option, all the checks on the certificate are skipped.

config := xmpp.Config{
	Address:      "localhost:5222",
	Jid:          "test@localhost",
	Credential:   xmpp.Password("Test"),
	TLSConfig:    tls.Config{InsecureSkipVerify: true},
}

Supported specifications

Clients

Components

Extensions

Package overview

Stanza subpackage

XMPP stanzas are basic and extensible XML elements. Stanzas (or sometimes special stanzas called 'nonzas') are used to leverage the XMPP protocol features. During a session, a client (or a component) and a server will be exchanging stanzas back and forth.

At a low-level, stanzas are XML fragments. However, Fluux XMPP library provides the building blocks to interact with stanzas at a high-level, providing a Go-friendly API.

The stanza subpackage provides support for XMPP stream parsing, marshalling and unmarshalling of XMPP stanza. It is a bridge between high-level Go structure and low-level XMPP protocol.

Parsing, marshalling and unmarshalling is automatically handled by Fluux XMPP client library. As a developer, you will generally manipulates only the high-level structs provided by the stanza package.

The XMPP protocol, as the name implies is extensible. If your application is using custom stanza extensions, you can implement your own extensions directly in your own application.

To learn more about the stanza package, you can read more in the stanza package documentation.

Router

TODO

Getting IQ response from server

TODO

Examples

We have several examples to help you get started using Fluux XMPP library.

Here is the demo "echo" client:

package main

import (
	"fmt"
	"log"
	"os"

	"gosrc.io/xmpp"
	"gosrc.io/xmpp/stanza"
)

func main() {
	config := xmpp.Config{
		TransportConfiguration: xmpp.TransportConfiguration{
			Address: "localhost:5222",
		},
		Jid:          "test@localhost",
		Credential:   xmpp.Password("test"),
		StreamLogger: os.Stdout,
		Insecure:     true,
		// TLSConfig: tls.Config{InsecureSkipVerify: true},
	}

	router := xmpp.NewRouter()
	router.HandleFunc("message", handleMessage)

	client, err := xmpp.NewClient(config, router, errorHandler)
	if err != nil {
		log.Fatalf("%+v", err)
	}

	// If you pass the client to a connection manager, it will handle the reconnect policy
	// for you automatically.
	cm := xmpp.NewStreamManager(client, nil)
	log.Fatal(cm.Run())
}

func handleMessage(s xmpp.Sender, p stanza.Packet) {
	msg, ok := p.(stanza.Message)
	if !ok {
		_, _ = fmt.Fprintf(os.Stdout, "Ignoring packet: %T\n", p)
		return
	}

	_, _ = fmt.Fprintf(os.Stdout, "Body = %s - from = %s\n", msg.Body, msg.From)
	reply := stanza.Message{Attrs: stanza.Attrs{To: msg.From}, Body: msg.Body}
	_ = s.Send(reply)
}

func errorHandler(err error) {
	fmt.Println(err.Error())
}

Reference documentation

The code documentation is available on GoDoc: gosrc.io/xmpp

Owner
Fluux
Multiprotocol Realtime Platform, by ProcessOne
Fluux
Comments
  • Introduce Transport interface and add Websocket support

    Introduce Transport interface and add Websocket support

    This PR aims to introduce the groundwork to support multiple transports, including the websocket transport requested in #112. I used a basic approach: introduce a new Transport interface which handles network connection and reading/writing tasks. There are also some obvious flaws:

    • [ ] I have not tested this beyond checking that the tests still pass
    • [x] There is no way to select the transport to use at the moment
    • [x] There should be a second transport implementation to show that this is useful.
    • [x] Handling of StartTLS needs to be moved into the transport, using either an only-allow-secure-connect flag or a report-if-connection-is-secure method that the session can check.

    If you are happy with the approach I used here I'll expand this further and implement a WebSocket transport.

  • Crashed with nil on socket by sending client

    Crashed with nil on socket by sending client

    The workaround PostConnect works nice. But there should not be crashed, if connect is not already established.

    https://github.com/FluuxIO/go-xmpp/blob/7a386ec8d04c376aecd99d4cc109e934693005f6/client.go#L181

  • MUC support

    MUC support

    I found my old code again ... yaja- most of the handling is a little bit trash.

    But the library of structs is still not bad (here: xmpp)

    The parsing is really easy: https://dev.sum7.eu/genofire/yaja/blob/master/client/comm.go#L9-37.

    Another nice feature is, that it is not necessary to iterate over all Message.Extensions we could just make a if PresenceClient.MUC !=nil because omitempty pointer are filled with nil if the values for this structs are not given.

    atm i miss somethings to replace other libraries in related project:

    • muc support
    • obb (to publish image urls as http_upload)
    • html body
  • Remove

    Remove "no depdencies" statement from README

    As is apparent from the current go.mod file, this library definitely depends on various other libraries. This in turn makes it depend on Go 1.13 (currently).

  • Prosody &

    Prosody & "echo" demo: not receiving any messages

    I'm a new user of go-xmpp and playing with the examples right now. I'm using Prosody as the XMPP server to talk with. I can successfully authenticate but no messages are delivered/routed to the echo client. After the session is initialized the StreamLogger stays silent and never logs anything else, no messages, no IQs, pings, ...).

    When I modify the example code I can even send messages from the echo client which are delivered successfully but still, no stanzas are ever received. Looking into the discussion of https://github.com/FluuxIO/go-xmpp/issues/9 I implemented a postConnect function to manually set the presence (which the echo demo client never did), but that doesn't help. Prosody doesn't deliver any messages to the echo demo client.

  • IQ result routes

    IQ result routes

    This is an attempt to fix #78. The approach I am taking is to introduce an API like this to the router:

    router.NewIqResultRoute(context.Background(), "9128171").HandlerFunc(func (s Sender, p stanza.Packet) {
        // Process IQ result 
    })
    

    The context is there to support cancellation and timeouts. They have become a pretty standard feature in golang webservers, and work well here. With a timeout the example becomes:

    router.NewIqResultRoute(context.WithTimeout(time.Second * 30, context.Background()), "9128171")
      .HandlerFunc(func (s Sender, p stanza.Packet) {
          // Process IQ result 
      })
      .TimeoutHandlerFunc(func (err error) {
          // Handle a timeout
      })
    

    To make this a little easier to use I am thinking of adding a method to Client to combine sending an IQ and adding a result route. Something like:

    func (c Client) SendIq(iq stanza.Packet, handler HandlerFunc) (*IqResultRoute, error) {
        if err := c.Send(iq); err != nil {
            return nil, err
        }
        return c.router.NewIqResultRoute(context.Background(), iq.Attrs.id).HandlerFunc(handler), nil
    }
    

    @mremond Does this look sensible to you?

    Remaining TODO items:

    • [x] Add router tests
    • [x] Expire old entries in iqResultRoutes
    • [x] If a result route is replaced cancel its context (if possible?)
  • Allow custom route matchers

    Allow custom route matchers

    When implementing a component handler I find myself needing to route based on the payload of an IQ message. Currently this requires you to register a generic IQ namespace handler, and do your own routing in that. Something like:

    router.NewRoute().IQNamespaces(NSMyProtocol).StanzaType("get").HandlerFunc(func (s xmpp.Sender, p stanza.Packet) {
        iq, ok := p.(xmpp.IQ)
        if !ok {
            return
        }
    
        switch payload := iq.Payload.(type) {
        case FooPayload:
            handleFoo(s, p)
        case BarPayload:
            handleBar(s, p)
        }
    })
    

    If would be very convenient if addMatcher was exposed so you could do something like this:

    
    type myProtocolMatcher string
    
    func (n myProtocolMatcher) Match(p stanza.Packet, match *RouteMatch) bool {
        iq, ok := p.(xmpp.IQ)
        if !ok {
            return false
        }
        // This assumes we have an iq.Payload extension registered with a struct type that
        // adds a Local() method. It would be very convenient if IQPayload already has that.
        return iq.Payload.Namespace() == NSMyProtocol && iq.Payload != nil && iq.Payload.Local() == n
    }
    
    router.NewRoute().AddMatcher(myProtocolMatcher("foo")).HandlerFunc(…)
    
    
  • Setup GitHub actions to run tests

    Setup GitHub actions to run tests

    I noticed you had to fix a failing test after my last PR, which is something I should have noticed myself. To help with that this PR adds a GitHub Action to automatically run all tests.

    To enable this you need to signup for GitHub Actions for the FluuxIO organisation first. After that I should work automatically.

  • Add support for initial Router for packet matching & delegation

    Add support for initial Router for packet matching & delegation

    • Add basic support for Router to make it easier to get your code trigger when some packets are received.
    • Add initial support for namespace delegation (XEP-0355) and priviledged entities (XEP-0356) and example component.
    • Clean up un IQ structures.
  • MUC history of zero values is not supported

    MUC history of zero values is not supported

    if int is 0 it will not be decoded - because you set omitempty. Solution is to set use pointer so that omitempty would handle the pointer and not the value. On this value a value like 0 is allowed.


    if you do not use it like here programmed, please create tests for it.

  • Stanza package & pattern to help building stanzas

    Stanza package & pattern to help building stanzas

    • Move parsing and stanza marshalling / unmarshalling to stanza package
    • Add pattern & basic helpers to simplify stanza building. This was requested on #61
  • GetDecoder() on an XMPP transport is called before Connect()

    GetDecoder() on an XMPP transport is called before Connect()

    ERRO[0212] stream error: invalid-from
    
    [ 3][t 0][1653306110.321923017][Client.cpp:291][&td_requests]   End to wait for updates, returning object 205 0x7fb9e43f8e50
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x90 pc=0x1173bba]
    
    goroutine 573 [running]:
    encoding/xml.(*Decoder).Token(0x0, 0x10, 0xc0002bfcb8, 0xb9bf79, 0x20)
            /usr/lib/go-1.15/src/encoding/xml/xml.go:282 +0x3a
    gosrc.io/xmpp/stanza.NextXmppToken(0x0, 0x7fba1c22b108, 0xc00038b8c0, 0x30, 0xc000366400)
            /home/bodqhrohro/go/pkg/mod/dev.narayana.im/narayana/[email protected]/stanza/parser.go:89 +0x45
    gosrc.io/xmpp/stanza.NextPacket(0x0, 0x0, 0x0, 0xc000464690, 0xc0002bffc0)
             /home/bodqhrohro/go/pkg/mod/dev.narayana.im/narayana/[email protected]/stanza/parser.go:53 +0x45
    gosrc.io/xmpp.(*Component).recv(0xc0001b0000)
            /home/bodqhrohro/go/pkg/mod/dev.narayana.im/narayana/[email protected]/component.go:128 +0x93
    created by gosrc.io/xmpp.(*Component).Resume
            /home/bodqhrohro/go/pkg/mod/dev.narayana.im/narayana/[email protected]/component.go:104 +0xa0b
    
  • Fix passing Component to StreamManager

    Fix passing Component to StreamManager

    0a4acd12c34b0048ff7554b7c56ddce975eb9286, which fixes #160, introduced a regression as it assumed only Client may implement StreamClient, and passing a component triggers an unconditional "client is not disconnected" error.

  • WIP: Support for XEP-0070 Verifying HTTP Requests via XMPP

    WIP: Support for XEP-0070 Verifying HTTP Requests via XMPP

    Support Verifying HTTP Requests via XMPP.

    I know that xep-0070 is very niche. I forked it to implement the following component: https://gitlab.com/jnanar/HTTPAuthentificationOverXMPP/-/tree/update_FluuxIO It is a fork of https://git.kingpenguin.tk/chteufleur/HTTPAuthentificationOverXMPP that rely on an obsolete XMPP library. If you are interesting in this PR, I will add some tests. If not, I will try to move the code of this PR in the component code. Thanks for your time :-)

  • InitialPresence should not be a constant

    InitialPresence should not be a constant

    I'd like to include XEP-0086 caps in the <presence/> sent. (Some users may want to also set a different <show/>, <status/> or <priority/>).

    Right now, it's a constant that cannot be adjusted, so I'll send one immediately after -- however, it should be adjustable before the connection starts.

  • 【FEATURE】implementing ANONYMOUS auth mechanism ?

    【FEATURE】implementing ANONYMOUS auth mechanism ?

    Hi there, is there any plan on support for ANONYMOUS auth mechanism ? It seems only PLAIN and X-OAUTH2 were supported.

    https://xmpp.org/extensions/xep-0175.html

Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.
Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.

Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.

Dec 27, 2022
GO2P is a P2P framework, designed with flexibility and simplicity in mind
GO2P is a P2P framework, designed with flexibility and simplicity in mind

go2p golang p2p framework By v-braun - viktor-braun.de. Description GO2P is a P2P framework, designed with flexibility and simplicity in mind. You can

Jan 5, 2023
Bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API
Bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API

bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API (mattermost not required!)

Jan 4, 2023
IRC bot for launch ddos attack, Mainly of scan target are IoT device that run linux and open default SSH port
IRC bot for launch ddos attack, Mainly of scan target are IoT device that run linux and open default SSH port

IRC bot for launch ddos attack, Mainly of scan target are IoT device that run linux and open default SSH port

Nov 10, 2021
Steam's protocol in Go to allow automation of different actions on the Steam network without running an actual Steam client

Steam's protocol in Go to allow automation of different actions on the Steam network without running an actual Steam client. Includes APIs for friends, chatting, trading, trade offers and TF2 crafting.

Jan 4, 2023
Wake-On-LAN Server for Home Automation
Wake-On-LAN Server for Home Automation

Wake-On-LAN Server for Home Automation This project builds a simple docker container that runs a webserver that allows you to send a wake-on-lan magic

Jan 21, 2022
A simple Go library to toggle on and off pac(proxy auto configuration) for Windows, MacOS and Linux

pac pac is a simple Go library to toggle on and off pac(proxy auto configuration

Dec 26, 2021
Simple, fast and scalable golang rpc library for high load

gorpc Simple, fast and scalable golang RPC library for high load and microservices. Gorpc provides the following features useful for highly loaded pro

Dec 19, 2022
Simple and modern beanstalkd library for Golang

go-jackd package main import "github.com/getjackd/go-jackd" func main() {

Sep 27, 2022
A library for the MIGP (Might I Get Pwned) protocolA library for the MIGP (Might I Get Pwned) protocol

MIGP library This contains a library for the MIGP (Might I Get Pwned) protocol. MIGP can be used to build privacy-preserving compromised credential ch

Dec 3, 2022
Simple mDNS client/server library in Golang

mdns Simple mDNS client/server library in Golang. mDNS or Multicast DNS can be used to discover services on the local network without the use of an au

Jan 4, 2023
A simple TUN/TAP library written in native Go.

water water is a native Go library for TUN/TAP interfaces. water is designed to be simple and efficient. It wraps almost only syscalls and uses only G

Jan 7, 2023
Simple REST client library in Go

Simple REST client library in Go Context The goal was to make a minimal library that could be easily reused and expanded in other projects. It doesn't

Sep 21, 2022
The graceful package is a simple library to shutdown application gracefully.

بِسْمِ اللّٰهِ الرَّحْمٰنِ الرَّحِيْمِ السَّلاَمُ عَلَيْكُمْ وَرَحْمَةُ اللهِ وَبَرَكَاتُهُ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَٰلَمِينَ ٱلْحَمْدُ لِلَّهِ رَ

Dec 27, 2021
Simple-request-limiter - Example of limiting API requests using standard Go library

Route: http://localhost:8080/urls example of body in POST request that was used:

Feb 2, 2022
A golang library about socks5, supports all socks5 commands. That Provides server and client and easy to use. Compatible with socks4 and socks4a.

socks5 This is a Golang implementation of the Socks5 protocol library. To see in this SOCKS Protocol Version 5. This library is also compatible with S

Nov 22, 2022
Simple wget - Simple wget written as test for Scorum

simple_wget simple wget written as test for Scorum Task: Implement in Go (http:/

Jan 24, 2022
Hetzner-dns-updater - A simple tool to update a DNS record via Hetzner DNS API. Used for simple HA together with Nomad

hetzner-dns-updater A small utility tool to update a single record via Hetzner D

Feb 12, 2022