All Projects → ThomasLeister → prosody-filer

ThomasLeister / prosody-filer

Licence: MIT license
Golang mod_http_upload_external server for Prosody and Ejabberd

Programming Languages

go
31211 projects - #10 most used programming language
shell
77523 projects
Dockerfile
14818 projects

Projects that are alternatives of or similar to prosody-filer

Chat Sdk Ios
Chat SDK iOS - Open Source Mobile Messenger
Stars: ✭ 813 (+1882.93%)
Mutual labels:  messaging, xmpp
Mongooseim
MongooseIM is a mobile messaging platform with focus on performance and scalability
Stars: ✭ 1,387 (+3282.93%)
Mutual labels:  messaging, xmpp
Jackal
Instant messaging server for the Extensible Messaging and Presence Protocol (XMPP).
Stars: ✭ 899 (+2092.68%)
Mutual labels:  messaging, xmpp
Quickblox Ios Sdk
QuickBlox iOS SDK for messaging and video calling
Stars: ✭ 373 (+809.76%)
Mutual labels:  messaging, xmpp
Tigase Server
Highly optimized, extremely modular and very flexible XMPP/Jabber server
Stars: ✭ 170 (+314.63%)
Mutual labels:  messaging, xmpp
Ejabberd
Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
Stars: ✭ 5,077 (+12282.93%)
Mutual labels:  messaging, xmpp
Quickblox Javascript Sdk
JavaScript SDK of QuickBlox cloud backend platform
Stars: ✭ 98 (+139.02%)
Mutual labels:  messaging, xmpp
Qmchatviewcontroller Ios
An elegant ready to go chat view controller for iOS applications
Stars: ✭ 75 (+82.93%)
Mutual labels:  messaging, xmpp
Mnm
The legitimate email replacement — n-identity, decentralized, store-and-forward, open protocol, open source. (Server)
Stars: ✭ 162 (+295.12%)
Mutual labels:  messaging, xmpp
Q Municate Ios
Q-municate iOS repository
Stars: ✭ 164 (+300%)
Mutual labels:  messaging, xmpp
Chatsecure Ios
ChatSecure is a free and open source encrypted chat client for iOS that supports OTR and OMEMO encryption over XMPP.
Stars: ✭ 3,044 (+7324.39%)
Mutual labels:  messaging, xmpp
django-sitemessage
Reusable application for Django introducing a message delivery framework
Stars: ✭ 51 (+24.39%)
Mutual labels:  messaging, xmpp
mod push appserver
Simple and extendable appserver for XMPP pushes (aka. XEP-0357)
Stars: ✭ 24 (-41.46%)
Mutual labels:  xmpp, prosody
Chat
Instant messaging platform. Backend in Go. Clients: Swift iOS, Java Android, JS webapp, scriptable command line; chatbots
Stars: ✭ 8,238 (+19992.68%)
Mutual labels:  messaging, xmpp
Chat Sdk Android
Chat SDK Android - Open Source Mobile Messenger
Stars: ✭ 1,496 (+3548.78%)
Mutual labels:  messaging, xmpp
Lurch
XEP-0384: OMEMO Encryption for libpurple.
Stars: ✭ 245 (+497.56%)
Mutual labels:  messaging, xmpp
mnm-hammer
mnm implements TMTP protocol. Let Internet sites message members directly, instead of unreliable, insecure email. Contributors welcome! (Client)
Stars: ✭ 66 (+60.98%)
Mutual labels:  messaging, xmpp
blaster
Web hooks for message queues
Stars: ✭ 14 (-65.85%)
Mutual labels:  messaging
q-municate-web
Q-municate Web chat application
Stars: ✭ 66 (+60.98%)
Mutual labels:  xmpp
myprosody
A Python library for measuring the acoustic features of speech (simultaneous speech, high entropy) compared to ones of native speech.
Stars: ✭ 162 (+295.12%)
Mutual labels:  prosody

Prosody Filer

A simple file server for handling XMPP http_upload requests. This server is meant to be used with the Prosody mod_http_upload_external module.

Despite the name, this server is also compatible with Ejabberd and Ejabberd's http_upload module!


Why should I use this server?

  • Prosody developers recommend using http_upload_external instead of http_upload (Matthew Wild on the question if http_upload is memory leaking):

    "BTW, I am not aware of any memory leaks in the HTTP upload code. However it is known to be very inefficient. That's why it has a very low upload limit, and we encourage people to use mod_http_upload_external instead. We set out to write a good XMPP server, not HTTP server (of which many good ones already exist), so our HTTP server is optimised for small bits of data, like BOSH and websocket. Handling large uploads and downloads was not a goal (and implementing a great HTTP server is not a high priority for the project compared to other things). Our HTTP code buffers the entire upload into memory. More, it does it in an inefficient way that can use up to 4x the actual size of the data (if the data is large). So uploading a 10MB file can in theory use 40MB RAM. But it's not a leak, the RAM is later cleared and reused. [...] The GC will free the memory at some point, but the OS may still report that Prosody is using that memory due to the way the libc allocator works. Most long lived processes behave this way (only increasing RAM, rarely decreasing)."

  • This server works without any script interpreters or additional dependencies. It is delivered as a binary.
  • Go is very good at serving HTTP requests and "made for this task".

Download

If you are using regular x86_64 Linux, you can download a finished binary for your system on the release page. No need to compile this application yourself.

Build (optional)

If you're using something different than a x64 Linux, you need to compile this application yourself.

To compile the server, you need a full Golang development environment. This can be set up quickly: https://golang.org/doc/install#install

Then checkout this repo:

go get github.com/ThomasLeister/prosody-filer

and switch to the new directory:

cd $GOPATH/src/github.com/ThomasLeister/prosody-filer

The application can now be build:

### Build static binary
./build.sh

### OR regular Go build
go build main.go

Set up / configuration

Setup Prosody Filer environment

Create a new user for Prosody Filer to run as:

adduser --disabled-login --disabled-password prosody-filer

Switch to the new user:

su - prosody-filer

Copy

  • the binary prosody-filer and
  • config config.example.toml

to /home/prosody-filer/. Rename the configuration to config.toml.

Make sure the prosody-filer binary is executable:

chmod u+x prosody-filer

Configure Prosody

Back in your root shell make sure mod_http_upload is disabled and mod_http_upload_external is enabled! Then configure the external upload module:

http_upload_external_base_url = "https://uploads.myserver.tld/upload/"
http_upload_external_secret = "mysecret"
http_upload_external_file_size_limit = 50000000 -- 50 MB

Restart Prosody when you are finished:

systemctl restart prosody

Alternative: Configure Ejabberd

Although this tool is named after Prosody, it can be used with Ejabberd, too! Make sure you have a Ejabberd configuration similar to this:

  mod_http_upload:
    put_url: "https://uploads.@HOST@/upload"
    external_secret: "mysecret"
    max_size: 52428800

Configure Prosody Filer

Prosody Filer configuration is done via the config.toml file in TOML syntax. There's not much to be configured:

### IP address and port to listen to, e.g. "[::]:5050"
listenport      = "[::1]:5050"

### Secret (must match the one in prosody.conf.lua!)
secret          = "mysecret"

### Where to store the uploaded files
storeDir        = "./upload/"

### Subdirectory for HTTP upload / download requests (usually "upload/")
uploadSubDir    = "upload/"

Make sure mysecret matches the secret defined in your mod_http_upload_external settings!

In addition to that, make sure that the nginx user or group can read the files uploaded via prosody-filer if you want to have them served by nginx directly.

Docker usage

To build container:

docker build . -t prosody-filer:latest

To run container use:

docker run -it --rm -v $PWD/config.example.toml:/config.toml prosody-filer -config /config.toml

Systemd service file

Create a new Systemd service file: /etc/systemd/system/prosody-filer.service

[Unit]
Description=Prosody file upload server

[Service]
Type=simple
ExecStart=/home/prosody-filer/prosody-filer
Restart=always
WorkingDirectory=/home/prosody-filer
User=prosody-filer
Group=prosody-filer
# Group=nginx  # if the files should get served by nginx directly:

[Install]
WantedBy=multi-user.target

Reload the service definitions, enable the service and start it:

systemctl daemon-reload
systemctl enable prosody-filer
systemctl start prosody-filer

Done! Prosody Filer is now listening on the specified port and waiting for requests.

Configure Nginx

Create a new config file /etc/nginx/sites-available/uploads.myserver.tld:

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name uploads.myserver.tld;

    ssl_certificate /etc/letsencrypt/live/uploads.myserver.tld/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/uploads.myserver.tld/privkey.pem;

    client_max_body_size 50m;

    location /upload/ {
        if ( $request_method = OPTIONS ) {
                add_header Access-Control-Allow-Origin '*';
                add_header Access-Control-Allow-Methods 'PUT, GET, OPTIONS, HEAD';
                add_header Access-Control-Allow-Headers 'Authorization, Content-Type';
                add_header Access-Control-Allow-Credentials 'true';
                add_header Content-Length 0;
                add_header Content-Type text/plain;
                return 200;
        }

        proxy_pass http://[::]:5050/upload/;
        proxy_request_buffering off;
    }
}

Enable the new config:

ln -s /etc/nginx/sites-available/uploads.myserver.tld /etc/nginx/sites-enabled/

Check Nginx config:

nginx -t

Reload Nginx:

systemctl reload nginx

Alternative configuration for letting Nginx serve the uploaded files

(not officially supported - user contribution!)

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name uploads.myserver.tld;

    ssl_certificate /etc/letsencrypt/live/uploads.myserver.tld/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/uploads.myserver.tld/privkey.pem;

    location /upload/ {
        if ( $request_method = OPTIONS ) {
                add_header Access-Control-Allow-Origin '*';
                add_header Access-Control-Allow-Methods 'PUT, GET, OPTIONS, HEAD';
                add_header Access-Control-Allow-Headers 'Authorization, Content-Type';
                add_header Access-Control-Allow-Credentials 'true';
                add_header Content-Length 0;
                add_header Content-Type text/plain;
                return 200;
        }

        root /home/prosody-filer;
        autoindex off;
        client_max_body_size 51m;
        client_body_buffer_size 51m;
        try_files $uri $uri/ @prosodyfiler;
    }
    location @prosodyfiler {
        proxy_pass http://[::1]:5050;
        proxy_buffering off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}

apache2 configuration (alternative to Nginx)

(This configuration was provided by a user and has never been tested by the author of Prosody Filer. It might be outdated and might not work anymore)

<VirtualHost *:80>
    ServerName upload.example.eu
    RedirectPermanent / https://upload.example.eu/
</VirtualHost>

<VirtualHost *:443>
    ServerName upload.example.eu
    SSLEngine on

    SSLCertificateFile "Path to the ca file"
    SSLCertificateKeyFile "Path to the key file"

    Header always set Public-Key-Pins: ''
    Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
    H2Direct on

    <Location /upload>
        Header always set Access-Control-Allow-Origin "*"
        Header always set Access-Control-Allow-Headers "Content-Type"
        Header always set Access-Control-Allow-Methods "OPTIONS, PUT, GET"

        RewriteEngine On

        RewriteCond %{REQUEST_METHOD} OPTIONS
        RewriteRule ^(.*)$ $1 [R=200,L]
    </Location>

    SSLProxyEngine on

    ProxyPreserveHost On
    ProxyRequests Off
    ProxyPass / http://localhost:5050/
    ProxyPassReverse / http://localhost:5050/
</VirtualHost>

Automatic purge

Prosody Filer has no immediate knowlegde over all the stored files and the time they were uploaded, since no database exists for that. Also Prosody is not capable to do auto deletion if mod_http_upload_external is used. Therefore the suggested way of purging the uploads directory is to execute a purge command via a cron job:

@daily    find /home/prosody-filer/upload/ -mindepth 1 -type d -mtime +28 -print0 | xargs -0 -- rm -rf

This will delete uploads older than 28 days.

Check if it works

Get the log via

journalctl -f -u prosody-filer

If your XMPP clients uploads or downloads any file, there should be some log messages on the screen.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].