Monday, November 08, 2010 at 12:06 AM.
system.verbs.builtins.webserver.handler
on handler (adrparams) {
<<Change notes:
<<March 05, 1998 at 8:40:09 PM by WMF
<<Now doesn't call webstar.sendPartial when using Frontier's Web server
<<Thu, Dec 18, 1997 at 3:52:23 PM by PBS
<<Added callbacks structure.
<<user.webserver.callbacks.filterRequest.
<<This is a table of scripts that receive one parameter,
<<the address of the cgi params table.
<<Every script has a shot at altering this table.
<<Returned values are ignored.
<<user.webserver.callbacks.handleRequest
<<This is a table of scripts that receive one parameter,
<<the address of the cgi params table.
<<If a script returns anything other than ""
<<then the returned value will be returned to the server,
<<thus over-riding the default CGI Framework behavior.
<<user.webserver.callbacks.filterPage
<<This is a table of scripts that receives two parameters,
<<the address of the cgi params table and the address of the htmltext to be returned.
<<Every script has a shot at altering the returned page
<<or the cgi params (though there's little point in the second).
<<Returned values are ignored.
<<"Grandfathered-in" suites.webserverScripts and webserver.actions tables.
<<Mon, Dec 8, 1997 at 12:27:02 PM by PBS
<<Fixed preferences.
<<Made changes appropriate to new user table structure.
<<PBS 9/19/97: Now takes a table address as parameter.
<<The cgi params table is now created in the trap script.
<<PBS Jan-Feb 97
<<New parameters:
<<appID: the four-character signature of the server application
<<serverPath: the path to the server application
<<websiteFolder: the path to the website folder
<<For many servers, you can use file.folderFromPath (serverPath)
<<to get the path to the website folder. For personal web servers
<<the server may not be in the web site folder, so this parameter
<<is useful.
<<Changed calls to sendPartial to use the name of the server
<<application instead of the application signature.
<<This way one can distinguish between two servers of the same
<<type, as long as their names are different in the Finder.
<<Outlines can now be returned. These are evaluated exactly
<<the same way as wp-text objects.
<<New preference: user.webserver.chunkSize allows one to
<<change the size of the data returned in send-partial calls.
<<Return File Not Found error instead of error message page
<<when the object cannot be found.
<<DW 12/9/95: added support for partial returns in WebStar
<<see local routine "buildReturn"
local (adrscript = false, i);
local (callbackText = "");
local (adrFilters = @user.webserver.callbacks.filterRequest);
local (adrHandlers = @user.webserver.callbacks.handleRequest);
local (adrPageFilters = @user.webserver.callbacks.filterPage);
<<If debugging is on, make a copy of the paramtable.
if webserver.getPref ("fldebug") {
temp.cgiParams = adrparams^};
on buildReturn (data) { <<DW 12/9/95 -- added
data = string (data);
if data == "" {
return (data)};
if not (data beginswith "HTTP/") {
<<Add header.
data = webserver.httpHeader () + data};
<<First call the filterPage callbacks.
for i = 1 to sizeOf (adrPageFilters^) {
try {
adrPageFilters^ [i] (adrparams, @data)}};
<<all fcgi calls should use the sendpartial event if the size > 24K
<<by putting it here, we catch *all* outgoing text, so none of
<<the webserverscripts need to worry about it. this is the right
<<place to put it. DW
<<...unless you're using Frontier's Web server. WMF
local(theOS = sys.os());
if theOS contains "Mac" || adrParams^.appName == file.fileFromPath (Frontier.getProgramPath()) {
return (data)};
local (maxchunksize = 24 * 1024);
if defined (user.webserver.prefs.chunkSize) { <<PBS 2/8/97: configurable chunk size
maxchunksize = user.webserver.prefs.chunkSize * 1024};
if maxchunksize == 0 || sizeof (data) < maxchunksize { <<no problem, AE Manager won't barf
return (data)};
loop {
if sizeof (data) <= maxchunksize {
webserver.sendPartial (string (data), adrparams, false);
return ("")};
local (chunk = string.mid (data, 1, maxchunksize));
data = string.delete (data, 1, maxchunksize);
webserver.sendPartial (string (chunk), adrparams, true);
sys.systemTask ()}};
<<Call the filterRequest scripts.
for i = 1 to sizeOf (adrFilters^) {
try {
adrFilters^ [i] (adrparams)}};
<<Call the handleRequest scripts.
for i = 1 to sizeOf (adrHandlers^) {
try {
callbackText = adrHandlers^ [i] (adrparams);
if callbackText != "" {
break}}};
<<Get the address of the script.
<<Skip this if one of the handleRequest scripts will handle the request.
if callbackText == "" {
bundle { <<Is it an action script?
<<Look in user.webserver.actions.
if defined (user.webserver.actions.[adrparams^.action]) {
adrscript = @user.webserver.actions.[adrparams^.action]}
else {
<<Grandfathered-in: look in webserver.actions table.
if defined (webserver.actions.[adrparams^.action]) {
adrscript = @webserver.actions.[adrparams^.action]}}};
if !adrscript { <<It's not an action. Build the address of the script.
local (addressString = adrparams^.scriptName);
bundle { <<clean up the address string
<<on entry, the string looks like this: /sub/samples.tellTime.fcgi
addressString = string.nthField (addressString, '/', string.countFields (addressString, '/'));
addressString = string.popSuffix (addressString)};
bundle { <<build the address of the script
adrscript = "user.webserver.cgis." + addressString;
if not defined (adrscript^) { <<Script not defined.
<<Grandfathered-in: look in suites.webserverScripts.
adrscript = "suites.webserverScripts." + addressString;
if not defined (adrscript^) {
return (webserver.fileNotFoundError (adrparams))}}}}};
<<Run the script and build the return.
try {
if callbackText != "" {
return (buildReturn (callbackText))};
<<Default behavior.
case typeOf (adrscript^) {
scriptType { << run script
case sys.os {
"WinNT";
"Win95" {
return (buildReturn (adrscript^ (adrparams)))}}; <<call the CGI script, return the result
case script.getLanguage (adrscript) {
"AppleScript" {
with adrparams^ {
return (buildReturn (adrscript^ (pathArgs, httpSearchArgs, username, password, fromUser, clientAddress, serverName, serverPort, scriptName, contentType, referer, userAgent, action, actionPath, postArgs, method, clientIP, fullRequest)))}};
"UserTalk" {
return (buildReturn (adrscript^ (adrparams)))}}}; <<call the CGI script, return the result
codeType { << run script
return (buildReturn (adrscript^ (adrparams)))}; <<call the CGI script, return the result
outlineType; <<return text or html
stringType; << return text or html
wpTextType { << return text or html
local (holder = string (adrscript^));
holder = webServer.processMacros (holder, adrparams);
if string.patternMatch ("<html>", string.lower (holder)) > 0 {
return (buildReturn (webserver.httpHeader () + holder))}
else {
return (buildReturn (webserver.httpHeader ("200 OK", "text/plain") + holder))}};
binaryType { <<determine mime-type and return
local (typeTest = getBinaryType (adrscript^));
if defined (user.webServer.prefs.mimeTypes.[typeTest]) {
with user.webServer.prefs.mimeTypes {
return (buildReturn (webserver.httpHeader ("200 OK", typeTest^) + string (adrscript^)))}}}}
else {
return (buildReturn (webserver.errorMessage (adrscript + " is not a servable object.")))}}
else {
semaphores.unlock ("");
return (webserver.errorMessage (tryError, adrparams))}}
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.