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