Monday, November 08, 2010 at 12:07 AM.
system.verbs.builtins.webserver.util.pathToAddressExt
on pathToAddressExt (path, nomad, adrParamTable, flput = false) {
<<Changes
<<1/7/06; 10:27:06 PM by DW
<<If there's a script in the prefs sub-table of the website named objectNotFoundHander, run it, allowing it to redirect to a different location. This is a poor man's version of the handler in mainResponder, needed for newsRiver's website.
<<1/7/06; 9:40:23 PM by DW
<<De-Biermanized.
<<Bierman comments
<<Sunday, May 24, 1998 at 12:13:45 PM by PBS
<<Force the docTree-walk loop to execute one time through if the path == "/"
<<Fixes weird %2Fdefault/ paths.
<<Script: system.verbs.builtins.webserver.util.pathToAddressExt; Version 3; Date: Thu, 21 May 1998 17:34:23 GMT; ID: RAB
<<Handle the default path transparency.
<<Script: system.verbs.builtins.webserver.util.pathToAddressExt; Version 2; Date: Mon, 11 May 1998 21:19:36 GMT; ID: RAB
<<Added code for handling PUT. The code is the same as GET if replacing an element, but returns true is all but the final element exists.
<<This allows the put to add a new item, but NOT a new structure.
<<Script: system.verbs.builtins.webserver.util.pathToAddressExt; Version 1; Date: Wed, 06 May 1998 20:26:15 GMT; ID: RAB
local (remainder, firstpart, treeElement = 1, fileElementStart = 0, doctree, origNomad);
local (default, flFile);
local (dataTableAdr, responderTableAdr, prefsTableAdr);
on callObjectNotFoundHandler () { //1/7/06 by DW
local (n = nomad, newn, adronfh);
loop {
newn = parentof (n^);
if not defined (newn^) {
return};
n = newn;
adronfh = @n^.["#objectNotFoundHandler"];
if defined (adronfh^) {
break}};
html.setpagetableaddress (adrParamTable);
adronfh^ ()};
on resolveDefault (addPart) {
local (k, newDefault);
flFile = false;
case typeOf(default^) {
tableType {
newDefault = @default^.[addPart];
if defined (newDefault^) {
default = newDefault;
return (true)};
if addPart == "" {
for k in prefsTableAdr^.ODBdefault {
newDefault = @default^.[k];
if defined (newDefault^) {
default = newDefault;
return (true)}}}};
addressType {
default = default^;
if defined (default^) {
return (resolveDefault (addPart))}};
filespecType {
default = default^;
if file.isFolder (default) {
default = string.poptrailing(default, file.getpathChar ()) + file.getpathChar () + addPart;
if file.exists (default) {
flFile = true;
return (true)}}}};
return (false)};
responderTableAdr = adrParamTable^.responderTableAdr; // the responder table
dataTableAdr = @responderTableAdr^.["data"]; //This table contains the user data for this responder
prefsTableAdr = @dataTableAdr^.["prefs"]; //This table contains the user prefs for this responder
path = string.popLeading (path, "/");
remainder = path;
bundle { //walk the doc tree
local (flFirstTime = true);
new (listType, @doctree);
doctree[treeElement] = nomad;
loop {
if remainder == "" and not (flFirstTime) {
break};
flFirstTime = false;
firstpart = string.nthfield (remainder, '/', 1);
remainder = string.delete (remainder, 1, sizeof (firstpart) + 1);
if (firstpart contains "\\") or (firstpart contains ":") or (firstpart contains "#") {
<<This means they are trying things like foo:::, etc, having a colon or backslash is not leagal syntax and therefore is a Bad Request
adrParamTable^.code = 400;
adrParamTable^.responseBody = webserver.util.buildErrorPage ("400 Bad Request", "The object " + adrParamTable^.path + " has improper syntax.");
return (false)};
if firstpart == ".." {
if treeElement <= 1 {
<<Access above the base is not allowed
adrParamTable^.code = 403;
adrParamTable^.responseBody = webserver.util.buildErrorPage ("403 Forbidden", "Access to the object " + adrParamTable^.path + " is forbidden.");
return (false)};
--treeElement;
nomad = doctree[treeElement];
if treeElement < fileElementStart {
fileElementStart = 0}} // This means we've dot-dotted our way back into the ODB table
else { //we are adding an element to the doc tree
if firstpart beginswith ".." {
<<This means they are trying things like ..., etc, starting with .. is not leagal syntax and therefore is a Bad Request
adrParamTable^.code = 400;
adrParamTable^.responseBody = webserver.util.buildErrorPage ("400 Bad Request", "The object " + adrParamTable^.path + " has improper syntax.");
return (false)};
if fileElementStart == 0 { //we are processing in the ODB walk
origNomad = nomad;;
nomad = @nomad^.[firstpart];
if adrParamTable^.responder == "websiteFramework" { //Handle images
if !defined (nomad^) {
if string.lower(firstpart) == string.lower (html.getPagePref("imageFolderName", origNomad)) {
firstpart = "#" + firstpart;
nomad = @origNomad^.[firstpart]}}};
if !defined (nomad^) { //first do some magic if the firstpart exists within the default tree
local (flResolved = false);
<<the object doesn't exist
<<Is it within the default path.
for i in prefsTableAdr^.ODBdefault {
default = @origNomad^.[i];
if defined (default^) {
if resolveDefault (firstpart) {
nomad = default;
if flFile {
fileElementStart = treeElement + 1};
flResolved = true;
break}}};
if not flResolved {
if flput { //processing for the PUT is a little different then for GET
if remainder == "" { //Then this is valid and the leaf is a new element
adrParamTable^.resultPath = nomad;
adrParamTable^.resultType = addressType; //we already know we are an address type here
return (true)}};
adrParamTable^.code = 404;
adrParamTable^.responseBody = webserver.util.buildErrorPage ("404 Not Found", "The object " + adrParamTable^.path + " doesn't exist.");
callObjectNotFoundHandler ();
return (false)}}
else {
if typeOf (nomad^) == addressType {
nomad = nomad^;
if !defined (nomad^) { //the object doesn't exist
adrParamTable^.code = 404;
adrParamTable^.responseBody = webserver.util.buildErrorPage ("404 Not Found", "The object " + adrParamTable^.path + " doesn't exist.");
callObjectNotFoundHandler ();
return (false)}};
if typeOf (nomad^) == filespecType {
nomad = nomad^;
fileElementStart = treeElement + 1}}}
else { //we are walking in the file system
nomad = string.poptrailing(nomad, file.getpathChar ()) + file.getpathChar () + firstpart;
if !file.exists(nomad) { //no generosity - if any element along the path does not exist, fail immedialtly
<<the file doesn't exist
if flput { //processing for the PUT is a little different then for GET
if remainder == "" { //Then this is valid and the leaf is a new element
adrParamTable^.resultPath = nomad;
adrParamTable^.resultType = filespecType; //we already know we are a file type here
return (true)}};
adrParamTable^.code = 404;
adrParamTable^.responseBody = webserver.util.buildErrorPage ("404 Not Found", "The object " + adrParamTable^.path + " does not exist.");
return (false)}};
++treeElement;
doctree[treeElement] = nomad}}};
adrParamTable^.resultPath = nomad;
adrParamTable^.resultType = addressType; //default
if fileElementStart > 0 { //nope, we were in the file system
adrParamTable^.resultType = filespecType};
return (true)}
<<bundle // testing
<<local (paramTable)
<<new (tableType, @paramTable)
<<paramTable.responder = "default"
<<paramTable.responderTableAdr = @user.webserver.responders.default
<<paramTable.path = "/"
<<dialog.notify(webserver.util.pathToAddressExt (paramTable.path, @user.webserver.responders.default.data.docTree, @paramTable))
<<paramTable.path = "/images/"
<<dialog.notify(webserver.util.pathToAddressExt (paramTable.path, @user.webserver.responders.default.data.docTree, @paramTable))
<<paramTable.path = "/frontier/debug/.../scripts"
<<dialog.notify(webserver.util.pathToAddressExt (paramTable.path, @user.webserver.responders.default.data.docTree, @paramTable))
<<paramTable.path = "/bierman/samples/davenet"
<<dialog.notify(webserver.util.pathToAddressExt (paramTable.path, @user.webserver.responders.default.data.docTree, @paramTable))
<<paramTable.path = "/bierman/samples/davenet/../../../../"
<<dialog.notify(webserver.util.pathToAddressExt (paramTable.path, @user.webserver.responders.default.data.docTree, @paramTable))
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.