XEP-0363 - File Upload for XMPP Chat

NethServer Version: 7.7.1908
Module: Chat

Does this module support XEP-0363 for File Upload? If not, is there a guide on how to enable this feature?

The module uses ejabberd which supports XEP-0363, but I think it is not enabled by default in ejabberd.yml
https://docs.ejabberd.im/admin/configuration/#mod-http-upload
https://xmpp.org/extensions/xep-0363.html

If you want to edit ejabberd.yml, take into account that the file is templated.

(Note: I’ve no experience with ejabberd so my knowledge on it is limited)

After lots of digging I was able to get this module working on my server by hacking away at the ejabberd.yml file, and then I even got it working with the templating system.

basically, the following needs to get added into the config in the listeners:

  -
    port: 5443
    module: ejabberd_http
    tls: true
    request_handlers:
        "": mod_http_upload

and in the mods section:

mod_http_upload:
   docroot: "/opt/ejabberd/uploads/"
   put_url: "https://xmpp.myDomain.com:5443/upload"

My scenario is not “standard”, but I think it is one that most will want. ejabberd is not installed on the TLD (mydomain.com) but is instead installed on a sub-domain. Nethserver REQUIRES that it be a sub-domain anyway, and I doubt everyone wants their XMPP names to be: me@neth.mydomain.com or me@chat.mydomain.com. XMPP supports DNS records to point usernames like me@mydomain.com to the real jabber server somewhere else (like xmpp.mydomain.com). You can read more about that here: https://wiki.xmpp.org/web/SRV_Records

Now that we know the working configuration we need to transform it to Nethserver’s template system.

Create some settings

I created some settings with the hope that we can put them in the UI later:

db configuration setprop ejabberd ModHttpUploadStatus enabled ModHttpUploadPutUrl https://xmpp.myDomain.com:5443/upload

Make some custome templates

There are two templates we need to touch: 40Listen and we also need to add our own custom template, for me I went with 86ModulesHttpModUpload

According to the documentation, we need to make our own templates in: /etc/e-smith/templates-custom/etc/ejabberd/ejabberd.yml/. Unfortunately, we have to do a full replace of the 40Listen because the current implementation of S2S puts a non-listener line at the end of the listeners, so we can’t just add a template after it with the normal Nethserver template convention.

First we need to make the custom template directly (the whole hierarchy) if it doesn’t already exist:
mkdir -p /etc/e-smith/templates-custom/etc/ejabberd/ejabberd.yml

This is what I did to the 40Listen template:
cp /etc/e-smith/templates/etc/ejabberd/ejabberd.yml/40Listen /etc/e-smith/templates-custom/etc/ejabberd/ejabberd.yml/40Listen

and add in:

{
if ($ejabberd{'ModHttpUploadStatus'} eq 'enabled') {
$OUT .= q(  -
    port: 5443
    module: ejabberd_http
    tls: true
    request_handlers:
      "": mod_http_upload);
}
}

Then I made the 86ModulesHttpModUpload template with:
touch /etc/e-smith/templates-custom/etc/ejabberd/ejabberd.yml/86ModulesHttpModUpload

and added in:

{
if ($ejabberd{'ModHttpUploadStatus'} eq 'enabled'){
    $OUT .= qq(
  mod_http_upload:
   docroot: "/opt/ejabberd/uploads/"
   put_url: "$ejabberd{'ModHttpUploadPutUrl'}"
);
}
}

Note that the qq is purposely not a q function because we need Perl to parse our upload config variable.

Regenerate the configuration file

Now that we have made our customizations we need to regenerate the template and see how it looks:
expand-template /etc/ejabberd/ejabberd.yml

Open up the port

I’m still not quite sure how to edit the service ports and get them to propagate so I added the port directly in the defaults, and also updated the service configuration directly (it was getting late, forgive me!)

echo -n ',5443' >> /etc/e-smith/db/configuration/defaults/ejabberd/TCPPorts

the -n is important because otherwise it will add a new line between the existing ports and the new one. Since this file doesn’t have a new line and it looks like it’s compiled into a one-line command, I assume the extra new line would be disastrous.

Now we update the ports:
config setprop ejabberd TCPPorts 5222,5223,5269,5280,5443

Set the ownership of the uploads folder

Last but not least, we need to make the uploads folder and make sure it’s owned by the ejabberd user:
chown ejabberd:ejabberd /opt/ejabberd/uploads

Trigger reconfiguring the service

Now that we have our configuration generated, our port opened, our upload folder ready, we can tell Nethserver to reconfigure the services:
signal-event runlevel-adjust

Summary

I hope this helps someone else.

I’m sure many things I have done do not align to the Nethserver way of doing things. Please feel free to guide me in the right direction. :slight_smile:

To do:

  1. Check if this is really the best practice for mod_http_upload. It seems to me that the URL it generates is not secured (but is long and unique, so that’s security through obscurity). I’m not sure if ejabberd can further secure it somehow, or if this is just the trade-off.
  2. Improve the 40Listen template so that the S2S configuration is in a separate file to allow additional modules to be added on just by creating a custom template, and not requiring a full replace of this file. I suggest breaking the S2S part into 42ListenS2S to allow people to add their own modules like 41ListenMyListener
  3. Maybe we need to make the port configurable to avoid conflicting with any other existing services?
3 Likes

hi all

I am implementing this http_upload feature with ejabberd_20.01, I cannot make it workable with pidgin, even if it works out o the box with an android client … some clues how to configure pidgin ?

EDIT: it works OTB with Gajim fun, but not with dino

You are right that Pidgin does not support it. There is some 3rd party plugin that was compiled for it a while ago, and I think it was only for Linux. In general, Pidgin support for XMPP is pretty pathetic.

1 Like