summaryrefslogtreecommitdiffstats
path: root/go/index.js
blob: 3bac2f7b12e5d19767d83e2c495b75777748be39 (plain)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// configuration
var hostname = process.env.HOSTN;
var httpPort = process.env.PORT;
var uriPrefix = process.env.URI_PREFIX;
var redisPrefix = process.env.REDIS_KEY_PREFIX;
var appendDomainToUri = process.env.NOT_SO_SHORT === 'true';


// automatic configuration
if (!httpPort) {
  httpPort = 1337;
}
if (!uriPrefix) {
  uriPrefix = '';
  if (hostname) {
    uriPrefix += 'http://' + hostname;
    if (httpPort != 80) {
      uriPrefix += ':' + httpPort;
    }
  }
}
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 = uriPrefix + shortPath;
      var key = redisPrefix + shortPath;

      redisClient.set(key, uri, function (error) {
        if (error) {
          return internalError(err, req, res);
        }

        if (appendDomainToUri) {
          shortUri += '#' + url.parse(uri).host
        }

        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');
}