Fork of tus-node-server, with edits from my own work in tus-express added.
tus is a new open protocol for resumable uploads built on HTTP. This is the tus protocol 1.0.0 node.js server implementation. This repo is adapted to fit some use cases in Express. Feel free to let me know if you have any comments or feedback!
You can provide a list of options to the handler functions:
- HEAD allows 'onError'
- PATCH allows 'onSuccess', 'onError'.
- POST allows 'filename', 'onSuccess', 'onError'
[...]
const tus = require('tus-node-server');
const server = new tus.Server();
server.datastore = new tus.FileStore({
directory: 'files/videos/user-uploads',
path: '/api/videos/tus-upload'
});
var app = express();
app.post('/api/videos/tus-upload', function(req, res) {
server.handle(req, res, {
filename: '50554d63-29bb-11e5-b345-feff819cdc9f',
onSuccess (fileName, filePath, done) {
Users.save({ user: req.user, uploads: [filePath] });
// 'done' MUST be called.
done();
}
});
});
app.all('/api/videos/tus-upload/*', function(req, res) {
server.handle(req, res, {
onError (err, statusCode) {
console.error(err);
// The response must be ended if
// using a custom error handler.
// If a custom error handler is not
// defined for a handler, tus-node-server
// will end the response and take care
// of the status codes consistent with
// the protocol.
res.sendStatus(statusCode);
}
});
});
[...]
- Build a standalone server (in original repo)
- Deploy tus-node-server as Express middleware (in original repo)
- Custom file directories (new)
- Custom file names (new)
- Execute callbacks (new)
- Use 'Upload-Metadata' header (new)
const tus = require('tus-node-server');
const server = new tus.Server();
server.datastore = new tus.FileStore({
path: '/files'
});
const host = '127.0.0.1';
const port = 8000;
server.listen({ host, port }, () => {
console.log(`[${new Date().toLocaleTimeString()}] tus server listening at http://${host}:${port}`);
});
Alternatively, you could deploy tus-node-server as Express Middleware
const tus = require('tus-node-server');
const server = new tus.Server();
server.datastore = new tus.FileStore({
path: '/files'
});
var app = express();
app.all('/files/*', function(req, res) {
server.handle(req, res);
});
app.listen(port, host);
Specify a directory to save your files. If 'directory' is not specified, then FileStore will just use 'path' as the file directory, saving uploads to /your/project/directory/api/videos/tus-upload
.
[...]
const tus = require('tus-node-server');
const server = new tus.Server();
server.datastore = new tus.FileStore({
directory: 'files/videos/user-uploads',
path: '/api/videos/tus-upload'
});
var app = express();
app.all('/api/videos/tus-upload/*', function(req, res) {
server.handle(req, res);
});
[...]
It may sometimes be necessary to use a custom file name to stay consistent with other parts of your application. Now you can pass in the filename when creating a new file.
[...]
const tus = require('tus-node-server');
const server = new tus.Server();
server.datastore = new tus.FileStore({
directory: 'files/videos/user-uploads',
path: '/api/videos/tus-upload'
});
var app = express();
app.post('/api/videos/tus-upload', function(req, res) {
server.handle(req, res, {
filename: '50554d63-29bb-11e5-b345-feff819cdc9f'
});
});
app.all('/api/videos/tus-upload/*', function(req, res) {
server.handle(req, res);
});
[...]
You may want to provide callbacks to execute stuff when the main operations are over.
[...]
app.patch('/api/videos/tus-upload/:fileId', function(req, res) {
server.handle(req, res, {
onSuccess (fileName, filePath, done) {
// Do stuff here
// ...and maybe some async stuff
database.ping((err, res) => {
if (err) console.error(err);
else {
console.log('Hey');
// 'done' MUST be called.
done();
}
});
}
});
});
app.all('/api/videos/tus-upload/*', function(req, res) {
server.handle(req, res);
});
[...]
The client can send an 'Upload-Metadata' header to send miscellaneous metadata (like filenames). See here for more details.
$ curl -X POST -I 'http://localhost:1337/files/' \
-H 'Tus-Resumable: 1.0.0' \
-H 'Upload-Length: 55109624' \
-H 'Upload-Metadata: filename bXktY29vbC12aWRlbw=='
HTTP/1.1 201 Created
Tus-Resumable: 1.0.0
Location: http://localhost:1337/files/my-cool-video
$ curl -X HEAD -I 'http://localhost:1337/files/my-cool-video' \
-H 'Tus-Resumable: 1.0.0'
HTTP/1.1 200 OK
Tus-Resumable: 1.0.0
Upload-Offset: 0
Upload-Length: 55109624
Upload-Metadata: {"filename":"my-cool-video"}