tus is a new open protocol for resumable uploads built on HTTP. This is the tus protocol 1.0.0 node.js server implementation.
$ npm install tus-node-serverLocal File Storage
server.datastore=newtus.FileStore({directory: './files'});
Google Cloud Storage
server.datastore=newtus.GCSDataStore({projectId: 'project-id',keyFilename: 'path/to/your/keyfile.json',bucket: 'bucket-name',});
Amazon S3
server.datastore=newtus.S3Store({bucket: 'bucket-name',accessKeyId: 'access-key-id',secretAccessKey: 'secret-access-key',region: 'eu-west-1',partSize: 8*1024*1024,// each uploaded part will have ~8MB,});
Use the tus-node-deploy Docker image
$ docker run -p 1080:8080 -d bhstahl/tus-node-deployconsttus=require('tus-node-server');constserver=newtus.Server({path: '/files'});server.datastore=newtus.FileStore({directory: './files'});consthost='127.0.0.1';constport=1080;server.listen({ host, port },()=>{console.log(`[${newDate().toLocaleTimeString()}] tus server listening at http://${host}:${port}`);});Use tus-node-server as Express Middleware
consttus=require('tus-node-server');constserver=newtus.Server({path: '/files'});server.datastore=newtus.FileStore({directory: './files'});constexpress=require('express');constapp=express();constuploadApp=express();uploadApp.all('*',server.handle.bind(server));app.use('/uploads',uploadApp);consthost='127.0.0.1';constport=1080;app.listen(port,host);Use tus-node-server with Koa or plain Node server
consthttp=require('http');consturl=require('url');constKoa=require('koa')consttus=require('tus-node-server');consttusServer=newtus.Server({path: '/files'});tusServer.datastore=newtus.FileStore({directory: './files'});constapp=newKoa();constappCallback=app.callback();constport=1080;constserver=http.createServer((req,res)=>{consturlPath=url.parse(req.url).pathname;// handle any requests with the `/files/*` patternif(/^\/files\/.+/.test(urlPath.toLowerCase())){returntusServer.handle(req,res);}appCallback(req,res);});server.listen(port)Use tus-node-server with Fastify
consttus=require('tus-node-server');consttusServer=newtus.Server({path: '/files'});tusServer.datastore=newtus.FileStore({directory: './files'});constfastify=require('fastify')({logger: true});/** * add new content-type to fastify forewards request * without any parser to leave body untouched * @see https://www.fastify.io/docs/latest/Reference/ContentTypeParser/ */fastify.addContentTypeParser('application/offset+octet-stream',(request,payload,done)=>done(null));/** * let tus handle preparation and filehandling requests * fastify exposes raw nodejs http req/res via .raw property * @see https://www.fastify.io/docs/latest/Reference/Request/ * @see https://www.fastify.io/docs/latest/Reference/Reply/#raw */fastify.all('/files',(req,res)=>{tusServer.handle(req.raw,res.raw);});fastify.all('/files/*',(req,res)=>{tusServer.handle(req.raw,res.raw);});fastify.listen(3000,(err)=>{if(err){fastify.log.error(err);process.exit(1);}});Execute code when lifecycle events happen by adding event handlers to your server.
consttus=require('tus-node-server');constEVENTS=require('tus-node-server').EVENTS;constserver=newtus.Server({path: '/files'});server.datastore=newtus.FileStore({directory: './files'});server.on(EVENTS.EVENT_UPLOAD_COMPLETE,(event)=>{console.log(`Upload complete for file ${event.file.id}`);});EVENT_FILE_CREATED: Fired when aPOSTrequest successfully creates a new fileExample payload:
{ file: { id: '7b26bf4d22cf7198d3b3706bf0379794', upload_length: '41767441', upload_metadata: 'filename NDFfbWIubXA0' } }EVENT_ENDPOINT_CREATED: Fired when aPOSTrequest successfully creates a new upload endpointExample payload:
{ url: 'http://localhost:1080/files/7b26bf4d22cf7198d3b3706bf0379794' }EVENT_UPLOAD_COMPLETE: Fired when aPATCHrequest finishes writing the fileExample payload:
{ file: { id: '7b26bf4d22cf7198d3b3706bf0379794', upload_length: '41767441', upload_metadata: 'filename NDFfbWIubXA0' } }EVENT_FILE_DELETED: Fired when aDELETErequest finishes deleting the fileExample payload:
{ file_id: '7b26bf4d22cf7198d3b3706bf0379794' }
Add custom GET handlers to suit your needs, similar to Express routing.
constserver=newtus.Server({path: '/files'});server.datastore=newtus.FileStore({directory: './files'});server.get('/uploads',(req,res)=>{// Read from your DataStorefs.readdir(server.datastore.directory,(err,files)=>{// Format the JSON response and send it}});The default naming of files is a random crypto hex string. When using your own namingFunction, make sure to create URL friendly names such as removing spaces.
constcrypto=require('crypto');// req is http.IncomingMessageconstrandomString=(req)=>{// same as the default implementationreturncrypto.randomBytes(16).toString('hex');}constserver=newtus.Server({path: '/files',namingFunction: randomString,});Start the demo server using Local File Storage
$ npm run demoOr start up the demo server using Google Cloud Storage
$ npm run gcs_demoThen navigate to the demo (localhost:1080) which uses tus-js-client