summaryrefslogtreecommitdiff
path: root/src/xmpp/jid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp/jid.cpp')
-rw-r--r--src/xmpp/jid.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/xmpp/jid.cpp b/src/xmpp/jid.cpp
index 29a5302..4f9917b 100644
--- a/src/xmpp/jid.cpp
+++ b/src/xmpp/jid.cpp
@@ -1,4 +1,12 @@
#include <xmpp/jid.hpp>
+#include <config.h>
+#include <cstring>
+
+#ifdef LIBIDN_FOUND
+ #include <stringprep.h>
+#endif
+
+#include <logger/logger.hpp>
Jid::Jid(const std::string& jid)
{
@@ -19,3 +27,41 @@ Jid::Jid(const std::string& jid)
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
+ // TODO: cache the result
+ 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 "";
+ }
+
+ return std::string(local) + "@" + domain;
+#else
+ (void)original;
+ return "";
+#endif
+}