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.

Details

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 "upload.example.org" "http_file_share"

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

Discovery

If, in the above example, your VirtualHost is not the parent domain of the component, i.e. example.org, 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 = {
    { "upload.example.org", "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 "upload.example.org" "http_file_share"
http_file_share_size_limit = 16*1024*1024 -- 16 MiB

Daily quotas

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

Component "upload.example.org" "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.

Access

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 "upload.example.org" "http_file_share"
http_file_share_access = {
    "filesharingenthusiast@example.net", -- this specifc user
    "example.org", -- anyone with a @example.org address
}

Restricting file types

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

Component "images.example.org" "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 "upload.example.org" "http_file_share"
http_file_share_secret = "U2VjcmV0VG9rZW4wMzYz"
http_file_share_base_url = "https://share.example.com/upload.php/"

Configuration

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" : "user@example.com"
   "expires" : 1612717960,
}

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

slot
Unique identifier for this upload.
iat
UNIX timestamp of when the token was issued.
exp
UNIX timestamp after which the token should be considered expired.
sub
Identity of the uploader, for per-user quotas.
filename
Name of the file being upload.
filesize
Size of the file, in bytes. Ensure this matches the size of the upload.
filetype
MIME type of the file. Ensure this is the content type the file is served with.
expires
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.
    eyJmaWxlbmFtZSI6InBpY3R1cmUucG5nIiwic2xvdCI6IlJWYktBZ1dQ
    Y3JVWUFvZGoiLCJmaWxlc2l6ZSI6NzE2OCwiZXhwIjoxNjEyMTEzNDYw
    LCJzdWIiOiJ1c2VyQGV4YW1wbGUuY29tIiwiZmlsZXR5cGUiOiJpbWFn
    ZS9wbmcifQ.7iiwBKcxCSx-UJQaVmj3CpYvIAve4SCmGJwiw4Fmjgc

< FILE CONTENT FOLLOWS >

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.