ADDED modules/httpd/build/content.inc Index: modules/httpd/build/content.inc ================================================================== --- /dev/null +++ modules/httpd/build/content.inc @@ -0,0 +1,94 @@ +[section {Class ::httpd::content}] + +The httpd module includes several ready to use implementations of content mixins +for common use cases. Options are passed in to the [cmd add_uri] method of the server. + +[section {Class ::httpd::content.cgi}] + +An implementation to relay requests to process which will accept post data +streamed in vie stdin, and sent a reply streamed to stdout. + +[list_begin definitions] +[call method cgi_info] + +Mandatory method to be replaced by the end user. If needed, activates the +process to proxy, and then returns a list of three values: + +[arg exec] - The arguments to send to exec to fire off the responding process, minus the stdin/stdout redirection. + +[list_end] + +[section {Class ::httpd::content.file}] + +An implementation to deliver files from the local file system. + +[list_begin definitions] + +[call option [cmd path]] + +The root directory on the local file system to be exposed via http. + +[call option [cmd prefix]] + +The prefix of the URI portion to ignore when calculating relative file paths. +[list_end] + +[section {Class ::httpd::content.proxy}] + +An implementation to relay requests to another HTTP server, and relay +the results back across the request channel. + +[list_begin definitions] +[call method proxy_info] + +Mandatory method to be replaced by the end user. If needed, activates the +process to proxy, and then returns a list of three values: + +[arg proxyhost] - The hostname where the proxy is located + +[arg proxyport] - The port to connect to + +[arg proxyscript] - A pre-amble block of text to send prior to the mirrored request + +[list_end] + +[section {Class ::httpd::content.scgi}] + +An implementation to relay requests to a server listening on a socket +expecting SCGI encoded requests, and relay +the results back across the request channel. + +[list_begin definitions] +[call method scgi_info] + +Mandatory method to be replaced by the end user. If needed, activates the +process to proxy, and then returns a list of three values: + +[arg scgihost] - The hostname where the scgi listener is located + +[arg scgiport] - The port to connect to + +[arg scgiscript] - The contents of the [arg SCRIPT_NAME] header to be sent + +[list_end] + +[section {Class ::httpd::content.websocket}] + +A placeholder for a future implementation to manage requests that can expect to be +promoted to a Websocket. Currently it is an empty class. + +[section {SCGI Server Functions}] + +The HTTP module also provides an SCGI server implementation, as well as an HTTP +implementation. To use the SCGI functions, create an object of the [cmd http::server.scgi] +class instead of the [cmd http::server] class. + +[section {Class ::httpd::reply.scgi}] + +An modified [cmd http::reply] implementation that understands how to deal with +netstring encoded headers. + +[section {Class ::httpd::server.scgi}] + +A modified [cmd http::server] which is tailored to replying to request according to +the SCGI standard instead of the HTTP standard. DELETED modules/httpd/build/content.man Index: modules/httpd/build/content.man ================================================================== --- modules/httpd/build/content.man +++ /dev/null @@ -1,94 +0,0 @@ -[section {Class ::httpd::content}] - -The httpd module includes several ready to use implementations of content mixins -for common use cases. Options are passed in to the [cmd add_uri] method of the server. - -[section {Class ::httpd::content.cgi}] - -An implementation to relay requests to process which will accept post data -streamed in vie stdin, and sent a reply streamed to stdout. - -[list_begin definitions] -[call method cgi_info] - -Mandatory method to be replaced by the end user. If needed, activates the -process to proxy, and then returns a list of three values: - -[arg exec] - The arguments to send to exec to fire off the responding process, minus the stdin/stdout redirection. - -[list_end] - -[section {Class ::httpd::content.file}] - -An implementation to deliver files from the local file system. - -[list_begin definitions] - -[call option [cmd path]] - -The root directory on the local file system to be exposed via http. - -[call option [cmd prefix]] - -The prefix of the URI portion to ignore when calculating relative file paths. -[list_end] - -[section {Class ::httpd::content.proxy}] - -An implementation to relay requests to another HTTP server, and relay -the results back across the request channel. - -[list_begin definitions] -[call method proxy_info] - -Mandatory method to be replaced by the end user. If needed, activates the -process to proxy, and then returns a list of three values: - -[arg proxyhost] - The hostname where the proxy is located - -[arg proxyport] - The port to connect to - -[arg proxyscript] - A pre-amble block of text to send prior to the mirrored request - -[list_end] - -[section {Class ::httpd::content.scgi}] - -An implementation to relay requests to a server listening on a socket -expecting SCGI encoded requests, and relay -the results back across the request channel. - -[list_begin definitions] -[call method scgi_info] - -Mandatory method to be replaced by the end user. If needed, activates the -process to proxy, and then returns a list of three values: - -[arg scgihost] - The hostname where the scgi listener is located - -[arg scgiport] - The port to connect to - -[arg scgiscript] - The contents of the [arg SCRIPT_NAME] header to be sent - -[list_end] - -[section {Class ::httpd::content.websocket}] - -A placeholder for a future implementation to manage requests that can expect to be -promoted to a Websocket. Currently it is an empty class. - -[section {SCGI Server Functions}] - -The HTTP module also provides an SCGI server implementation, as well as an HTTP -implementation. To use the SCGI functions, create an object of the [cmd http::server.scgi] -class instead of the [cmd http::server] class. - -[section {Class ::httpd::reply.scgi}] - -An modified [cmd http::reply] implementation that understands how to deal with -netstring encoded headers. - -[section {Class ::httpd::server.scgi}] - -A modified [cmd http::server] which is tailored to replying to request according to -the SCGI standard instead of the HTTP standard. ADDED modules/httpd/build/reply.inc Index: modules/httpd/build/reply.inc ================================================================== --- /dev/null +++ modules/httpd/build/reply.inc @@ -0,0 +1,297 @@ +[section {Class ::httpd::reply}] + +A class which shephards a request through the process of generating a +reply. + +The socket associated with the reply is available at all times as the [arg chan] +variable. + +The process of generating a reply begins with an [cmd httpd::server] generating a +[cmd http::class] object, mixing in a set of behaviors and then invoking the reply +object's [cmd dispatch] method. + +In normal operations the [cmd dispatch] method: + +[list_begin enumerated] + +[enum] +Invokes the [cmd reset] method for the object to populate default headers. + +[enum] +Invokes the [cmd HttpHeaders] method to stream the MIME headers out of the socket + +[enum] +Invokes the [cmd {request parse}] method to convert the stream of MIME headers into a +dict that can be read via the [cmd request] method. + +[enum] +Stores the raw stream of MIME headers in the [arg rawrequest] variable of the object. + +[enum] +Invokes the [cmd content] method for the object, generating an call to the [cmd error] +method if an exception is raised. + +[enum] +Invokes the [cmd output] method for the object +[list_end] + +[para] + +[section {Reply Method Ensembles}] + +The [cmd http::reply] class and its derivatives maintain several variables as dictionaries +internally. Access to these dictionaries is managed through a dedicated ensemble. The +ensemble implements most of the same behaviors as the [cmd dict] command. + +Each ensemble implements the following methods above, beyond, or modifying standard dicts: + +[list_begin definitions] + +[call method [cmd ENSEMBLE::add] [arg field] [arg element]] + +Add [arg element] to a list stored in [arg field], but only if it is not already present om the list. + +[call method [cmd ENSEMBLE::dump]] + +Return the current contents of the data structure as a key/value list. + +[call method [cmd ENSEMBLE::get] [arg field]] + +Return the value of the field [arg field], or an empty string if it does not exist. + +[call method [cmd ENSEMBLE::reset]] + +Return a key/value list of the default contents for this data structure. + +[call method [cmd ENSEMBLE::remove] [arg field] [arg element]] + +Remove all instances of [arg element] from the list stored in [arg field]. + +[call method [cmd ENSEMBLE::replace] [arg keyvaluelist]] + +Replace the internal dict with the contents of [arg keyvaluelist] + +[call method [cmd ENSEMBLE::reset]] + +Replace the internal dict with the default state. + +[call method [cmd ENSEMBLE::set] [arg field] [arg value]] + +Set the value of [arg field] to [arg value]. + +[list_end] + +[section {Reply Method Ensemble: http_info}] + +Manages HTTP headers passed in by the server. + +Ensemble Methods: + +[list_begin definitions] + +[call method [cmd http_info::netstring]] + +Return the contents of this data structure as a netstring encoded block. + +[list_end] + +[section {Reply Method Ensemble: request}] + +Managed data from MIME headers of the request. + +[list_begin definitions] + +[call method [cmd request::parse] [arg string]] + +Replace the contents of the data structure with information encoded in a MIME +formatted block of text ([arg string]). + +[list_end] + +[section {Reply Method Ensemble: reply}] + +Manage the headers sent in the reply. + + +[list_begin definitions] + +[call method [cmd reply::output]] + +Return the contents of this data structure as a MIME encoded block appropriate +for an HTTP response. + +[list_end] + +[section {Reply Methods}] + +[list_begin definitions] +[call method [cmd close]] + +Terminate the transaction, and close the socket. + +[call method [cmd HttpHeaders] [arg sock] [arg ?debug?]] + +Stream MIME headers from the socket [arg sock], stopping at an empty line. Returns +the stream as a block of text. + +[call method [cmd dispatch] [arg newsock] [arg datastate]] + +Take over control of the socket [arg newsock], and store that as the [arg chan] variable +for the object. This method runs through all of the steps of reading HTTP headers, generating +content, and closing the connection. (See class writetup). + +[call method [cmd error] [arg code] [arg ?message?] [arg ?errorInfo?]] + +Generate an error message of the specified [arg code], and display the [arg message] as the +reason for the exception. [arg errorInfo] is passed in from calls, but how or if it should be +displayed is a prerogative of the developer. + +[call method [cmd content]] + +Generate the content for the reply. This method is intended to be replaced by the mixin. + +Developers have the option of streaming output to a buffer via the [cmd puts] method of the +reply, or simply populating the [arg reply_body] variable of the object. +The information returned by the [cmd content] method is not interpreted in any way. + +If an exception is thrown (via the [cmd error] command in Tcl, for example) the caller will +auto-generate a 500 {Internal Error} message. + +A typical implementation of [cmd content] look like: + +[example { + +tool::define ::test::content.file { + superclass ::httpd::content.file + # Return a file + # Note: this is using the content.file mixin which looks for the reply_file variable + # and will auto-compute the Content-Type + method content {} { + my reset + set doc_root [my http_info get doc_root] + my variable reply_file + set reply_file [file join $doc_root index.html] + } +} +tool::define ::test::content.time { + # return the current system time + method content {} { + my variable reply_body + my reply set Content-Type text/plain + set reply_body [clock seconds] + } +} +tool::define ::test::content.echo { + method content {} { + my variable reply_body + my reply set Content-Type [my request get CONTENT_TYPE] + set reply_body [my PostData [my request get CONTENT_LENGTH]] + } +} +tool::define ::test::content.form_handler { + method content {} { + set form [my FormData] + my reply set Content-Type {text/html; charset=UTF-8} + my puts [my html header {My Dynamic Page}] + my puts "
" + my puts "You Sent" + my puts "
$f |
---|
" + my puts "Send some info:
" + my puts "