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