--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>nodejs-repoproxy</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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);
--- /dev/null
+# 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