mod_http_file_share XEP-0363: HTTP File Upload

Allow users to share files, such as pictures, videos and audio clips, by uploading them to the server, giving them an URL to pass on to one or more recipients.

This module is not yet included with Prosody, it’s currently only available in trunk builds and will be in the next major release.


mod_http_file_share implements XEP-0363: HTTP File Upload and supports using either Prosody’s built-in HTTP server or an external upload service.

Getting started

Simply add the following at the end of your config:

Component "" "http_file_share"

That’s it! Restart Prosody and try to share something!


If, in the above example, your VirtualHost is not the parent domain of the component, i.e., but something else, like chat.domain.example then you will need to specify that the component should be discoverable by setting:

VirtualHost "chat.domain.example"
disco_items = {
    { "", "file sharing service (this name is optional)" },

Larger files

Users wanting to share even larger files? The size limit can be increased with the http_file_share_size_limit setting.

Component "" "http_file_share"
http_file_share_size_limit = 16*1024*1024 -- 16 MiB

Daily quotas

The daily quota is a limit that prevents users from uploading more files if more than a certain amount of bytes have been uploaded during the last 24 hours.

Component "" "http_file_share"
http_file_share_daily_quota = 100*1024*1024 -- 100 MiB per day per user

Thus with the above configuration and one week retention, each user could store up to 700 MiB each.

Once this limit has been reached they must wait until at least one upload to become more than 24 hours old.

Global quota

Since it’s not always easy to estimate how much storage space will be needed, i.e. because the number of users may change which would increase the total theoretical usage by another 700 MiB (in the example from the previous section).

Component "" "http_file_share"
http_file_share_global_quota = 1024*1024*1024 -- 1 GiB total

With such configuration, the total size of all uploaded files will not be allowed to exceed 1 GiB.


Any local user on the same Prosody instance is allowed to use the upload service by default. The http_file_share_access setting can be specified to limit access to certain users or hosts, including hosts on other servers. Be careful!

Component "" "http_file_share"
http_file_share_access = {
    "", -- this specifc user
    "", -- anyone with a address

Restricting file types

Only want to serve images? Say so with the http_file_share_allowed_file_types setting.

Component "" "http_file_share"
http_file_share_allowed_file_types = { "image/*" }

Using a separate HTTP upload service

To use an external upload service, specify the base URL of via http_file_share_base_url and configure a strong shared secret via http_file_share_secret, which must also be specified in the configuration of the external upload service.

Component "" "http_file_share"
http_file_share_secret = "U2VjcmV0VG9rZW4wMzYz"
http_file_share_base_url = ""


All settings

Setting type default note
http_file_share_size_limit number 10*1024*1024 10 MiB
http_file_share_daily_quota number 10x the size limit 100 MiB
http_file_share_allowed_file_types set {} Access control
http_file_share_safe_file_types set {"image/*","video/*","audio/*","text/plain"} Safe to show in-line in e.g. browsers
http_file_share_expires_after number 7 * 86400 One week
http_file_share_access set {} Access control
http_file_share_base_url string unset Base URL of external upload service
http_file_share_secret string random External upload service

External upload protocol details

The external protocol works by passing various details in a JSON Web Token in an Authorization header.

Example payload:

   "iat" : 1612113160,
   "exp" : 1612113460,
   "filename" : "picture.png",
   "filesize" : 7168,
   "filetype" : "image/png",
   "slot" : "RVbKAgWPcrUYAodj",
   "sub" : ""
   "expires" : 1612717960,

This is normally signed with the HS256 algorithm (HMAC-SHA-256). The fields are as follows:

Unique identifier for this upload.
UNIX timestamp of when the token was issued.
UNIX timestamp after which the token should be considered expired.
Identity of the uploader, for per-user quotas.
Name of the file being upload.
Size of the file, in bytes. Ensure this matches the size of the upload.
MIME type of the file. Ensure this is the content type the file is served with.
UNIX timestamp after which the file should be considered expired.

Example request (line breaks for readability):

PUT /base_path/RVbKAgWPcrUYAodj/picture.png
Content-Type: image/png
Content-Length: 7168
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.


What data is stored?

For each file uploaded, the following information is stored:

  • File metadata; name, size and file type provided by the client.
  • File data itself.
  • Time when the upload slot was created.
  • Address of the user who requested the upload slot.

File data and metadata is obviously required to download the file again.

User address is needed to apply upload quotas.