From 737e22b1ef4bcd5c160854dda523763a7d904eb4 Mon Sep 17 00:00:00 2001 From: Dave Winer Date: Sat, 23 May 2015 19:35:14 -0400 Subject: [PATCH] v0.59 --- README.md | 4 ++ pagepark.js | 189 +++++++++++++++++++++++++++++----------------------- 2 files changed, 111 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 22c808a..73cb255 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,10 @@ There will always be more work to do here. ;-) #### Updates +##### v0.59 5/23/15 by DW + +You can now delegate requests to apps running on other ports on your server machine. There's a new optional section of the prefs. json file where you specify these mappings. It's called domainMap. It's a set of name-values, where the name is the domain, and the value is the port the requests are mapped to. Here's an example of a prefs.json that has a domainMap specified. It maps twitter.radio3.io to the process running on port 5342, twitter.happyfriends.camp to 5338, and any request on judgment.club to the process on port 5351. The name matches the end of the HOST header for the request, so a request for judy.judgment.club will map, as will renee.judgment.club and judgment.club. + ##### v0.57 5/11/15 by DW PagePark has pre-defined pages, /now, /version and /status, whose values are returned by PagePark itself. It used to be that they took precedence, so if a site defines pages with those names, the internal ones would be served instead. Now we only serve them if the site didn't define it. diff --git a/pagepark.js b/pagepark.js index 0bd37a1..7d203c5 100644 --- a/pagepark.js +++ b/pagepark.js @@ -1,4 +1,4 @@ -var myVersion = "0.58h", myProductName = "PagePark"; +var myVersion = "0.59f", myProductName = "PagePark"; //The MIT License (MIT) @@ -287,6 +287,31 @@ function handleHttpRequest (httpRequest, httpResponse) { } }); } + function delegateRequest (urlToDelegateTo) { + var theRequest = { + url: urlToDelegateTo, + headers: { + "X-Forwarded-Host": host, + "X-Forwarded-For": httpRequest.connection.remoteAddress + } + }; + try { + httpRequest.pipe (request (theRequest)).pipe (httpResponse); + } + catch (tryError) { + httpResponse.writeHead (500, {"Content-Type": "text/plain"}); + httpResponse.end (tryError.message); + } + } + function findMappedDomain (domain, callback) { //5/23/15 by DW + for (var x in pageparkPrefs.domainMap) { + if (utils.endsWith (domain, x)) { + callback (pageparkPrefs.domainMap [x]); //a mapped domain, delegate to this port + return; + } + } + callback (undefined); //it's one of our domains, handle it here + } try { var parsedUrl = urlpack.parse (httpRequest.url, true), host, lowerhost, port, referrer; @@ -338,96 +363,96 @@ function handleHttpRequest (httpRequest, httpResponse) { console.log (now.toLocaleTimeString () + " " + httpRequest.method + " " + host + ":" + port + " " + lowerpath + " " + referrer + " " + client); }); //handle the request - getDomainFolder (host, function (domainfolder, actualhost) { //might be a wildcard folder - var f = domainfolder + parsedUrl.pathname; - if (checkPathForIllegalChars (f)) { - fsSureFilePath (domainsPath, function () { //make sure domains folder exists - getConfigFile (actualhost, function (config) { //get config.json, if it exists -- 1/18/15 by DW - if (config != undefined) { - if (config.urlSiteRedirect != undefined) { - var urlRedirect = config.urlSiteRedirect + parsedUrl.pathname; - httpResponse.writeHead (302, {"Location": urlRedirect, "Content-Type": "text/plain"}); - httpResponse.end ("Temporary redirect to " + urlRedirect + "."); - return; - } - if (config.urlSiteContents != undefined) { //4/26/15 by DW -- v0.55 - var theRequest = { - url: config.urlSiteContents + httpRequest.url, - headers: { - "X-Forwarded-Host": host, - "X-Forwarded-For": httpRequest.connection.remoteAddress + findMappedDomain (host, function (thePort) { + if (thePort !== undefined) { + var urlRemote; + parsedUrl.protocol = "http:"; + parsedUrl.host = host + ":" + thePort; + parsedUrl.hostname = host; + parsedUrl.port = thePort; + urlRemote = urlpack.format (parsedUrl); + delegateRequest (urlRemote); + } + else { //no mapping, we handle the request + getDomainFolder (host, function (domainfolder, actualhost) { //might be a wildcard folder + var f = domainfolder + parsedUrl.pathname; + if (checkPathForIllegalChars (f)) { + fsSureFilePath (domainsPath, function () { //make sure domains folder exists + getConfigFile (actualhost, function (config) { //get config.json, if it exists -- 1/18/15 by DW + if (config != undefined) { + if (config.urlSiteRedirect != undefined) { + var urlRedirect = config.urlSiteRedirect + parsedUrl.pathname; + httpResponse.writeHead (302, {"Location": urlRedirect, "Content-Type": "text/plain"}); + httpResponse.end ("Temporary redirect to " + urlRedirect + "."); + return; + } + if (config.urlSiteContents != undefined) { //4/26/15 by DW -- v0.55 + delegateRequest (config.urlSiteContents + httpRequest.url); + return; + } + if (config.s3Path != undefined) { //5/11/15 PM by DW v0.58 + var firstPartOfHost = utils.stringNthField (host, ".", 1); //if it's dave.smallpict.com, this value is "dave" + var s3url = "http:/" + config.s3Path + firstPartOfHost + parsedUrl.pathname; //xxx + request (s3url, function (error, response, body) { + if (error) { + httpResponse.writeHead (500, {"Content-Type": "text/plain"}); + httpResponse.end ("Error accessing S3 data: " + error.message); + } + else { + httpResponse.writeHead (response.statusCode, {"Content-Type": response.headers ["content-type"]}); + httpResponse.end (body); + } + }); + return; } - }; - try { - httpRequest.pipe (request (theRequest)).pipe (httpResponse); - } - catch (tryError) { - httpResponse.writeHead (500, {"Content-Type": "text/plain"}); - httpResponse.end (tryError.message); } - return; - } - if (config.s3Path != undefined) { //5/11/15 PM by DW v0.58 - var firstPartOfHost = utils.stringNthField (host, ".", 1); //if it's dave.smallpict.com, this value is "dave" - var s3url = "http:/" + config.s3Path + firstPartOfHost + parsedUrl.pathname; //xxx - request (s3url, function (error, response, body) { - if (error) { - httpResponse.writeHead (500, {"Content-Type": "text/plain"}); - httpResponse.end ("Error accessing S3 data: " + error.message); + fs.stat (f, function (err, stats) { + if (err) { + switch (lowerpath) { + case "/version": + httpResponse.writeHead (200, {"Content-Type": "text/plain"}); + httpResponse.end (myVersion); + break; + case "/now": + httpResponse.writeHead (200, {"Content-Type": "text/plain"}); + httpResponse.end (now.toString ()); + break; + case "/status": + var status = { + prefs: pageparkPrefs, + status: pageparkStats + } + httpResponse.writeHead (200, {"Content-Type": "text/plain"}); + httpResponse.end (utils.jsonStringify (status)); + break; + default: + return404 (); + break; + } } else { - httpResponse.writeHead (response.statusCode, {"Content-Type": response.headers ["content-type"]}); - httpResponse.end (body); - } - }); - return; - } - } - fs.stat (f, function (err, stats) { - if (err) { - switch (lowerpath) { - case "/version": - httpResponse.writeHead (200, {"Content-Type": "text/plain"}); - httpResponse.end (myVersion); - break; - case "/now": - httpResponse.writeHead (200, {"Content-Type": "text/plain"}); - httpResponse.end (now.toString ()); - break; - case "/status": - var status = { - prefs: pageparkPrefs, - status: pageparkStats + if (stats.isDirectory ()) { + if (!utils.endsWith (f, "/")) { + f += "/"; + } + findIndexFile (f, function (findex) { + serveFile (findex, config); + }); + } + else { + serveFile (f, config); } - httpResponse.writeHead (200, {"Content-Type": "text/plain"}); - httpResponse.end (utils.jsonStringify (status)); - break; - default: - return404 (); - break; - } - } - else { - if (stats.isDirectory ()) { - if (!utils.endsWith (f, "/")) { - f += "/"; } - findIndexFile (f, function (findex) { - serveFile (findex, config); - }); - } - else { - serveFile (f, config); - } - } + }); + }); }); - }); + } + else { + httpResponse.writeHead (500, {"Content-Type": "text/plain"}); + httpResponse.end ("The file name contains illegal characters."); + } }); } - else { - httpResponse.writeHead (500, {"Content-Type": "text/plain"}); - httpResponse.end ("The file name contains illegal characters."); - } }); } catch (tryError) {