1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
// configuration
var httpPort = process.env.PORT;
var redisPrefix = process.env.REDIS_KEY_PREFIX;
// automatic configuration
if (!httpPort) {
httpPort = 1337;
}
if (!redisPrefix) {
redisPrefix = 'go:';
}
// load libraries
var http = require('http');
var url = require('url');
var formidable = require('formidable');
var redis = require('redis');
// instantiate components
var redisClient = redis.createClient();
var httpServer = http.createServer(listener);
// setup compoments
redisClient.on('error', function (err) {
console.log('redis made a bubu:', err.message);
process.exit(23);
});
httpServer.listen(httpPort, function () {
console.log('http server listening on port', httpPort);
});
// http handler
function listener (req, res) {
if (req.method === 'POST' && req.url === '/') {
return create(req, res);
} else if (req.method === 'GET') {
return retrieve(req, res);
} else {
return methodNotAllowed(req, res);
}
}
function create (req, res) {
redisClient.incr(redisPrefix + 'index', function (err, reply) {
if (err) {
return internalError(err, req, res);
}
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
if (err) {
return internalError(err, req, res);
}
var uri = fields.uri;
// TODO check uri(?)
var shortPath = '/' + reply;
var shortUri = 'http://' + req.headers.host + shortPath;
var key = redisPrefix + shortPath;
redisClient.set(key, uri, function (error) {
if (error) {
return internalError(err, req, res);
}
res.writeHead(200, { 'content-type': 'text/plain' });
return res.end(shortUri + '\r\n');
});
});
});
}
function retrieve (req, res) {
var key = redisPrefix + url.parse(req.url).path;
redisClient.get(key, function (error, reply) {
if (error) {
return internalError(err, req, res);
}
if (typeof reply !== 'string') {
res.writeHead(404, { 'content-type': 'text/plain' });
return res.end('not found\r\n');
}
res.writeHead(302, {
'content-type': 'text/plain',
'location': reply,
});
return res.end();
});
}
function methodNotAllowed (req, res) {
res.writeHead(405, { 'content-type': 'text/plain' });
return res.end('method not allowed\r\n');
}
function internalError (error, req, res) {
res.writeHead(500, { 'content-type': 'text/plain' });
return res.end(error.message + '\r\n');
}
|