REBOL [
Title: "FastCGI Broker"
File: %fcgi-broker.r
Date: 15-Dec-2005
Author: "Pascal Hurni"
Version: 1.0.1
Library: [
level: 'intermediate
platform: 'windows
type: [module tool]
domain: [cgi http html extension win-api]
tested-under: [w2k core 2.5.6 view 1.3.1 view 1.3.2]
support: http://mortimer.devcave.net/projects/rebfcgi
license: 'bsd
see-also: http://mortimer.devcave.net
]
Purpose: {Rebol script broker for a hooked rebol interpreter launched as a FastCGI application.
This is the root script which runs others scripts on request of the FastCGI peer.
This enables REBOL/Core or REBOL/View to act as a FastCGI application without the need
for REBOL/Command.
This script only works on Windows with a patched REBOL interpreter.
Details available at http://mortimer.devcave.net/projects/rebfcgi
}
]
fcgi-broker: context [
;-- buffer for the command
command: make string! 8192
;-- magic value to indicate 'end of command'
magic: to-binary {^~ReBfCgI}
;-- alias for the input stream
stdin: system/ports/input
;-- Function that waits for the next request
wait-for-command: func [port [port!] /local result][
;-- commands are line oriented
set-modes stdin [lines: true]
;-- Read stdin until we find the magic marker (this is to skip previous stdin data not read)
while [not error? result: try [command: copy first port]][
if command: find/tail command magic [
return command
]
]
;-- Loop broken by an error, is it an EOF ?
if not-equal? 315 get in disarm result 'code [
;-- No, show it
probe result
]
none
]
;-- The broker itself
run: has [result][
;-- Keep original words
quit': :quit
halt': :halt
;-- Quit and Halt executed in the script, should simply abort the do block
quit: halt: func [[throw]][return none]
;-- Wait and get next FCGI command
while [command: wait-for-command stdin][
;-- Execute the command which will set up the system/options/cgi
do command
;-- Launch the script (DO DOES is for encapsulating the try block in a function so that QUIT and HALT can simply RETURN)
if do does [error? set/any 'result try [do to-rebol-file system/options/cgi/path-translated]][
;-- Output error to web server
print rejoin ["Content-Type: text/plain^/^/" mold disarm result "
"]
]
;-- Put the 'End of command' marker in the output stream
write-io system/ports/output magic length? magic
;-- This tries to force a thread scheduling, so that the FcgiHandler can catch the magic marker (it has a higher priority)
wait 0.01
]
;-- No more commands, end.
quit: :quit'
halt: :halt'
]
]
;-- Do it!
fcgi-broker/run