In yet another in a long string of rapid-fire ideas turned into alpha quality code, I'd like to annouce the availability of the Pike ScriptRunner. ScriptRunner is a FastCGI application that will (hopefully) run under pretty much any web server that supports FastCGI. The ScriptRunner allow you to run pike scripts under non-pike based web servers. Because ScriptRunner uses FastCGI, its performance should be close to embedded language solutions like mod_perl, but with a lot less worries about security and overflows. With ScriptRunner you can introduce all of your friends to Pike without forcing them to suffer bad performance or the (more likely) attachment to Apache. In addition, ScriptRunner does a lot of the unpleasant work of parsing incoming requests, allowing you to get right to the task of writing your code. Right now, it's pretty early on in its development, so there are a lot of niceties present in Roxen or Caudium that aren't available, and it's not terribly well tested, so it could have some nasty bugs. Enough raw functionality is available to be highly useful; hopefully there will be interest in improving things in this area. ScriptRunner contains code written by others over the years; this is really more of a gathering of snippets into something more readily useful to others. Requirements: Pike 7.6+ libfastcgi (available from http://www.fastcgi.com) Public.Web.FastCGI (available from http://www.siriushosting.com/pike/fastcgi.html) Features: - Multi-threaded request handling - Session persistence - Persistent interpreter - Compiled object caching - Incoming requests are parsed and passed to you in a request id object. - Handles FCGI processing for you. Just return a string or control mapping from your parse() method. Installation: Please visit the ScriptRunner page for more updated information: http://www.gotpike.org/PikeWiki/index.pike?page=PikeApps/Pike+ScriptRunner Basic installation instructions are located in the file INSTALL. Apache users: see the file INSTALL.Apache for information on configuring Apache support for FastCGI. Get the snapshot tarball here: http://buoy.riverweb.com:8080/viewrep/cvs/scriptrunner Add a redirect to convert all requests to (*.pike) to /path/to/scriptrunner.fcgi($1) (actual syntax will vary based on the redirector you're using. For example, if I've installed ScriptRunner so that the ScriptRunner.fcgi is called by the following request: http://www.mysite.com/path/to/ScriptRunner.fcgi and I put a pike script in /some/other/path.pike on my website, I need my redirect to internally change http://www.mysite.com/some/other/path.pike to http://www.mysite.com/path/to/ScriptRunner.fcgi/some/other/path.pike This is a common technique used by PHP and other languages. Alternately, you could use mod_actions to do the same thing: AddHandler scriptrunner-pike-script .pike Action scriptrunner-pike-script /path/to/ScriptRunner.fcgi In the long run, this may be a simpler option. Some example scripts are included to give you a head start. Writing Pike Scripts: First of all, you should know how to write code in the Pike language. It's pretty easy, and if you're accustomed to C-like languages, such as C or Java, you should be able to pick things up in a few minutes. A pike script must impliment the following method: string|mapping parse(RequestID request_id); request_id is an object that contains the request information, all broken down into the most important components. Accessing the scriptrunner application without providing a script file will give you an example of what's contained in the RequestID object. Some important members of a RequestID object: variables: a mapping containing key-value pairs for all passed query and POST variables. ScriptRunner does not differentiate between GET and POST variables. cookies: a mapping containing key-value pairs for all cookies provided to the server during the request. query: the contents of the request string following the ? method: the HTTP method sent by the client. client: an array containing elements of the client agent being used. pragma: a multiset containing any pragma keys sent by the client agent. the most common of these is "no-cache". prot: the http protocol and version, for example: HTTP/1.0. referrer: an array containing the referrer. remoteaddr: the client's ip address remotehost: the client's remote hostname, if available. misc: a mapping containing miscellaneous information about the request. misc->session_variables: if set to use sessions, your script or psp page will have a mapping here that you can add to and which will be maintained across requests. Currently, this can not contain programs or objects. misc->session_id: if set to use sessions, this will be a string containing the current session identifier. Your parse() function can run any pike code you'd like, and when you're done, it should return either a string containing the HTML content to return to the browser, or a "control" mapping. A control mapping is a mapping that contains certain indices that control the response returned to the browser. You'd want to return a mapping if you need to alter the content type of the result, or if you want to add special headers or change the status code. example2.pike gives you an example of a control mapping used to perform a HTTP redirect. Future releases of ScriptRunner will provide convenience functions that will generate appropriate control mappings for you. Until then, Here are the contents (and default falues): ([ /* the result code to return, 200 is "OK" */ "error" : 200 /* the mime content type to return */ "type" : "content/html" /* a string or Stdio.File object containing the data to return. If a File object, the data will be read() from the object. Not required, strictly speaking, but it is normally important to provide. */ "data" : UNDEFINED /* a mapping containing response headers to provide */ "_headers" : UNDEFINED ]) Do note that the contents of this mapping may change once convenience functions arrive. If you find yourself performing a large number of string concatenations to create the result string, you may want to consider using String.Buffer, which can improve the performance of your application in these situations. See the Pike module reference for more information on String.Buffer. Upon successful compilation of your script, it will be instantiated into an object, so you can provide create() and destroy() methods to control startup and shutdown of services required by parse(). Note that upon compilation, scripts are cached. Scripts can currently be reloaded by sending the Pragma: no-cache header (by doing a "super reload" using mozilla based browsers). Do not count on destroy() to be called immediately upon destruction, as there may be a delay between the script being recompiled and garbage collection, which forces destroy() to be called. In the event of a compilation failure, the error will be displayed to the client and written to a log file. Compilation retries will occurr on subsequent requests. In the event of an uncaught error exception, an error and stacktrace will be returned to the browser, as well as written to the log file. Comments, Feedback and Participation: I welcome all of these, especially if you're interested in helping to debug and enhance the code. Contact me if you'd like to help out.