71fddb18dae178c24a280a0360fa4e709da64ddf
[nodejs-repoproxy.git] / lib / router.js
1 var url = require("url");
2 var fs = require("fs");
3 var cache = require("./cache.js");
4 var path = require("path");
5
6 exports.routeRequest = function(req, res) {
7         // first, unify the request
8         var thisQuery = unifyRequest(req, res, function(unified) {
9                 if(unified.exists) {
10                         if(unified.isFile) {
11                                 cache.serviceFile(unified);
12                         } else if(unified.isDirectory) {
13                                 cache.serviceDirectory(unified);
14                         } else {
15                                 console.log("ERROR: something went majorly wrong with something, ", unified);
16                         }
17                 } else {
18                         // it doesnt exist yet, so we send it to the cache service
19                         console.log("file doesnt exist, upstream we go: ", unified);
20                         cache.upstreamRequest(unified, function(err) {
21                                 if(err == null) {
22                                         cache.watchAndService(unfied);
23                                 } // if upstream sends anything other then a 200, cache.upstreamRequest will handle it (i.e. 302, 404, etc)
24                         });
25                 }
26         });
27 }
28
29 function unifyRequest(req, res, callback, testing) {
30         var unified = new Object();
31         var originalurl = url.parse(req.url);
32         
33         // create the base unified object
34         unified.a = req;
35         unified.b = res;
36
37         // create the request url
38         // remove /pub if it exists
39         unified.requestFor = originalurl.pathname.replace(/^\/pub/, "");
40         unified.originalReq = originalurl.pathname;
41         
42         // create the full file path by spanning the cachedir
43         unified.fullFilePath = (global.repoproxy.cacheDir + "/" + originalurl.pathname.replace(/^\/pub/, "")).replace(/\/+/g, "/");
44         
45         // determine if the request is for a directory
46         if(unified.requestFor.match(/\/$/) != null) {
47                 unified.isDirectoryRequest = true;
48                 unified.fullPathDirName = unified.fullFilePath;
49         } else {
50                 unified.isDirectoryRequest = false;
51                 unified.fullPathDirName = path.dirname(unified.fullFilePath);
52         }
53         
54         // determine the topPath, subpath etc.
55         var spl = unified.requestFor.split("/");
56         unified.topPath = spl[1];
57         unified.subPath = "";
58         if(spl.length > 2) {
59                 for(var i=2; i < spl.length; i++) {
60                         if(unified.subPath == "") unified.subPath = spl[i];
61                         else unified.subPath += "/" + spl[i];
62                 }
63         } else {
64                 unified.subPath = null;
65         }
66         
67         
68         fs.stat(unified.fullFilePath, function(err, stats) {
69                 if(err == null) {
70                         unified.exists = true;
71                         if(stats.isDirectory() && !unified.isDirectoryRequest) {
72                                 //send a 302 and call it a day
73                                 res.writeHead("302", { 'Location': unified.originalReq+"/" });
74                                 res.end();
75                                 
76                                 // TODO: remove this after testing
77                                 if(testing) callback(null);
78                                 return 302;
79                         }
80                         
81                         if(stats.isDirectory()) {
82                                 unified.isDirectory = true;
83                                 unified.isFile = false;
84                         } else if(stats.isFile()) {
85                                 unified.isDirectory = false;
86                                 unified.isFile = true;                          
87                         } else {
88                                 unified.isDirectory = false;
89                                 unified.isFile = false;
90                         }
91                 } else {
92                         unified.exists = false;
93                 }
94                 
95                 callback(unified);
96         });
97         
98         return 0;
99 }
100
101 exports.unifyRequest = unifyRequest;