tus-node-server
tus-node-server copied to clipboard
Add Hapi Integration
Is it possible to add Hapi integration similar to this? The Code doesn't seem to work anymore. any ideas how to fix?
It's not officially supported and I haven't researched Hapi to know what is required for the integration. PRs welcome :)
@corusm It's bad practice, but I've forked tus-node-server
into hapi-tus-node-server
, so anyone using Hapi can install hapi-tus-node-server
and use it as a Hapi plugin. Feel free to give it a try if you like. Hat tip to everyone who posted in the thread TUS Resumable Uploads, and of course, all the awesome people who have brought us tus!
@corusm, I am trying also to implement with Hapi. I haven't use hapi-tus-node-server but I instead used the exemple in the Quick Guide and adapted it to work with Hapi.
The only issue I seem to have so fare is that the [file-id].info is empty on S3 and is not created in the file storage. I wonder if this a bug in the package or something wrong with Hapi but here's what I have came up with.
I you use hapi-cors, you have to add headers used by tus
await server.register({
plugin: require('hapi-cors'),
options: {
origins: ['*'],
headers: [
'Accept', 'Content-Type', 'Authorization',
/* EXTRA HEADERS */
'tus-resumable','upload-length','upload-metadata','x-http-method-override','upload-offset',
'x-requested-with', 'x-forwarded-host','x-forwarded-proto','Forwarded'
/* ****************** */
],
methods: ['POST, GET, PUT, DELETE, PATCH, HEAD']
}
});
Make sure to also add "PATCH and HEAD" in methods
These are the 3 routes I needed
const path = require('path');
const handlers = require(path.resolve('handlers/commons/media'));
const basic = '/api/v1/commons/media'
module.exports = [
{
method: 'PATCH',
path: basic + '/files/{any*}',
options: {
handler: handlers.uploadFiles,
description: 'Upload file',
auth: {
access: {
scope: ['clientscope:profile']
}
},
payload:{
maxBytes: 104857600,
output: 'stream',
parse: true,
multipart: true
},
tags: ['api', 'commons'],
}
},
{
method: '*',
path: basic + '/files/{any*}',
options: {
handler: handlers.uploadFiles,
description: 'Upload file',
auth: {
access: {
scope: ['clientscope:profile']
}
},
tags: ['api', 'commons'],
}
},
{
method: '*',
path: basic + '/files',
options: {
handler: handlers.uploadFiles,
description: 'Upload file',
auth: {
access: {
scope: ['clientscope:profile']
}
},
tags: ['api', 'commons'],
}
}
];
And here is my handler :
const path = require('path');
const {s3Config} = require(path.resolve("config/config"));
const {Server} = require('@tus/server')
const {S3Store} = require('@tus/s3-store')
const {FileStore} = require('@tus/file-store')
class media {
static async uploadFiles(request,h){
try{
// IF YOU WANT TO USE S3
const s3Store = new S3Store({
partSize: 8 * 2 ** 20, //If you want to use MultiParts
s3ClientConfig: s3Config,
})
// IF YOU WANT TO USE FileStore
const fileStore = new FileStore({ directory: './temp/files' })
const tusServer = new Server({
//PATH will be sent back to your frontend so make sure to set the same path as your route ex: basic + '/files/{any*}'
path: '/api/v1/commons/media/files',
datastore: s3Store, // Use fileStore if you want to use local upload
async onUploadCreate(req, res, upload) {
/*
DO YOUR STUFF HERE before it starts to upload
Eg: Save meta in DB before upload
*/
return res
},
async onUploadFinish(req, res, upload) {
/*
DO YOUR STUFF HERE after the upload is completed
Eg: Update status or do other actions
*/
return res
}
})
await tusServer.handle(request.raw.req, request.raw.res)
return h.response(); //Make sure to return a 204. you could also use h.response().code(204)
}catch (e) {
// Handle errors here
console.log(e);
return h.response().code(500)
}
}
}
module.exports = media;
I still have to figure out an issue which is an ERR_HTTP_HEADERS_SENT. I will come back it in a later time but if anyone have a fix it would be great. I hid it (FOR NOW ;) ) by adding :
process.on('unhandledRejection', (err) => {
if(err.code !== 'ERR_HTTP_HEADERS_SENT'){
console.log(err);
}
//process.exit(1);
});
in my unhandledRejection
event in my app.js