JavaScript
Clone or download
Acconut Allow empty values in Upload-Metadata header
Fixes #117

Squashed commit of the following:

commit 1ddbd46abd80d1c39a4e2425b5a9bb002e9609ac
Author: Acconut <maerious@gmail.com>
Date:   Mon Aug 6 14:50:44 2018 +0200

    Cleanup code

commit b0a8d2b
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 18:47:26 2018 +0800

    remove trailing space

commit 5796865
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 18:41:40 2018 +0800

    brace style error

commit 58fd9c8
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 18:32:54 2018 +0800

    if metadata is empty, or only contains spaces, \t, \n, invalid

commit a9abcc2
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 18:29:01 2018 +0800

    if metadata is empty, or only contains spaces, \t, \n, invalid

commit 2f2fc0d
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 18:21:39 2018 +0800

    if metadata is empty, return true; if only contains spaces, \t, \n, return true

commit a819acb
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 17:46:49 2018 +0800

    get back my changes

commit 12cb2f2
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 17:23:28 2018 +0800

    try original code to see if my changes led to the travis CI error

commit fcb895f
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 17:14:52 2018 +0800

    try original code to see if my changes led to the travis CI error

commit 45f30a4
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 17:03:26 2018 +0800

    change test case 3 in line 85 to false since we allow empty metadata

commit f4be763
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 16:59:15 2018 +0800

    change test case 1 in line 83 to false

commit 2749283
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 16:55:36 2018 +0800

    change test case 2 in line 84 to false

commit bbefa75
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 16:41:10 2018 +0800

    bug in if statemetn

commit a428919
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 16:39:45 2018 +0800

    syntax error in if statemetn

commit db394d9
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 16:35:05 2018 +0800

    bug: RequestValidator _invalidUploadMetadataHeader should fail on non comma separated list

commit 07068d2
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 16:14:26 2018 +0800

    fix compiling error: should be 'let i' instead of 'const i'

commit 95c516b
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 16:02:37 2018 +0800

    fix lint errors

commit 324def5
Author: hedj <hedj@i2r.a-star.edu.sg>
Date:   Tue Jul 31 12:46:34 2018 +0800

    allowing empty metadata values in RequestValidator
Latest commit b5ca5c2 Aug 6, 2018

README.md

tus-node-server

npm version Build Status Coverage Status Dependency Status

tus is a new open protocol for resumable uploads built on HTTP. This is the tus protocol 1.0.0 node.js server implementation.

Installation

$ npm install tus-node-server

Flexible Data Stores

  • Local File Storage

    server.datastore = new tus.FileStore({
        path: '/files'
    });
  • Google Cloud Storage

    server.datastore = new tus.GCSDataStore({
        path: '/files',
        projectId: 'project-id',
        keyFilename: 'path/to/your/keyfile.json',
        bucket: 'bucket-name',
    });
  • Amazon S3

    server.datastore = new tus.S3Store({
        path: '/files',
        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,
        tmpDirPrefix: 'tus-s3-store',
    });

Quick Start

Use the tus-node-deploy Docker image

$ docker run -p 1080:8080 -d bhstahl/tus-node-deploy

Build a standalone server yourself

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 = 1080;
server.listen({ host, port }, () => {
    console.log(`[${new Date().toLocaleTimeString()}] tus server listening at http://${host}:${port}`);
});

Use tus-node-server as Express Middleware

const tus = require('tus-node-server');
const server = new tus.Server();
server.datastore = new tus.FileStore({
    path: '/files'
});

const app = express();
const uploadApp = express();
uploadApp.all('*', server.handle.bind(server));
app.use('/uploads', uploadApp);

const host = '127.0.0.1';
const port = 1080;
app.listen(port, host);

Use tus-node-server with Koa or plain Node server

const http = require('http');
const url = require('url');
const Koa = require('koa')
const tus = require('tus-node-server');
const tusServer = new tus.Server();

const app = new Koa();
const appCallback = app.callback();
const port = 1080;

tusServer.datastore = new tus.FileStore({
    path: '/files',
});

const server = http.createServer((req, res) => {
    const urlPath = url.parse(req.url).pathname;

    // handle any requests with the `/files/*` pattern
    if (/^\/files\/.+/.test(urlPath.toLowerCase())) {
        return tusServer.handle(req, res);
    }

    appCallback(req, res);
});

server.listen(port)

Features

Events:

Execute code when lifecycle events happen by adding event handlers to your server.

const Server = require('tus-node-server').Server;
const EVENTS = require('tus-node-server').EVENTS;

const server = new Server();
server.on(EVENTS.EVENT_UPLOAD_COMPLETE, (event) => {
    console.log(`Upload complete for file ${event.file.id}`);
});
  • EVENT_FILE_CREATED: Fired when a POST request successfully creates a new file

    Example payload:

    {
        file: {
            id: '7b26bf4d22cf7198d3b3706bf0379794',
            upload_length: '41767441',
            upload_metadata: 'filename NDFfbWIubXA0'
         }
    }
    
  • EVENT_ENDPOINT_CREATED: Fired when a POST request successfully creates a new upload endpoint

    Example payload:

    {
        url: 'http://localhost:1080/files/7b26bf4d22cf7198d3b3706bf0379794'
    }
    
  • EVENT_UPLOAD_COMPLETE: Fired when a PATCH request finishes writing the file

    Example payload:

    {
        file: {
            id: '7b26bf4d22cf7198d3b3706bf0379794',
            upload_length: '41767441',
            upload_metadata: 'filename NDFfbWIubXA0'
        }
    }
    

Custom GET handlers:

Add custom GET handlers to suit your needs, similar to Express routing.

const server = new Server();
server.get('/uploads', (req, res) => {
    // Read from your DataStore
    fs.readdir(server.datastore.path, (err, files) => {
        // Format the JSON response and send it
    }
});

Custom file names:

const fileNameFromUrl = (req) => {
    return req.url.replace(/\//g, '-');
}

server.datastore = new tus.FileStore({
    path: '/files',
    namingFunction: fileNameFromUrl
});

Development

Start the demo server using Local File Storage

$ npm run demo

Or start up the demo server using Google Cloud Storage

$ npm run gcs_demo

Then navigate to the demo (localhost:1080) which uses tus-js-client