initial commit
authorPaul J R <me@pjr.cc>
Fri, 18 Jan 2013 20:29:00 +0000 (07:29 +1100)
committerPaul J R <me@pjr.cc>
Fri, 18 Jan 2013 20:29:00 +0000 (07:29 +1100)
.project [new file with mode: 0644]
lib/config.js [new file with mode: 0644]
lib/router.js [new file with mode: 0644]
proxy.js [new file with mode: 0644]
repos.conf [new file with mode: 0644]

diff --git a/.project b/.project
new file mode 100644 (file)
index 0000000..88ec34d
--- /dev/null
+++ b/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>nodejs-repoproxy</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+       </buildSpec>
+       <natures>
+       </natures>
+</projectDescription>
diff --git a/lib/config.js b/lib/config.js
new file mode 100644 (file)
index 0000000..8d5de4b
--- /dev/null
@@ -0,0 +1,79 @@
+var fs = require("fs");
+
+exports.loadConfig = function (conffile) {
+       
+       global.repoproxy = new Object();
+       global.repoproxy.listenPort = 8008;
+       global.repoproxy.cacheDir = "./cache";
+       global.repoproxy.repo = new Object();
+       
+       var confFileData = fs.readFileSync(conffile, "utf8");
+       
+       // first split the file on carriage returns;
+       var confLines = confFileData.split("\n");
+       
+       // go thru each line looking for config vars
+       for(var i=0; i<confLines.length; i++) {
+               
+               // trim a line down
+               var line_one = confLines[i].trim();
+               
+               // split it up with :'s
+               var line_real = line_one.replace(/#.*/,"").split(":");
+               
+               // parse the line
+               switch(line_real[0]) {
+               case "repo":
+                       
+                       // TODO: VALIDATE!
+                       console.log("Adding repo: '/%s' type '%s' from '%s', with update interval of '%s' days, and expire time of '%s' days.", line_real[1], line_real[2], line_real[3]+":"+line_real[4], line_real[5], line_real[6]);
+                       var thisrepo = { type : line_real[2], url: line_real[3]+":"+line_real[4], updateinterval: line_real[5], expiretime: line_real[6] };
+                       global.repoproxy.repo[line_real[1]] = thisrepo;
+                       
+                       break;
+               case "cachedir":
+                       console.log("Cache dir set to: ", line_real[1]);
+                       global.repoproxy.cacheDir = line_real[1];
+                       
+                       break;
+               case "listenport":
+                       console.log("Port set to: ", line_real[1]);
+                       global.repoproxy.listenPort = line_real[1];
+                       break;
+               default:
+                       if(line_real[0] != "") {
+                               console.log("Invalid line in configuration file ignored: '%s'", line_one);
+                       }
+               }
+       }
+       
+       createCacheStructure();
+}
+
+
+function createCacheStructure() {
+       try {
+               var state = fs.statSync(global.repoproxy.cacheDir);
+               //console.log("state is:", state);
+       } catch(e) {
+               try {
+                       fs.mkdirSync(global.repoproxy.cacheDir);
+               } catch(ex) {
+                       console.log("ERROR: failure to create cache directory, '%s'", global.repoproxy.cacheDir);
+               }
+       }
+       
+       for(var index in global.repoproxy.repo) {
+               var fullDir = global.repoproxy.cacheDir + "/" + index;
+               try {
+                       var state = fs.statSync(global.repoproxy.cacheDir);
+                       //console.log("state is:", state);
+               } catch(e) {
+                       try {
+                               fs.mkdirSync(fullDir);
+                       } catch(ex) {
+                               console.log("ERROR: failed to create cache directory, '%s' for '%s'", fullDir, index);
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/lib/router.js b/lib/router.js
new file mode 100644 (file)
index 0000000..ae8408c
--- /dev/null
@@ -0,0 +1,85 @@
+var url = require("url");
+var fs = require("fs");
+
+exports.routeRequest = function(req, res) {
+       // first, strip a /pub/ off the front if it exists
+       var originalurl = url.parse(req.url);
+               
+       thisurl = originalurl.pathname.replace(/^\/pub/, "");
+       
+       console.log("pathname now: ", thisurl);
+       
+       //if(thisurl.pathname == "") thisurl.pathname = "/";
+       
+       var reqpath = global.repoproxy.cacheDir + "/" + thisurl;
+       
+       console.log("request on '%s'", reqpath);
+
+       // see what we're dealing with
+       fs.stat(reqpath, function(err, stat) {
+               console.log("err is ", err);
+               console.log("stat is ", stat);
+               console.log("fs.stats is ", fs.stats);
+               
+               if(err == null) {
+                       if(stat.isDirectory()) {
+                               if(originalurl.pathname.charAt(originalurl.pathname.length-1) != "/") {
+                                       // redirect to url + "/"
+                                       res.writeHead("302", { "Location": originalurl.pathname+"/" });
+                                       res.end();
+                               } else {
+                                       writeDirectoryListing(reqpath, originalurl.pathname, res);
+                               }
+                       } else {
+                               if(stat.isFile()) {
+                                       fs.readFile(reqpath, "utf8", function(err, data) {
+                                               res.write(data);
+                                               res.end();
+                                       });
+                               }
+                       }
+               } else {
+                       // go upstream..
+                       res.write("here we need to go upstream");
+                       res.end();
+               }
+       });     
+}
+
+function writeDirectoryListing(reqpath, requesturi, res) {
+       res.write("<html><h1>Directory listing for " + requesturi + "</h1><hr><pre>");
+       if(requesturi != "/") res.write("<a href=\"..\">Parent</a>\n\n");
+       fs.readdir(reqpath, function(err, files) {
+               console.log("doing directory listing on: ", reqpath);
+               if(err == null) {
+                       
+                       // TODO: make this work asynchronously...
+                       if(files.length == 0) {
+                               res.write("Empty Directory....\b");
+                       } else {
+                               for(var i=0; i<files.length; i++) {
+                                       // avoiding statSync is too hard for now, will fix later TODO: fix this sync bit
+                                       var stats = fs.statSync(reqpath+"/"+files[i]);
+                                       
+                                       if(stats.isDirectory()) {
+                                               
+                                               res.write("Directory: <a href=\""+files[i]+"/\">"+files[i]+"/</a>\n");
+                                       } else if(stats.isFile()) {
+                                               var padlength = 80 - (files[i].length) - stats.size.toString().length;
+                                               var padding = "";
+                                               if(padlength > 0) {
+                                                       padding = new Array(padlength).join(" ");
+                                               }
+                                               res.write("File:      <a href=\""+files[i]+"\">"+files[i]+"</a>"+padding+stats.size+" bytes\n");
+                                       }
+                               }
+                       }
+                       res.write("<hr></pre>");
+                       res.end();
+               } else {
+                       res.write("we have entered bizaro world...\n");
+                       res.write("</pre>");
+                       res.end();
+               }
+       });
+}
\ No newline at end of file
diff --git a/proxy.js b/proxy.js
new file mode 100644 (file)
index 0000000..770e7dc
--- /dev/null
+++ b/proxy.js
@@ -0,0 +1,12 @@
+var http = require("http");
+var config = require("./lib/config.js");
+var router = require("./lib/router.js");
+
+
+// first we load the config...
+config.loadConfig("./repos.conf");
+
+console.log("globals: ", global.repoproxy);
+
+// next we start our main request loop
+http.createServer(router.routeRequest).listen(global.repoproxy.listenPort);
diff --git a/repos.conf b/repos.conf
new file mode 100644 (file)
index 0000000..90bd646
--- /dev/null
@@ -0,0 +1,17 @@
+# cachedir is where it'll store files
+cachedir:./cache
+
+# port to listen on for requests
+listenport:8008
+
+ploop:asdf
+# a repo definition
+# repo:base_url:type:upstream_url:updateinterval:packageage
+# were:
+#              base_url is the name for url on this proxy (i.e. fedora for /fedora, /pub is automatically removed from urls, i.e. /pub/fedora = /fedora)
+#              type = yum or apt
+#              upstream_url is the url for the upstream repo
+#              updateinterval is how often repo meta data is refreshed (days)
+#              packageage is how long a package will go unread before it gets deleted (days)
+repo:fedora:yum:http://ftp.iinet.net.au/pub/fedora/linux/:7:120
+repo:fedora2:yum:http://ftp.iinet.net.au/pub/fedora/linux/:7:120
\ No newline at end of file