Monday, November 08, 2010 at 12:06 AM.
system.verbs.builtins.webserver.server
on server (adrparamtable, httpRequest=nil) { <<Thursday, November 11, 1999 at 3:09:25 AM by AR <<Implemented as a kernel script in Frontier 6.1. <<Old code <<on server (adrparamtable, httpRequest=nil) <<The entrypoint to Frontier's built in web server. <<paramtable has info about the http request <<client <<inetdConfigTableAdr <<port <<ready <<refcon <<request <<stream <<timeout <<12/19/98; 10:51:51 AM by DW <<wait until Frontier is finished starting up <<we have to be concerned about this when Frontier is running behind a web server such as IIS or WebSTAR. <<10/2/98; 4:36:25 AM by DW <<carefully reviewed the code, minor streamlining, more work to do later <<create a new sub-table of paramtable, stats <<any code in the execution chain can add info to this table <<to start, we're going to record the value of clock.ticks () at various points in the process <<9/17/98; 7:34:33 AM by DW <<added optional httpRequest parameter, allows it to be called directly from tcp.httpClient <<6/4/98 by RAB <<Added call to webserve.util.parseCookies <<while system.temp.Frontier.startingUp //6.0, wait here until Frontier has finished starting up <<if (defined (user.webserver.prefs.flWaitDuringStartup)) and (not user.webserver.prefs.flWaitDuringStartup) //PBS 3/19/99 <<break <<thread.sleepFor (1) << <<new (tabletype, @adrparamtable^.stats) <<adrparamtable^.stats.requestProcessingStarted = clock.ticks () << <<if httpRequest != nil <<adrparamtable^.request = httpRequest <<else <<adrparamtable^.request = string (webserver.util.readUntil (adrparamtable^.stream, "\r\n\r\n", adrparamtable^.timeout)) <<adrparamtable^.request = string (webserver.util.readUntil (adrparamtable^.stream, "\r\n\r\n", adrparamtable^.timeout)) << <<new (tableType, @adrparamtable^.requestHeaders) <<adrparamtable^.firstLine = webserver.util.parseHeaders (adrparamtable^.request, @adrparamtable^.requestHeaders) << <<if defined (adrparamtable^.requestHeaders.Expect) <<return (webserver.util.buildResponse (417)) // we can't live up to the client's expectations << <<bundle //now that the headers are parsed, make sure we have the whole body <<adrparamtable^.requestBody = "" <<if defined (adrparamtable^.requestHeaders.["Content-Length"]) <<local (len = number (adrparamtable^.requestHeaders.["Content-Length"])) <<local (ix = string.patternmatch ("\r\n\r\n", adrparamtable^.request)) <<adrparamtable^.requestBody = string.delete (adrparamtable^.request, 1, ix + 3) << <<if sizeOf (adrparamtable^.requestBody) < len <<local (bytesToRead = len - sizeOf (adrparamtable^.requestBody)) <<local (bytes = webserver.util.readBytes (adrparamtable^.stream, bytesToRead, adrparamtable^.timeout)) <<adrparamtable^.requestBody = adrparamtable^.requestBody + bytes <<if sizeOf (adrparamtable^.requestBody) < len <<we couldn't read the whole body for some reason <<return (webserver.util.buildResponse (400, nil, webserver.util.buildErrorPage ("400 Bad Request", "The request body couldn't be read."))) <<if sizeOf (adrparamtable^.requestBody) > len // strip off any traling junk <<adrparamtable^.requestBody = string.delete (adrparamtable^.requestBody, len +1, infinity) << <<local (path, httpVersion) <<bundle //check for illegal requests <<path = string.nthField (adrparamtable^.firstLine, " ", 2) <<if !(path beginsWith "/") && !(path beginsWith "http:") && (path != "*") <<return (webserver.util.buildResponse (400, nil, webserver.util.buildErrorPage ("400 Bad Request", "All URIs must begin with / or http:"))) <<if path beginsWith "http://" <<it's a future-style full URL <<local (pathParts = string.urlSplit (path)) <<path = "/" + pathParts[3] <<httpVersion = string.nthField (adrparamtable^.firstLine, " ", 3) <<httpVersion = string.nthField (httpVersion, "/", 2) <<if httpVersion == "1.1" <<if not defined (adrparamtable^.requestHeaders.Host) <<Every HTTP/1.1 request must include a Host header <<return (webserver.util.buildResponse (400, nil, webserver.util.buildErrorPage ("400 Bad Request", "Every HTTP/1.1 request must include a Host header"))) <<else //PBS 2/28/99: don't call date.versionLessThan on every request: most requests are HTTP 1.1 <<if not date.versionLessThan (httpVersion, "2.0") <<if the version is 2.0 or greater, we don't know how to handle it <<return (webserver.util.buildResponse (505, nil, webserver.util.buildErrorPage ("505 Version Not Supported", "This server does not support HTTP/" + httpVersion))) << <<bundle //set up searchArgs and pathArgs <<adrparamtable^.searchArgs = "" <<if path contains "?" <<adrparamtable^.searchArgs = string.nthField (path, "?", 2) <<path = string.nthField (path, "?", 1) <<adrparamtable^.pathArgs = "" <<if not (path contains "$") <<path = string.replace (path, "%24", "$") //PBS 5/10/99: fix for proxy servers that url encode the $ <<if path contains "$" <<adrparamtable^.pathArgs = string.nthField (path, "$", 2) <<path = string.nthField (path, "$", 1) << <<webserver.util.parseCookies (adrparamtable) << <<adrparamtable^.URI = path <<adrparamtable^.path = path <<adrparamtable^.method = string.nthField (adrparamtable^.firstLine, " ", 1) <<try {adrparamtable^.host = adrparamtable^.requestHeaders.host} //PBS 7/31/98 << <<local (s = webserver.dispatch (adrparamtable)) <<bundle //6.0, maintain stats, if the feature is turned on <<if user.webserver.prefs.flStats <<local (threads = Frontier.countthreads ()) <<if threads > user.webserver.stats.maxConnections <<user.webserver.stats.maxConnections = threads <<local (memavail = sys.memavail ()) <<if memavail > user.webserver.stats.maxmemavail <<user.webserver.stats.maxmemavail = memavail <<if memavail < user.webserver.stats.minmemavail <<user.webserver.stats.minmemavail = memavail <<user.webserver.stats.hits++ <<return (s) kernel (webserver.server)}
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.