upstream now appears to work just fine
[nodejs-repoproxy.git] / lib / cache.js
index bf1a3b0..e065a2a 100644 (file)
@@ -19,26 +19,116 @@ function upstreamRequest(unify, callback) {
        // first do a head request
        console.log("upsteram as ", unify.requestFor);
        
-       var splpath = unify.requestFor.split("/");
-       var topdir = splpath[1];
-       var toppath = "";
-       for(var i=2; i < splpath.length; i++) {
-               if(toppath == "") {
-                       toppath = splpath[i];
-               } else {
-                       toppath += "/" + splpath[i];
-               }
-       }
-       console.log("uppath = '%s' and '%s'", topdir, toppath);
-       if(typeof global.repoproxy.repo[topdir] != "undefined") {
-               console.log("which is ", global.repoproxy.repo[topdir]);
-               console.log("so upstream is, ", global.repoproxy.repo[topdir].url + toppath);
+       var endData = false;
+       var xpath = "";
+       var filefd = null;
+       if(unify.topPath !=null) if(unify.topPath != "") if(typeof global.repoproxy.repo[unify.topPath] != "undefined") {
+               var uplink = global.repoproxy.repo[unify.topPath].url;
+               xpath = uplink + unify.subPath;
        }
        
+       //unify.b.write("would send to '" + xpath + "'");
+       //unify.b.end();
+       
+       console.log("sending off to '%s'", xpath);
+       
+       var headReq = url.parse(xpath);
+       headReq["method"] = "HEAD";
+       
+       getup = http.request(xpath, function(res) {
+               res.setEncoding("utf8");
+               
+               if(!endData) {
+                       console.log("status code is ", typeof res.statusCode);
+                       switch(res.statusCode) {
+                       // TODO: this 301 directory redirect thing needs to work better
+                       case 301:
+                       case 302:
+                               
+                               var loc = res.headers.location.substr(res.headers.location.length-4);
+                               var against_t = xpath + "/";
+                               var against = against_t.substr(against_t.length-4);
+                               
+                               if(loc == against) {
+                                       console.log("got a redirect, upstream for loc => loc/ assuming its a directory");
+                                       makeCacheDir(unify);
+                                       unify.b.writeHead(302, { "Location": unify.originalReq + "/" });
+                               } else {
+                                       console.log("checked '%s' against '%s', was false, sending 404", loc, against);
+                                       unify.b.writeHead(404, {"Content-Type": "text/plain"});
+                                       unify.b.write("404 Not Found\n");
+                               }
+                               unify.b.end();
+                               endData = true;
+                               break;
+                               
+                       case 404:
+                               unify.b.writeHead(404, {"Content-Type": "text/plain"});
+                               unify.b.write("404 Not Found\n");
+                               unify.b.end();
+                               endData = true;
+                               break;
+                       case 200:
+                               makeCacheDir(unify);
+                               if(unify.isDirectoryRequest) {
+                                       serviceDirectory(unify);                                        
+                                       endData = true;
+                               } else {
+                                       // this is where it gets ugly
+                                       console.log("do ugly write: ", unify);
+                                       //unify.b.write(data);
+                                       getAndService(unify, xpath);
+                                       
+                               }
+                               break;
+                       default:
+                               console.log(".... data");
+                               //unify.b.write(data);
+                       }
+               }               
+               //console.log("res is now ", res);
+       });
+       
+       getup.end();
+       
+       //console.log("getup: ", getup);
 }
 
 exports.upstreamRequest = upstreamRequest;
 
+function getAndService(unify, xpath) {
+       
+       if(global.repoproxy.downloads[unify.fullFilePath] == 1) {
+               
+               unify.b.write("trying to service inline");
+               unify.b.end();
+       } else {
+               global.repoproxy.downloads[unify.fullFilePath] = 1;
+       
+               http.get(xpath, function(res) {
+       
+                   var file = fs.createWriteStream(unify.fullFilePath);
+               
+                   console.log("res: ", res);
+               
+                   //res.setEncoding("utf8");
+               
+                   res.on("data", function(data) {
+                           //console.log("chunk");
+                           file.write(data);
+                           unify.b.write(data);
+                   });
+               
+                   res.on("end", function() {
+                           console.log("end...");
+                           unify.b.end();
+                           file.end();
+                           global.repoproxy.downloads[unify.fullFilePath] = 0;
+                   });
+               });
+       }
+}
+
 // the service file routine .... PLEASE KILL ME!
 function serviceFile(unify) {
        
@@ -58,6 +148,23 @@ function serviceFile(unify) {
 
 exports.serviceFile = serviceFile;
 
+function makeCacheDir(path) {
+       console.log("attempting to create... '%s' as '%s'", path.fullPathDirName, path.subPathDirName);
+       
+       var startAt = path.topFullPath;
+       var nextbits = path.subPathDirName.split("/");
+       for(var i=0; i < nextbits.length; i++) {
+               startAt += "/" + nextbits[i];
+               console.log("attempt mkdir on '%s'", startAt);
+               try {
+                       fs.mkdirSync(startAt);
+               } catch(e) {
+                       //console.log("e in mkdir, ", e);
+               }
+       }
+       //process.exit(0);
+}
+
 function serviceDirectory(unify) {
        var nfiles = 0;
        var res = unify.b;