Monday, November 08, 2010 at 12:05 AM.

system.verbs.builtins.radio.webServer.walk

on walk (path, adrfilepath) { //returns boolean, if true, the file/folder was found
	<<Changes
		<<1/7/02; 11:47:04 AM by JES
			<<Files/folders which begin with '.' are invisible -- they're a 404.
		<<12/9/01; 7:00:30 AM by DW
			<<Folders would not 404, now they do.
		<<8/12/01; 4:17:38 PM by JES
			<<Fixed a bug in the code that returns false if the file is invisible: We were checking for the file as named in the request path, instead of the file found by radio.file.locateFileIgnoringExtension.
		<<8/11/01; 5:33:27 PM by JES
			<<Invisible files/folders return a 404 File Not Found error.
		<<6/15/01; 12:33:33 AM by PBS
			<<Removed the multiple checks for objectName containing ".." -- also removed the stack, because now it's not needed.
			<<Fixed bug where URLs such as /real/file/fake/extra/bits would get you the same as /real/file -- those should return a 404.
		<<5/6/01; 7:48:47 AM by DW
			<<It's easier to work on the walk code if it's in a separate script.
	local (nomad = user.radio.prefs.wwwfolder);
	local (objectName, pc = file.getPathChar ());
	while (sizeOf (path) > 0) {
		path = string.popLeading (path, '/');
		objectName = string.nthField (path, '/', 1);
		path = string.delete (path, 1, sizeOf (objectName));
		bundle { //DW and PBS 08/09/00: close security hole
			<<if objectName beginsWith ".." //DW 08/09/00: close security hole//08/02/01 JES: This is now handled by radio.webServer.responder
				<<scriptError ("Can't process objects with names beginning with \"..\".")
			if objectName contains "\\" { //PBS 08/09/00: \ character not allowed
				scriptError ("Can't process objects with names containing \"\\\".")};
			if objectName contains ":" { //PBS 08/09/00: : character not allowed
				scriptError ("Can't process objects with names containing \":\".")}};
		bundle { //JES 01/07/02: close security hole
			if objectName beginsWith "." {
				if sizeOf (objectName) > 1 {
					return (false)}}};
		
		local (nextnomad = nomad + objectName);
		if sizeOf (path) > 0 { //if we're not at the terminus, this better be a folder
			local (subfolder = nextnomad + pc);
			if not file.exists (subfolder) { //doesn't exist, it's a 404
				return (false)};
			if not file.isfolder (subfolder) { //not a folder -- it's a 404.
				return (false)};
			if not file.isVisible (subfolder) { //invisible folders cause a 404.
				return (false)};
			nomad = subfolder}
		else { //it's the final part of the path, a request for a folder or file
			if not (file.exists (nextnomad)) { //is it a 404 File Not Found?
				if not radio.file.locateFileIgnoringExtension (nextnomad, adrfilepath) {
					return (false)};
				if file.isVisible (adrfilepath^) { //found a visible file -- return true. (adrfilepath^ is already set.)
					return (true)}
				else { //invisible files are a 404.
					return (false)}};
			adrfilepath^ = nextnomad;
			return (true)}}}
<<bundle //test code
	<<local (f)
	<<walk ("/", @f)
	<<walk ("/stories/", @f)
	<<dialog.alert (f)



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.