Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
biboumi
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
98
Issues
98
List
Boards
Labels
Service Desk
Milestones
Merge Requests
12
Merge Requests
12
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
louiz’
biboumi
Commits
f0e07bea
Commit
f0e07bea
authored
Mar 02, 2015
by
louiz’
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Forgot to remove some XMPP files that are now in louloulibs instead
parent
649ebaf1
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
0 additions
and
862 deletions
+0
-862
CMakeLists.txt
CMakeLists.txt
+0
-3
src/xmpp/jid.cpp
src/xmpp/jid.cpp
+0
-94
src/xmpp/jid.hpp
src/xmpp/jid.hpp
+0
-36
src/xmpp/xmpp_parser.cpp
src/xmpp/xmpp_parser.cpp
+0
-169
src/xmpp/xmpp_parser.hpp
src/xmpp/xmpp_parser.hpp
+0
-126
src/xmpp/xmpp_stanza.cpp
src/xmpp/xmpp_stanza.cpp
+0
-274
src/xmpp/xmpp_stanza.hpp
src/xmpp/xmpp_stanza.hpp
+0
-160
No files found.
CMakeLists.txt
View file @
f0e07bea
...
...
@@ -76,9 +76,6 @@ include_directories(${ICONV_INCLUDE_DIRS})
include_directories
(
${
LIBUUID_INCLUDE_DIRS
}
)
# If they are found in louloulibs CMakeLists.txt, we inherite these values
if
(
LIBIDN_FOUND
)
include_directories
(
${
LIBIDN_INCLUDE_DIRS
}
)
endif
()
if
(
SYSTEMD_FOUND
)
include_directories
(
${
SYSTEMD_INCLUDE_DIRS
}
)
endif
()
...
...
src/xmpp/jid.cpp
deleted
100644 → 0
View file @
649ebaf1
#include <xmpp/jid.hpp>
#include <cstring>
#include <map>
#include <louloulibs.h>
#ifdef LIBIDN_FOUND
#include <stringprep.h>
#endif
#include <logger/logger.hpp>
Jid
::
Jid
(
const
std
::
string
&
jid
)
{
std
::
string
::
size_type
slash
=
jid
.
find
(
'/'
);
if
(
slash
!=
std
::
string
::
npos
)
{
this
->
resource
=
jid
.
substr
(
slash
+
1
);
}
std
::
string
::
size_type
at
=
jid
.
find
(
'@'
);
if
(
at
!=
std
::
string
::
npos
&&
at
<
slash
)
{
this
->
local
=
jid
.
substr
(
0
,
at
);
at
++
;
}
else
at
=
0
;
this
->
domain
=
jid
.
substr
(
at
,
slash
-
at
);
}
#include <iostream>
static
constexpr
size_t
max_jid_part_len
=
1023
;
std
::
string
jidprep
(
const
std
::
string
&
original
)
{
#ifdef LIBIDN_FOUND
using
CacheType
=
std
::
map
<
std
::
string
,
std
::
string
>
;
static
CacheType
cache
;
std
::
pair
<
CacheType
::
iterator
,
bool
>
cached
=
cache
.
insert
({
original
,
{}});
if
(
std
::
get
<
1
>
(
cached
)
==
false
)
{
// Insertion failed: the result is already in the cache, return it
return
std
::
get
<
0
>
(
cached
)
->
second
;
}
const
std
::
string
error_msg
(
"Failed to convert "
+
original
+
" into a valid JID:"
);
Jid
jid
(
original
);
char
local
[
max_jid_part_len
]
=
{};
memcpy
(
local
,
jid
.
local
.
data
(),
jid
.
local
.
size
());
Stringprep_rc
rc
=
static_cast
<
Stringprep_rc
>
(
::
stringprep
(
local
,
max_jid_part_len
,
static_cast
<
Stringprep_profile_flags
>
(
0
),
stringprep_xmpp_nodeprep
));
if
(
rc
!=
STRINGPREP_OK
)
{
log_error
(
error_msg
+
stringprep_strerror
(
rc
));
return
""
;
}
char
domain
[
max_jid_part_len
]
=
{};
memcpy
(
domain
,
jid
.
domain
.
data
(),
jid
.
domain
.
size
());
rc
=
static_cast
<
Stringprep_rc
>
(
::
stringprep
(
domain
,
max_jid_part_len
,
static_cast
<
Stringprep_profile_flags
>
(
0
),
stringprep_nameprep
));
if
(
rc
!=
STRINGPREP_OK
)
{
log_error
(
error_msg
+
stringprep_strerror
(
rc
));
return
""
;
}
// If there is no resource, stop here
if
(
jid
.
resource
.
empty
())
{
std
::
get
<
0
>
(
cached
)
->
second
=
std
::
string
(
local
)
+
"@"
+
domain
;
return
std
::
get
<
0
>
(
cached
)
->
second
;
}
// Otherwise, also process the resource part
char
resource
[
max_jid_part_len
]
=
{};
memcpy
(
resource
,
jid
.
resource
.
data
(),
jid
.
resource
.
size
());
rc
=
static_cast
<
Stringprep_rc
>
(
::
stringprep
(
resource
,
max_jid_part_len
,
static_cast
<
Stringprep_profile_flags
>
(
0
),
stringprep_xmpp_resourceprep
));
if
(
rc
!=
STRINGPREP_OK
)
{
log_error
(
error_msg
+
stringprep_strerror
(
rc
));
return
""
;
}
std
::
get
<
0
>
(
cached
)
->
second
=
std
::
string
(
local
)
+
"@"
+
domain
+
"/"
+
resource
;
return
std
::
get
<
0
>
(
cached
)
->
second
;
#else
(
void
)
original
;
return
""
;
#endif
}
src/xmpp/jid.hpp
deleted
100644 → 0
View file @
649ebaf1
#ifndef JID_INCLUDED
# define JID_INCLUDED
#include <string>
/**
* Parse a JID into its different subart
*/
class
Jid
{
public:
explicit
Jid
(
const
std
::
string
&
jid
);
std
::
string
domain
;
std
::
string
local
;
std
::
string
resource
;
private:
Jid
(
const
Jid
&
)
=
delete
;
Jid
(
Jid
&&
)
=
delete
;
Jid
&
operator
=
(
const
Jid
&
)
=
delete
;
Jid
&
operator
=
(
Jid
&&
)
=
delete
;
};
/**
* Prepare the given UTF-8 string according to the XMPP node stringprep
* identifier profile. This is used to send properly-formed JID to the XMPP
* server.
*
* If the stringprep library is not found, we return an empty string. When
* this function is used, the result must always be checked for an empty
* value, and if this is the case it must not be used as a JID.
*/
std
::
string
jidprep
(
const
std
::
string
&
original
);
#endif // JID_INCLUDED
src/xmpp/xmpp_parser.cpp
deleted
100644 → 0
View file @
649ebaf1
#include <xmpp/xmpp_parser.hpp>
#include <xmpp/xmpp_stanza.hpp>
#include <logger/logger.hpp>
/**
* Expat handlers. Called by the Expat library, never by ourself.
* They just forward the call to the XmppParser corresponding methods.
*/
static
void
start_element_handler
(
void
*
user_data
,
const
XML_Char
*
name
,
const
XML_Char
**
atts
)
{
static_cast
<
XmppParser
*>
(
user_data
)
->
start_element
(
name
,
atts
);
}
static
void
end_element_handler
(
void
*
user_data
,
const
XML_Char
*
name
)
{
static_cast
<
XmppParser
*>
(
user_data
)
->
end_element
(
name
);
}
static
void
character_data_handler
(
void
*
user_data
,
const
XML_Char
*
s
,
int
len
)
{
static_cast
<
XmppParser
*>
(
user_data
)
->
char_data
(
s
,
len
);
}
/**
* XmppParser class
*/
XmppParser
::
XmppParser
()
:
level
(
0
),
current_node
(
nullptr
)
{
this
->
init_xml_parser
();
}
void
XmppParser
::
init_xml_parser
()
{
// Create the expat parser
this
->
parser
=
XML_ParserCreateNS
(
"UTF-8"
,
':'
);
XML_SetUserData
(
this
->
parser
,
static_cast
<
void
*>
(
this
));
// Install Expat handlers
XML_SetElementHandler
(
this
->
parser
,
&
start_element_handler
,
&
end_element_handler
);
XML_SetCharacterDataHandler
(
this
->
parser
,
&
character_data_handler
);
}
XmppParser
::~
XmppParser
()
{
if
(
this
->
current_node
)
delete
this
->
current_node
;
XML_ParserFree
(
this
->
parser
);
}
int
XmppParser
::
feed
(
const
char
*
data
,
const
int
len
,
const
bool
is_final
)
{
int
res
=
XML_Parse
(
this
->
parser
,
data
,
len
,
is_final
);
if
(
res
==
XML_STATUS_ERROR
&&
(
XML_GetErrorCode
(
this
->
parser
)
!=
XML_ERROR_FINISHED
))
log_error
(
"Xml_Parse encountered an error: "
<<
XML_ErrorString
(
XML_GetErrorCode
(
this
->
parser
)))
return
res
;
}
int
XmppParser
::
parse
(
const
int
len
,
const
bool
is_final
)
{
int
res
=
XML_ParseBuffer
(
this
->
parser
,
len
,
is_final
);
if
(
res
==
XML_STATUS_ERROR
)
log_error
(
"Xml_Parsebuffer encountered an error: "
<<
XML_ErrorString
(
XML_GetErrorCode
(
this
->
parser
)));
return
res
;
}
void
XmppParser
::
reset
()
{
XML_ParserFree
(
this
->
parser
);
this
->
init_xml_parser
();
if
(
this
->
current_node
)
delete
this
->
current_node
;
this
->
current_node
=
nullptr
;
this
->
level
=
0
;
}
void
*
XmppParser
::
get_buffer
(
const
size_t
size
)
const
{
return
XML_GetBuffer
(
this
->
parser
,
static_cast
<
int
>
(
size
));
}
void
XmppParser
::
start_element
(
const
XML_Char
*
name
,
const
XML_Char
**
attribute
)
{
level
++
;
XmlNode
*
new_node
=
new
XmlNode
(
name
,
this
->
current_node
);
if
(
this
->
current_node
)
this
->
current_node
->
add_child
(
new_node
);
this
->
current_node
=
new_node
;
for
(
size_t
i
=
0
;
attribute
[
i
];
i
+=
2
)
this
->
current_node
->
set_attribute
(
attribute
[
i
],
attribute
[
i
+
1
]);
if
(
this
->
level
==
1
)
this
->
stream_open_event
(
*
this
->
current_node
);
}
void
XmppParser
::
end_element
(
const
XML_Char
*
name
)
{
(
void
)
name
;
level
--
;
this
->
current_node
->
close
();
if
(
level
==
1
)
{
this
->
stanza_event
(
*
this
->
current_node
);
}
if
(
level
==
0
)
{
this
->
stream_close_event
(
*
this
->
current_node
);
delete
this
->
current_node
;
this
->
current_node
=
nullptr
;
}
else
this
->
current_node
=
this
->
current_node
->
get_parent
();
if
(
level
==
1
)
this
->
current_node
->
delete_all_children
();
}
void
XmppParser
::
char_data
(
const
XML_Char
*
data
,
int
len
)
{
if
(
this
->
current_node
->
has_children
())
this
->
current_node
->
get_last_child
()
->
add_to_tail
(
std
::
string
(
data
,
len
));
else
this
->
current_node
->
add_to_inner
(
std
::
string
(
data
,
len
));
}
void
XmppParser
::
stanza_event
(
const
Stanza
&
stanza
)
const
{
for
(
const
auto
&
callback
:
this
->
stanza_callbacks
)
{
try
{
callback
(
stanza
);
}
catch
(
const
std
::
exception
&
e
)
{
log_debug
(
"Unhandled exception: "
<<
e
.
what
());
}
}
}
void
XmppParser
::
stream_open_event
(
const
XmlNode
&
node
)
const
{
for
(
const
auto
&
callback
:
this
->
stream_open_callbacks
)
callback
(
node
);
}
void
XmppParser
::
stream_close_event
(
const
XmlNode
&
node
)
const
{
for
(
const
auto
&
callback
:
this
->
stream_close_callbacks
)
callback
(
node
);
}
void
XmppParser
::
add_stanza_callback
(
std
::
function
<
void
(
const
Stanza
&
)
>&&
callback
)
{
this
->
stanza_callbacks
.
emplace_back
(
std
::
move
(
callback
));
}
void
XmppParser
::
add_stream_open_callback
(
std
::
function
<
void
(
const
XmlNode
&
)
>&&
callback
)
{
this
->
stream_open_callbacks
.
emplace_back
(
std
::
move
(
callback
));
}
void
XmppParser
::
add_stream_close_callback
(
std
::
function
<
void
(
const
XmlNode
&
)
>&&
callback
)
{
this
->
stream_close_callbacks
.
emplace_back
(
std
::
move
(
callback
));
}
src/xmpp/xmpp_parser.hpp
deleted
100644 → 0
View file @
649ebaf1
#ifndef XMPP_PARSER_INCLUDED
# define XMPP_PARSER_INCLUDED
#include <xmpp/xmpp_stanza.hpp>
#include <functional>
#include <expat.h>
/**
* A SAX XML parser that builds XML nodes and spawns events when a complete
* stanza is received (an element of level 2), or when the document is
* opened/closed (an element of level 1)
*
* After a stanza_event has been spawned, we delete the whole stanza. This
* means that even with a very long document (in XMPP the document is
* potentially infinite), the memory is never exhausted as long as each
* stanza is reasonnably short.
*
* The element names generated by expat contain the namespace of the
* element, a colon (':') and then the actual name of the element. To get
* an element "x" with a namespace of "http://jabber.org/protocol/muc", you
* just look for an XmlNode named "http://jabber.org/protocol/muc:x"
*
* TODO: enforce the size-limit for the stanza (limit the number of childs
* it can contain). For example forbid the parser going further than level
* 20 (arbitrary number here), and each XML node to have more than 15 childs
* (arbitrary number again).
*/
class
XmppParser
{
public:
explicit
XmppParser
();
~
XmppParser
();
public:
/**
* Init the XML parser and install the callbacks
*/
void
init_xml_parser
();
/**
* Feed the parser with some XML data
*/
int
feed
(
const
char
*
data
,
const
int
len
,
const
bool
is_final
);
/**
* Parse the data placed in the parser buffer
*/
int
parse
(
const
int
size
,
const
bool
is_final
);
/**
* Reset the parser, so it can be used from scratch afterward
*/
void
reset
();
/**
* Get a buffer provided by the xml parser.
*/
void
*
get_buffer
(
const
size_t
size
)
const
;
/**
* Add one callback for the various events that this parser can spawn.
*/
void
add_stanza_callback
(
std
::
function
<
void
(
const
Stanza
&
)
>&&
callback
);
void
add_stream_open_callback
(
std
::
function
<
void
(
const
XmlNode
&
)
>&&
callback
);
void
add_stream_close_callback
(
std
::
function
<
void
(
const
XmlNode
&
)
>&&
callback
);
/**
* Called when a new XML element has been opened. We instanciate a new
* XmlNode and set it as our current node. The parent of this new node is
* the previous "current" node. We have all the element's attributes in
* this event.
*
* We spawn a stream_event with this node if this is a level-1 element.
*/
void
start_element
(
const
XML_Char
*
name
,
const
XML_Char
**
attribute
);
/**
* Called when an XML element has been closed. We close the current_node,
* set our current_node as the parent of the current_node, and if that was
* a level-2 element we spawn a stanza_event with this node.
*
* And we then delete the stanza (and everything under it, its children,
* attribute, etc).
*/
void
end_element
(
const
XML_Char
*
name
);
/**
* Some inner or tail data has been parsed
*/
void
char_data
(
const
XML_Char
*
data
,
int
len
);
/**
* Calls all the stanza_callbacks one by one.
*/
void
stanza_event
(
const
Stanza
&
stanza
)
const
;
/**
* Calls all the stream_open_callbacks one by one. Note: the passed node is not
* closed yet.
*/
void
stream_open_event
(
const
XmlNode
&
node
)
const
;
/**
* Calls all the stream_close_callbacks one by one.
*/
void
stream_close_event
(
const
XmlNode
&
node
)
const
;
private:
/**
* Expat structure.
*/
XML_Parser
parser
;
/**
* The current depth in the XML document
*/
size_t
level
;
/**
* The deepest XML node opened but not yet closed (to which we are adding
* new children, inner or tail)
*/
XmlNode
*
current_node
;
/**
* A list of callbacks to be called on an *_event, receiving the
* concerned Stanza/XmlNode.
*/
std
::
vector
<
std
::
function
<
void
(
const
Stanza
&
)
>>
stanza_callbacks
;
std
::
vector
<
std
::
function
<
void
(
const
XmlNode
&
)
>>
stream_open_callbacks
;
std
::
vector
<
std
::
function
<
void
(
const
XmlNode
&
)
>>
stream_close_callbacks
;
XmppParser
(
const
XmppParser
&
)
=
delete
;
XmppParser
&
operator
=
(
const
XmppParser
&
)
=
delete
;
};
#endif // XMPP_PARSER_INCLUDED
src/xmpp/xmpp_stanza.cpp
deleted
100644 → 0
View file @
649ebaf1
#include <xmpp/xmpp_stanza.hpp>
#include <utils/encoding.hpp>
#include <utils/split.hpp>
#include <stdexcept>
#include <iostream>
#include <string.h>
std
::
string
xml_escape
(
const
std
::
string
&
data
)
{
std
::
string
res
;
res
.
reserve
(
data
.
size
());
for
(
size_t
pos
=
0
;
pos
!=
data
.
size
();
++
pos
)
{
switch
(
data
[
pos
])
{
case
'&'
:
res
+=
"&"
;
break
;
case
'<'
:
res
+=
"<"
;
break
;
case
'>'
:
res
+=
">"
;
break
;
case
'\"'
:
res
+=
"""
;
break
;
case
'\''
:
res
+=
"'"
;
break
;
default:
res
+=
data
[
pos
];
break
;
}
}
return
res
;
}
std
::
string
xml_unescape
(
const
std
::
string
&
data
)
{
std
::
string
res
;
res
.
reserve
(
data
.
size
());
const
char
*
str
=
data
.
c_str
();
while
(
str
&&
*
str
&&
static_cast
<
size_t
>
(
str
-
data
.
c_str
())
<
data
.
size
())
{
if
(
*
str
==
'&'
)
{
if
(
strncmp
(
str
+
1
,
"amp;"
,
4
)
==
0
)
{
res
+=
"&"
;
str
+=
4
;
}
else
if
(
strncmp
(
str
+
1
,
"lt;"
,
3
)
==
0
)
{
res
+=
"<"
;
str
+=
3
;
}
else
if
(
strncmp
(
str
+
1
,
"gt;"
,
3
)
==
0
)
{
res
+=
">"
;
str
+=
3
;
}
else
if
(
strncmp
(
str
+
1
,
"quot;"
,
5
)
==
0
)
{
res
+=
"
\"
"
;
str
+=
5
;
}
else
if
(
strncmp
(
str
+
1
,
"apos;"
,
5
)
==
0
)
{
res
+=
"'"
;
str
+=
5
;
}
else
res
+=
"&"
;
}
else
res
+=
*
str
;
str
++
;
}
return
res
;
}
XmlNode
::
XmlNode
(
const
std
::
string
&
name
,
XmlNode
*
parent
)
:
parent
(
parent
),
closed
(
false
)
{
// split the namespace and the name
auto
n
=
name
.
rfind
(
":"
);
if
(
n
==
std
::
string
::
npos
)
this
->
name
=
name
;
else
{
this
->
name
=
name
.
substr
(
n
+
1
);
this
->
attributes
[
"xmlns"
]
=
name
.
substr
(
0
,
n
);
}
}
XmlNode
::
XmlNode
(
const
std
::
string
&
name
)
:
XmlNode
(
name
,
nullptr
)
{
}
XmlNode
::~
XmlNode
()
{
this
->
delete_all_children
();
}
void
XmlNode
::
delete_all_children
()
{
for
(
auto
&
child
:
this
->
children
)
{
delete
child
;
}
this
->
children
.
clear
();
}
void
XmlNode
::
set_attribute
(
const
std
::
string
&
name
,
const
std
::
string
&
value
)
{
this
->
attributes
[
name
]
=
value
;
}
void
XmlNode
::
set_tail
(
const
std
::
string
&
data
)
{
this
->
tail
=
xml_escape
(
data
);
}
void
XmlNode
::
add_to_tail
(
const
std
::
string
&
data
)
{
this
->
tail
+=
xml_escape
(
data
);
}
void
XmlNode
::
set_inner
(
const
std
::
string
&
data
)
{
this
->
inner
=
xml_escape
(
data
);
}
void
XmlNode
::
add_to_inner
(
const
std
::
string
&
data
)
{
this
->
inner
+=
xml_escape
(
data
);
}
std
::
string
XmlNode
::
get_inner
()
const
{
return
xml_unescape
(
this
->
inner
);
}
std
::
string
XmlNode
::
get_tail
()
const
{
return
xml_unescape
(
this
->
tail
);
}
XmlNode
*
XmlNode
::
get_child
(
const
std
::
string
&
name
,
const
std
::
string
&
xmlns
)
const
{
for
(
auto
&
child
:
this
->
children
)
{
if
(
child
->
name
==
name
&&
child
->
get_tag
(
"xmlns"
)
==
xmlns
)
return
child
;
}
return
nullptr
;
}
std
::
vector
<
XmlNode
*>
XmlNode
::
get_children
(
const
std
::
string
&
name
,
const
std
::
string
&
xmlns
)
const
{
std
::
vector
<
XmlNode
*>
res
;
for
(
auto
&
child
:
this
->
children
)
{
if
(
child
->
name
==
name
&&
child
->
get_tag
(
"xmlns"
)
==
xmlns
)
res
.
push_back
(
child
);
}
return
res
;
}
XmlNode
*
XmlNode
::
add_child
(
XmlNode
*
child
)
{
child
->
parent
=
this
;
this
->
children
.
push_back
(
child
);
return
child
;
}
XmlNode
*
XmlNode
::
add_child
(
XmlNode
&&
child
)
{
XmlNode
*
new_node
=
new
XmlNode
(
std
::
move
(
child
));
return
this
->
add_child
(
new_node
);
}
XmlNode
*
XmlNode
::
get_last_child
()
const
{
return
this
->
children
.
back
();
}
void
XmlNode
::
close
()
{
if
(
this
->
closed
)
throw
std
::
runtime_error
(
"Closing an already closed XmlNode"
);
this
->
closed
=
true
;
}
XmlNode
*
XmlNode
::
get_parent
()
const
{
return
this
->
parent
;