This commit is contained in:
2017-08-26 17:48:10 +02:00
commit 43393cfe9c
11 changed files with 138 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
node_modules/
package-lock.json

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# shrt
A URL shortener service.

12
hash.js Normal file
View File

@@ -0,0 +1,12 @@
const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
function randomChar() {
return ALPHABET.charAt(Math.floor(Math.random()*62))
}
function createHash(len) {
var str = '';
while(str.length < len) str += randomChar();
return str;
}
module.exports = createHash;

21
package.json Normal file
View File

@@ -0,0 +1,21 @@
{
"name": "shrt",
"version": "0.0.1",
"description": "A URL shortener",
"main": "shrt.js",
"scripts": {
"start": "node shrt.js"
},
"keywords": [
"url",
"shortener"
],
"author": "hellerve",
"license": "GPL",
"dependencies": {
"hapi": "^14.1.0",
"inert": "^4.0.1",
"joi": "^9.0.4",
"mongoose": "^4.5.8"
}
}

0
public/404.css Normal file
View File

0
public/script.js Normal file
View File

0
public/style.css Normal file
View File

66
routes.js Normal file
View File

@@ -0,0 +1,66 @@
const Joi = require('joi');
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const hash = require('./hash');
const HASHLEN = 7;
const baseUrl = process.env.BASE_URL || 'shrt.in';
const schema = new Schema({
shrt: String,
url: String,
});
const Shrt = mongoose.model('Shrt', schema);
module.exports = [
{
method: 'GET',
path: '/',
handler(request, reply) {
reply.file('views/index.html');
}
},
{
method: 'GET',
path: '/public/{file}',
handler(request, reply) {
reply.file(`public/${request.params.file}`);
}
},
{
method: 'POST',
path: '/new',
handler(request, reply) {
const uid = hash(HASHLEN);
const r = new Shrt({
short: `${baseUrl}/${uniqueID}`,
url: request.payload.url,
});
r.save((err, redir) => err ? reply(err) : reply(redir));
},
config: {
validate: {
payload: {
url: Joi.string()
.regex(/^https?:\/\/([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/)
.required()
}
}
}
},
{
method: 'GET',
path:'/{hash}',
handler(request, reply) {
const query = {
'short': `${baseUrl}/${request.params.hash}`
};
Shrt.findOne(query, (err, shrt) => {
if (err) return reply(err);
else if (shrt) reply().redirect(shrt.url);
else reply.file('views/404.html').code(404);
});
}
},
];

34
shrt.js Normal file
View File

@@ -0,0 +1,34 @@
const Hapi = require('hapi');
const server = new Hapi.Server();
const routes = require('./routes');
const mongoose = require('mongoose');
const mongoUri = process.env.MONGOURI || 'mongodb://localhost/shortio';
const options = {
server: {
socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 }
},
replset: {
socketOptions: { keepAlive: 300000, connectTimeoutMS : 30000 }
}
};
mongoose.connect(mongoUri, options);
const db = mongoose.connection;
server.connection({
port: process.env.PORT || 3000,
routes: { cors: true }
});
server.register(require('inert'), (err) => {
db.on('error', console.error.bind(console, 'connection error:'))
.once('open', () => {
server.route(routes);
server.start(err => {
if (err) throw err;
console.log(`Server running at port ${server.info.port}`);
});
});
});

0
views/404.html Normal file
View File

0
views/index.html Normal file
View File