2. HTTP File Upload component
Tigase’s HTTP File Upload component is an implementation of XEP-0363 HTTP File Upload specification. This allows file transfer between XMPP clients by uploading a file to HTTP server and sending only link to download file to recipient.
This implementation makes use of the HTTP server used by Tigase XMPP Server and Tigase HTTP API component to provide web server for file upload and download.
By default this component is disabled and needs to be enabled in configuration file before it can be used. Another requirement is that the proper database schema needs to be applied to database which will be used by component.
2.1. Enabling HTTP File Upload Component
Configuration.
upload() {}
2.2. Metadata repository
Running the component requires a repository where it can store information about allocated slots. For this, a metadata repository is used. It is possible to specify a specific implementation of FileUploadRepository
for every domain.
By default, metadata for all domains will be stored in the default
repository. Implementation of which will be selected based on kind of data source defined as default
.
2.2.1. DummyFileUploadRepository
This is very simple repository which does not store any data. Due to that, it can be very fast! However, it is not able to remove old uploads and apply any upload limits.
2.2.2. JDBCFileUploadRepository
This repository implementation stores data in database used to store procedures and functions. By default, data should be stored in the tig_hfu_slots
table but it can be changed by modification of stored procedures or reconfiguration of the repository implementation to use different stored procedures and functions than provided.
2.3. Storage
Component contains a pluggable storage mechanism, which means that it is relatively easy to implement custom storage provisions. By default DirectoryStore
based storage is used.
Currently following storage providers are available out of the box.
2.3.1. DirectoryStore
This storage mechanism places files in subdirectories with names that correspond to the id of allocated slot. If required, it is possible to group all slot directories allocated by single user in a directory containing this user name.
By default there is no redundancy if this store is used in clustered environment. Every file will be stored on a single cluster node.
Available properties:
- path
Contains path to directory in which subdirectory with files will be created on the local machine. (default: ``data/upload``)
- group-by-user
Configures if slots directories should be grouped in user directories. (default: false)
2.4. Logic
Logic is responsible for generation of URI and applying limits. It groups all configuration settings related to allocation of slots, etc.
Available properties:
- local-only
Allow only users with accounts on the local XMPP server to use this component for slot allocation. (default: true)
- max-file-size
Set maximum size of a single allocated slot (maximum file size) in bytes. (default: 5000)
- port
Specifies the port which should be used in generating the upload and download URI. If it is not set, then secured (HTTPS) server port will be used if available, and plain HTTP in other case. (default: not set)
- protocol
Protocol which should be used. This is only used in conjunction with ``port``. Possible values are:
http
https
- serverName
Server name to use as domain part in generated URI. (default: server hostname)
- upload-uri-format
Template used in generation of URI for file upload. (default: ``{proto}://{serverName}:{port}/upload/{userJid}/{slotId}/{filename}``)
- download-uri-format
Template used in generation of URI for file download. (default: ``{proto}://{serverName}:{port}/upload/{slotId}/{filename}``)
2.4.1. URI template format
Every block in the template between {
and }
is a named part which will be replaced by the property value during generation of URI for slot.
Blocks possible to use:
- proto
Name of protocol.
- serverName
Domain name of server.
- port
Port on which HTTPS (or HTTP) server is listening.
- userJid
JID of user requesting slot allocation.
- domain
Domain of user requesting slot allocation.
- slotId
Generated ID of slot.
- filename
Name of file to upload.
Note
slotId
and filename
are required to be part of every URI template.
Warning
Inclusion of userJid
or domain
will speed up the lookup for slot id during upload and download operation if more than one metadata repository is configured. However, this may lead to leak of user JID or user domain if message with URI containing this part will be send to recipient which is unaware of the senders’ JID (ie. in case of anonymous MUC room).
2.5. File upload expiration
From time to time it is required to remove expired file to make place for new uploads. This is done by the expiration
task.
Available properties:
- expiration-time
How long the server will keep uploaded files. Value in Java Period format (default: P30D - 30 days)
- period
How often the server should look for expired files to remove. Value in Java Period format (default: P1D - 1 day)
- delay
Time since server start up before the server should look for expired files to remove. Value in Java Period format (default: 0)
- limit
Maximum number of files to remove during a single execution of
expiration
. (default: 10000)
2.6. Examples
2.6.1. Complex configuration example
Configuration with a separate repository for metadata to example.com
pointing to file_upload
data source, custom upload and download URI, maximum file size set to 10MB, expiration done every 6 hours and grouping of slot folders by user jid.
Complex configuration example.
upload() {
logic {
'local-only' = false
'max-file-size' = 10485760
'upload-uri-format' = '{proto}://{serverName}:{port}/upload/{userJid}/{slotId}/{filename}'
'download-uri-format' = '{proto}://{serverName}:{port}/upload/{domain}/{slotId}/{filename}'
}
expiration {
'period' = P6H
}
repositoryPool {
'example.com' () {
'data-source' = "file_upload"
}
}
store {
'group-by-user' = true
}
}
2.6.2. Example configuration for clustering with HA
Configuration for high availability in a cluster with common storage at /mnt/shared
and both servers available as upload.example.com
Example configuration with HA.
upload() {
logic {
'upload-uri-format' = '{proto}://upload.example.com:{port}/upload/{userJid}/{slotId}/{filename}'
'download-uri-format' = '{proto}://upload.example.com:{port}/upload/{domain}/{slotId}/{filename}'
}
store {
path = '/mnt/shared/upload'
}
}
2.7. S3 support for HTTP File Upload
By default HTTP File Upload component shipped with Tigase XMPP Server stores uploaded files locally in the directory structure. If you are using AWS it may be better to store data using external service like S3 which are better suited for this task and are more resilient.
Note
For this feature to work please make sure that you are using all required dependencies (either by using -dist-max
package or obtaining them from tigase-extras aws module)
2.7.1. Enabling storage in S3
To enable storage in S3, you need to add following lines to your configuration file:
upload () {
store (class: tigase.extras.http.upload.S3Store, active: true, exportable: true) {
bucket = 'bucket-name'
}
}
This will enable HTTP File Upload component and configure it to be used with S3 bucket named bucket-name
in the same region as your EC2 instance on which Tigase XMPP Server is running.
Warning
You would need to manually create this S3 bucket and allow your EC2 instance to access it (read and write). Alternatively, you could add autocreateBucket = true
inside store
block, which will enable Tigase XMPP Server to create this S3 bucket in the local AWS region.
If you wish to use S3 bucket from another AWS region, you can do that by adding setting region
property in the store
block to the id of the AWS region, ie. set to us-west-2
to use US West (Oregon)
region:
upload () {
store (class: tigase.extras.http.upload.S3Store, active: true, exportable: true) {
bucket = 'bucket-name'
region = 'us-west-2'
}
}
If you wish to share the same S3 bucket between different installations of Tigase XMPP Server, you should configure bucketKeyPrefix
property of store
with different identifiers for each installation. That will allow you to easily filter data uploaded for each installation and will allow Tigase XMPP Server to provide you with correct storage usage for each installation.
upload () {
store (class: tigase.extras.http.upload.S3Store, active: true, exportable: true) {
bucket = 'bucket-name'
bucketKeyPrefix = '45252AF'
}
}
S3Store requires appropriate IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListStorageLensConfigurations",
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:CreateBucket",
"s3:GetBucketLocation"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::bucket-name",
"arn:aws:s3:::bucket-name/*",
"arn:aws:s3:*:441807014745:accesspoint/*",
"arn:aws:s3:*:441807014745:storage-lens/*",
"arn:aws:s3:*:441807014745:job/*"
]
}
]
}