• Stars
    star
    136
  • Rank 267,670 (Top 6 %)
  • Language
    Erlang
  • License
    Apache License 2.0
  • Created about 8 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Erlang/Elixir XMPP parsing and serialization library on top of Fast XML

Erlang/Elixir XMPP library

CI Coverage Status Hex version

The library provides comprehensive representation of XMPP elements as well as tools to work with them. Every such element is represented by an Erlang record. Most of the library's code is auto generated and thus considered to be bug free and efficient.

The approach is very similar to ASN.1, Google Protocol Buffers or Apache Thrift: an XML element is transformed into internal language structure (an Erlang record in our case) - the process known as "decoding". During decoding, validation is also performed, thus well-typed structures are generated, potentially decreasing bugs related to handcrafted parsing. A reverse process known as "encoding" is applied for transforming an Erlang record into an XML element.

The library should be used along with fast_xml library, because it is only able to decode from and encode to structures generated by that library (that is, xmlel() elements).

Table of Contents:

  1. Status
  2. Compiling
  3. API
  4. Usage
    1. Initialization and header files
    2. XMPP elements
    3. Decoding and encoding
    4. Stanzas
      1. Common fields
      2. Constructing stanza responses
    5. Error elements
    6. Text elements
    7. Pretty printer
    8. Namespaces
    9. XMPP addresses
    10. Language translation
  5. Supported XMPP elements

Status

The library is considered as production ready and has been used in ejabberd XMPP server since version 16.12. However, the API is quite unstable so far and incompatibilities may be introduced from release to release. The stable API will be denoted by 2.x tag in the future.

Dependency

You need at least Erlang OTP 19.0.

Compiling

As usual, the following commands are used to obtain and compile the library:

$ git clone https://github.com/processone/xmpp.git
$ cd xmpp
$ make

API

The full API is documented in doc/API.md

Usage

Initialization and header files

Before calling any function from the library, xmpp application should be started.

Although there are several header files which a developer might find useful to look into, they should not be included directly in the code. Only include/xmpp.hrl file should be included, because it already includes all needed headers and also defines some useful macros. So the typical code should look like:

%% file: foo.erl
-module(foo).
-include_lib("xmpp/include/xmpp.hrl").
...
start() ->
    application:start(xmpp),
    ...

XMPP elements

All XMPP elements (records) are defined in include/xmpp_codec.hrl file. For convenience, every record has the corresponding type spec. There is also predefined xmpp_element() type which is a container for all defined record types: so sometimes we will refer to an arbitrary XMPP element as xmpp_element() in the rest of this document. These records are generated automatically by XML generator from specification file specs/xmpp_codec.spec. The specification file contains information about XML elements defined within XMPP related namespace.

TODO: writing specs for new elements will be documented later. For now you can learn by example: pick up a spec of any element which is very close to the one you want to add a spec for and use it as a pattern

WARNING: you should not include xmpp_codec.hrl in your erlang code. Include xmpp.hrl instead. xmpp_codec.hrl should be only used to consult definitions of existing XMPP elements.

Decoding and encoding

Once an xmlel() element is obtained (either using fxml_stream:parse_element/1 function or by any other means), it can be decoded using either decode/1 or decode/3 functions. The result will be an XMPP element. Note that decoding might fail if there is no known XMPP element for the provided xmlel() element, or xmlel() is invalid, so you should call these functions inside try ... catch. Exceptions returned during decoding can be formatted using format_error/1 or io_format_error/1 functions.

Example:

handle(#iq{type = get, sub_els = [El]} = IQ) ->
    try xmpp:decode(El) of
        Pkt -> handle_iq_child_element(Pkt)
    catch _:{xmpp_codec, Reason} ->
        Txt = xmpp:format_error(Reason),
	io:format("iq has malformed child element: ~s", [Txt]),
	handle_iq_with_malformed_child_element(IQ)
    end.

encode/1 and encode/2 functions can be used for reverse transformation, i.e. to encode an XMPP element into xmlel() element. Encoding would never fail as long as provided XMPP element is valid.

Stanzas

Amongst all XMPP elements defined in the library, the most notable ones are stanzas: message(), presence() and iq() elements. A large part of xmpp module deals with stanzas.

Common fields

Records of all stanzas have several common fields: id, type, lang, from, to, sub_els and meta. Although it's acceptable to manipulate with these fields directly (which is useful in pattern matching, for example), xmpp module provides several functions to work with them:

Constructing stanza responses

For creating iq() replies the following functions exist: make_iq_result/1 and make_iq_result/2.

These two functions are iq() specific and create iq() elements of type result only. To create an error response from an arbitrary stanza (including iq()) make_error/2 function can be used.

Error elements

A series of functions is provided by xmpp module for constructing stanza_error() or stream_error() elements. To construct stanza_error() elements the functions with err_ prefix can be used, such as err_bad_request/0 or err_internal_server_error/2. To construct stream_error() elements the functions with serr_ prefix can be used, such as serr_not_well_formed/0 or serr_invalid_from/2.

Text elements

The text element is represented by #text{} record (of text() type). Some record fields, such as #message.body or #presence.status, contain a list of text elements (i.e. [text()]). To avoid writing a lot of extracting code the following functions can be used to manipulate with text() elements: get_text/1, get_text/2, mk_text/1 and mk_text/2.

Pretty printer

For pretty printing of XMPP elements (for example, for dumping elements in the log in a more readable form), pp/1 function can be used.

Namespaces

There are many predefined macros for XMPP specific XML namespaces defined in include/ns.hrl such as ?NS_CLIENT or ?NS_ROSTER.

WARNING: you should not include ns.hrl in your erlang code. Include xmpp.hrl instead. Consult this file only to obtain a macro name for the required namespace.

There is also get_ns/1 function which can be used to obtain a namespace of xmpp_element() or from xmlel() element.

XMPP addresses

An XMPP address (aka Jabber ID or JID) can be represented using two types:

  • jid(): a JID is represented by a record #jid{}. This type is used to represent JIDs in XMPP elements.
  • ljid(): a JID is represented by a tuple {User, Server, Resource} where User, Server and Resource are stringprepped version of a nodepart, namepart and resourcepart of a JID respectively. This representation is useful for JIDs comparison and when a JID should be used as a key (in a Mnesia database, ETS table, etc.)

Both types and the record are defined in include/jid.hrl.

WARNING: you should not include jid.hrl in your erlang code. Include xmpp.hrl instead.

Functions for working with JIDs are provided by jid module.

Language translation

The library uses a callback function in order to perform language translation. The translation is applied when constructing text or error elements. To set the callback one can use set_tr_callback/1 function. By default, no translation is performed.

Supported XMPP elements

XMPP elements from the following documents are supported:

As well as some proprietary extensions from ProcessOne

More Repositories

1

ejabberd

Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
Erlang
6,101
star
2

tsung

Tsung is a high-performance benchmark framework for various protocols including HTTP, XMPP, LDAP, etc.
Erlang
2,543
star
3

ejabberd-contrib

Growing and curated ejabberd contributions repository - PR or ask to join !
Erlang
250
star
4

stun

STUN and TURN library for Erlang / Elixir
Erlang
245
star
5

eturnal

STUN / TURN standalone server
Erlang
241
star
6

xmpp-messenger-ios

iOS XMPP Messenger Framework
Swift
219
star
7

exmpp

Erlang XMPP library
Erlang
179
star
8

fast_xml

Fast Expat based Erlang XML parsing library
Erlang
134
star
9

oneteam

OneTeam XMPP multi-platform client. This is a Mozilla / XUL based platform, developed mostly in Javascript and C++ XPCOM.
C
100
star
10

docker-ejabberd

Set of ejabberd Docker images
Shell
95
star
11

grapherl

ejabberd monitoring server
Erlang
91
star
12

fast_tls

TLS / SSL OpenSSL-based native driver for Erlang / Elixir
C
83
star
13

demo-xmpp-ios

XMPPFramework Basic client relying using CocoaPods package
Swift
56
star
14

iconv

Fast encoding conversion library for Erlang / Elixir
Shell
54
star
15

fast_yaml

Fast YAML native library for Erlang / Elixir
Erlang
51
star
16

rtb

Benchmarking tool to stress real-time protocols
Erlang
50
star
17

eimp

Erlang Image Manipulation Process
Erlang
47
star
18

cache_tab

In-memory cache Erlang / Elixir library
Erlang
44
star
19

oms

Erlang-based Flash media server supporting video streaming, video conferencing, RPC call from client and from server, Remote Shared objects.
JavaScript
43
star
20

go-erlang

Go library for Erlang/Elixir interop
Go
31
star
21

ejabberd-vagrant-dev

Vagrant and Ansible script to create a VM preconfigured for ejabberd development
31
star
22

ejabberd-api

ejabberd API library in Go and multi-platform command-line tool
Go
24
star
23

xmpp-websocket-client

Test XMPP Websocket client
JavaScript
21
star
24

esip

ProcessOne SIP server component in Erlang
Erlang
20
star
25

p1_utils

Erlang Utility Modules from ProcessOne
Erlang
19
star
26

p1_pgsql

Pure Erlang PostgreSQL driver
Erlang
19
star
27

oneweb

OneWeb firefox extension to interact with browser and share content over XMPP
JavaScript
18
star
28

p1_mysql

Pure Erlang MySQL driver
Erlang
18
star
29

fast_ts

Fast TS is a fast Time Series Event Stream Processor
Elixir
17
star
30

stringprep

Fast Stringprep implementation for Erlang / Elixir
C
16
star
31

jamler

OCaml
15
star
32

docs.ejabberd.im

This is documentation site for ejabberd messaging server
CSS
14
star
33

mqtree

Index tree for MQTT topic filters
C
14
star
34

ezlib

Native zlib driver for Erlang / Elixir
Erlang
13
star
35

mysql

Erlang MySQL driver
Erlang
13
star
36

xml

Fast Expat based Erlang XML parsing library
Erlang
12
star
37

pkix

PKIX certificates management for Erlang
Erlang
11
star
38

epam

epam helper for Erlang / Elixir PAM authentication support
Erlang
11
star
39

p1_acme

ACME client library for Erlang
Erlang
11
star
40

eiconv

iconv Erlang binding
Shell
10
star
41

tls

TLS / SSL native driver for Erlang / Elixir
C
10
star
42

p1pp

ProcessOne Push Platform Command Line
Ruby
10
star
43

dpk

Analyse & convert data from online services for backup, indexing or migration purpose
Go
9
star
44

httpmock

HTTP recorder and mock library
HTML
9
star
45

xmpp-notifier

Github Action to send repository notifications to XMPP
Go
9
star
46

pgsql

Pure Erlang PostgreSQL driver
Erlang
8
star
47

p1_yaml

Fast Yaml native library for Erlang / Elixir
Erlang
7
star
48

yconf

YAML configuration processor
Erlang
7
star
49

p1pp-js

ProcessOne Push Platform Javascript library
JavaScript
7
star
50

fluux

fluux.io is a scalable messaging service (SaaS) powered by ejabberd Business Edition
7
star
51

android-wave-client

Wave client for Android mobile
Java
6
star
52

elixir_experiments

This is a repository containing Elixir experiments for ejabberd
Elixir
5
star
53

eredis_queue

Erlang Async Job Processing
Erlang
5
star
54

zlib

Native zlib driver for Erlang
Erlang
5
star
55

ecrdt

CRDT compliant data structures
Erlang
4
star
56

bfile

An interface to fast FILE I/O
C
4
star
57

p1_sip

ProcessOne SIP server component
Erlang
4
star
58

rebar3_exunit

A plugin to run Elixir ExUnit tests from rebar3 build tool
Erlang
2
star
59

google-wave-api

Wave API ported for Android
Java
2
star
60

dns-tools

Provides a programmer-friendly API for a number of undocumented OTP dns lookup, resolution, caching and configuration functions.
Erlang
2
star
61

ejabberd-po

Translation files for ejabberd
Erlang
2
star
62

soundcloud

Minimal library to implement SoundCloud client in Go
Go
1
star
63

OpenfireExporter

Export users from Openfire
1
star
64

p1_logger

ProcessOne logger for ejabberd
Erlang
1
star
65

jorge

Jorge is set of php scripts that are front-end for Oleg Palij ejabberd mod_logdb
PHP
1
star
66

ejabberdOSXPrefs

ejabberd preference panel for OSX
Objective-C
1
star
67

boxcar-ios-framework

iOS Push Framework for Boxcar
Objective-C
1
star
68

jira-security-level-plugin

This is a JIRA plugin to automatically set security level based on group of the reporter
Java
1
star