httpd 1.6 '''''' ''Tcl Web Server'' HTTP protocol implementation ---- '''SYNOPSIS''' package require '''httpd ?1.6?''' * '''Httpd_Init''' * '''Httpd_Shutdown''' * '''Httpd_RegisterShutdown''' ''cmd'' * '''Httpd_Server''' ?''port''? ?''name''? ?''ipaddr''? * '''Httpd_ServerShutdown''' * '''Httpd_SecureServer''' ?''port''? ?''name''? ?''ipaddr''? * '''Httpd_SecureServerShutdown''' * '''Httpd_CurrentSocket''' ?''sock''? * '''Httpd_Webmaster''' ?''email''? * '''Httpd_VirtualHost''' ''host file'' * '''Httpd_VirtualHosts''' ''hostNames file'' * '''Httpd_Port''' ?''sock''? * '''Httpd_SecurePort''' * '''Httpd_Peername''' ''sock'' * '''Httpd_Protocol''' ''sock'' * '''Httpd_Name''' ''sock'' * '''Httpd_SelfUrl''' ''url'' ?''sock''? * '''Httpd_CompletionCallback''' ''sock cmd'' * '''Httpd_SockClose''' ''sock closeit'' ?''message''? * '''Httpd_RequestComplete''' ''sock'' * '''Httpd_Suspend''' ''sock'' ?''timeout''? * '''Httpd_Resume''' ''sock'' ?''timeout''? * '''Httpd_Pair''' ''sock fd'' * '''Httpd_DumpHeaders''' ''sock'' * '''Httpd_PostDataSize''' ''sock'' * '''Httpd_GetPostData''' ''sock varName'' ?''size''? * '''Httpd_ReadPostDataAsync''' ''sock cmd'' * '''Httpd_GetPostDataAsync''' ''sock varName blockSize cmd'' * '''Httpd_CopyPostData''' ''sock channel cmd'' * '''Httpd_GetPostChannel''' ''sock sizeName'' * '''Httpd_SetCookie''' ''sock cookie'' ?''modify''? * '''Httpd_RemoveCookies''' ''sock pattern'' * '''Httpd_ReturnFile''' ''sock type path'' ?''offset''? * '''Httpd_ReturnData''' ''sock type content'' ?''code''? ?''close''? * '''Httpd_ReturnCacheableData''' ''sock type content date'' ?''code''? * '''Httpd_Error''' ''sock code'' ?''detail''? * '''Httpd_Redirect''' ''newurl sock'' * '''Httpd_RedirectSelf''' ''newurl sock'' * '''Httpd_RedirectDir''' ''sock'' * '''Httpd_NotModified''' ''sock'' * '''Httpd_RequestAuth''' ''sock type realm'' ---- '''DESCRIPTION''' The package '''httpd''' implements the server side of the HTTP protocol and as such can be used as the core of any Tcl based web server implementation. One such full-fledged web server is '''tclhttpd'''. ''Note:'' This package does ''not'' provide the ability to register a callback when a request was received completely. It dispatches all collected requests to the package '''httpd::url''' instead. This package then provides an interface for the definition and usage of a database mapping from urls to implementations, i.e. Tcl commands handling them. The API is divided into the following four categories, each described in its own section. ---- '''Server Management''' Operations to handle the server at large. '''Httpd_Init''' : Initializes the internal data structures of the package. Has to be called before '''Httpd_Server''' or '''Httpd_SecureServer'''. Some of the others public commands of this package will call this command on their own if it had not been called before. '''Httpd_Shutdown''' : A convenience command. It calls '''Httpd_ServerShutdown''', '''Httpd_SecureServerShutdown''', and all callback commands registered with the package through '''Httpd_RegisterShutdown'''. The registered callbacks are called before the two shutdown commands of this package. Any errors thrown by the callbacks are logged via the package '''httpd::log''', but ignored otherwise. The result of the command is a boolean value. '''false''' signals to the caller that at least one of the registered callbacks threw an error. '''Httpd_RegisterShutdown''' ''cmd'': Registers ''cmd'' as a callback which will be called when the server is shutdown via '''Httpd_Shutdown'''. Errors thrown by ''cmd'' during its invocation are logged, but otherwise ignored. Any result returned by ''cmd'' is ignored]]. The ''cmd'' is called without any argument. '''Httpd_Server''' ?''port''? ?''name''? ?''ipaddr''?: Starts the server by listening for connections on the desired ''port''. This may be re-run to re-start the server. If no ''port'' was specified it defaults to '''80'''. The caller can specify the qualified host name returned in the Host field of each server response. This defaults to the result of '''info hostname'''. A non-default interface address can be specified through ''ipaddr''. Otherwise '''IP_ADDR_ANY''' is used so the server can accept connections from any interface. Automatically calls '''Httpd_Init''' if it has not been done manually before. The command returns the empty string. ''Note:'' It is possible for the package to have the server listen on multiple ports, just call this command more than once. However note that the package remembers only the last port opened for listening. This means that a shutdown will stop only connections on the last port opened with this command, and nothing else. '''Httpd_ServerShutdown''' : This command closes the listening socket of the server. Existing HTTP connections are kept open, but no new connection will be possible. '''Httpd_SecureServer''' ?''port''? ?''name''? ?''ipaddr''?: Like '''Httpd_Server''', except that additional setup for SSL is performed, requiring the package '''TLS''', and that the port defaults to '''443'''. '''Httpd_SecureServerShutdown''' : Like '''Httpd_ServerShutdown''', except that listening socket for secure connections is closed. '''Httpd_CurrentSocket''' ?''sock''?: If a ''sock'' is specified it is remembered globally as the current socket. Otherwise the globally remembered current socket is returned. '''Httpd_Webmaster''' ?''email''?: Defines a global ''email'' address for the webmaster. If no address was specified the last address set is returned. '''Httpd_VirtualHost''' ''host file'': Undocumented in the sources ... '''Httpd_VirtualHosts''' ''hostNames file'': Undocumented in the sources ... '''Httpd''': A global array variable containing global configuration information. '''bufsize''': Chunk size for copies. For example POST data. '''initialized''': Exists and true after package was initialized by '''Httpd_Init'''. '''ipaddr''': Non-default ipaddr for the server (for multiple interfaces). '''library''': Path of the directory containing the Tcl scripts. '''port''': The port this server is serving. '''listen''': The main listening socket id. '''server''': The server ID for the HTTP protocol. '''shutdown''': A list of Tcl callbacks to run when the server shuts down. '''sockblock''': Blocking mode value for sockets (normally this should be 0). '''timeout1''': Time before the server closes a kept-alive socket (msecs). '''timeout2''': Time before the server kills an in-progress transaction (msecs). '''timeout3''': Time allowed to drain extra post data. '''version''': The version number. '''maxused''': Max number of transactions per socket (keep alive). ---- '''Connection Management''' Management operations for connections. '''Httpd$sock''': The state of the open connection is stored in global variables, one per connection. These variables are arrays and have the prefix '''Httpd'''. Their distinguishing suffix is the handle of the channel (socket) they belong to. This means that any user code which has a connection handle can import the connection state into its current scope via a command like upvar #0 Httpd$sock data The elements of this array are documented here. URL implementations are free to hang additional state off the data array as long as they do not clobber the elements documented below. These keys in the state array are semi-public, or "well known". There are a few API's to access them, but URL implementations can rely on these: '''self''': A list of protocol ('''http''' or '''https'''), name, and port that capture the server-side of the socket address. Available through the '''Httpd_Protocol''', '''Httpd_Name''', and '''Httpd_Port''' API's. '''uri''': The complete URL, including protocol, servername, and query. '''proto''': Either '''http''' or '''https'''. '''url''': The URL after the server name and before the '?'. In other words, the url path. '''query''': The URL after the '?'. '''ipaddr''': The remote client's IP address. '''cert''': Client certificate (The result of '''tls::status'''). This is only relevant to connections coming in over a secure port. '''host''': The host specified in the URL, if any (proxy case). '''port''': The port specified in the URL, if any. '''mime,*''': HTTP header request lines (e.g., mime,content-type). '''count''': Content-Length. '''set-cookie''': List of Set-Cookie headers to stick into the response. Use '''Httpd_SetCookie''' to append to this. '''prefix''': Set by '''Url_Dispatch''' (in package '''httpd::url''') to be the URL domain prefix. '''suffix''': Set by '''Url_Dispatch''' to be the URL domain suffix. '''auth_type''': Set by the package '''httpd::auth''' to "Basic", etc. '''remote_user''': Set by the package '''httpd::auth''' to the username from Basic authentication. '''session''': Set by the package '''httpd::auth''' to the "realm,$username" from Basic auth. You can overwrite this session ID with something more useful. '''Internal''': Fields used by this module. '''left''': The number of keep-alive connections allowed. '''cancel''': AfterID of event that will terminate the connection on timeout. '''state''': State of request processing. '''version''': 1.0 or 1.1. '''line''': The current line of the HTTP request. '''mimeorder''': List indicating the order of MIME header lines. '''key''': Current header key. '''checkNewLine''': State bit for Netscape SSL newline bug hack. '''callback''': Command to invoke when request has completed. '''file_size''': Size of file returned by '''Httpd_ReturnFile'''. '''infile''': Open file used by '''fcopy''' to return a file, or CGI pipe. '''env''': During the dispatch of a request the element '''HTTP_CHANNEL''' contains the channel handle of the connection for that request. ''Danger:'' This is true only until the URL implementation enters the event loop on its own. After that this element can be overwritten by another request served in parallel. In other words this information is not reliable. A package using this variable is '''httpd::cookie''', especially the command '''Cookie_Get'''. It would have been better to provide a cookie retrieval command in this API here. '''Httpd_Port''' ?''sock''?: If no socket handle ''sock'' is provided the regular (non-secure) listening port is returned. Otherwise the port for the connection running over the specified socket is returned. '''Httpd_SecurePort''' : Returns the port number of the secure listening port, if a secure server was activated. An empty string will be returned if no secure server is running. '''Httpd_Peername''' ''sock'': Returns the DNS name of the client connected to the server over the socket ''sock''. '''Httpd_Protocol''' ''sock'': Returns the protocol for the connection. Either '''http''' or '''https'''. Used by '''Httpd_SelfUrl'''. '''Httpd_Name''' ''sock'': Return the server name for the connection ''sock''. Used by '''Httpd_SelfUrl'''. '''Httpd_SelfUrl''' ''url'' ?''sock''?: This command takes a server-relative ''url'' and returns the equivalent absolute url (containing server name, port, etc). The connection ''sock'' is required to be able to distinguish between regular and secure ports. '''Httpd_CompletionCallback''' ''sock cmd'': Register a procedure ''cmd'' to be called when an HTTP request is completed on the socket ''sock'', either normally or forcibly closed. This gives a URL implementation a guaranteed callback to clean up or log requests. The callback will be invoked with two additional arguments, ''sock'' and a string, in this order. The string can be empty. If the string is not empty it will contain an error message. Note that completed here does ''not'' mean completion of getting all input for the request, but rather that the response to the request was completed and sent to the client as well. '''Httpd_SockClose''' ''sock closeit'' ?''message''?: "Closes" the connection ''sock''. ''Note'' that the socket channel the connection runs over might actually remain open for a keep-alive connection. Calling this means a HTTP transaction is fully complete. The optional ''message'' defaults to '''Close'''. If the boolean flag ''closeit'' is set the socket for the connection is closed no matter what type the connection. This cleans up all state associated with the connection, including after events for timeouts, the data array, and fileevents. '''Httpd_RequestComplete''' ''sock'': Detect if a request has been sent and completed. The holder of a socket might need to know if the URL request was completed with one of the return-data commands, or is still lingering open. The result is a boolean value. '''true''' signals that the last request was fully completed. '''Httpd_Suspend''' ''sock'' ?''timeout''?: This command, and its counterpart '''Httpd_Resume''' can be used by the backend handling an url to temporarily disable and re-enable the reception of data from the connection ''sock''. For example if there are long-lasting server-side operations to handle the request which block and then enter the event loop on their own. If a ''timeout'' is set for the suspension the pending request will be forcibly aborted with an error reply when the time runs out. An example user of this mechanism are the all commands reading posted data (see below). They suspend normal operation, take over the socket to read the posted data and when reactivate the normal processing. '''Httpd_Resume''' ''sock'' ?''timeout''?: See '''Httpd_Suspend''' above. '''Httpd_Pair''' ''sock fd'': Connects the connection coming in over ''sock'' with the channel ''fd''. Any data arriving on ''sock'' is copied over to ''fd'' and vice versa. If either channel is closed the other will be closed too. This is the basic mechanism to redirect the internal processing of a request to an external application, i.e. for CGI processing, or to a a subordinate web server. '''Httpd_DumpHeaders''' ''sock'': This command returns a dictionary containing the received HTTP protocol headers for the connection ''sock''. The keys are header names without the trailing colon and mapped to lower case (e.g., content-type). The system adds two pseudo-headers: One that contains the original request URL; its name is "url". Another that contains the request protocol; its name is "method". There are no duplications in the header keys. If any headers were repeated, their values were combined by separating them with commas. ---- '''POST Management and Reading''' The commands listed here technically belong to the section '''Connection Management''', but are important enough to warrant their own section. They deal with data which was POST'ed as part of a request (form data, uploaded files). '''Httpd_PostDataSize''' ''sock'': Returns the amount of post data available in bytes for the current request, i.e. sent over the connection associated with the socket ''sock''. '''Httpd_GetPostData''' ''sock varName'' ?''size''?: Synchronously reads posted data from the socket ''sock'' and appends it to the buffer variable ''varName''. If ''size'' is not specified '''Httpd(bufsize)''' bytes will be read. The command returns the total number of bytes accumulated so far. '''Httpd_ReadPostDataAsync''' ''sock cmd'': Activates the asynchronous reading of posted data from the socket ''sock'', as it arrives. Whenever more posted data arrives on the socket ''sock'' the specified command prefix '''cmd''' will be called. This is a convenience command wrapped around '''Httpd_GetPostDataAsync''' (see below) setting things up so that arriving data is added to the '''query''' component of the status variable for the connection. '''Httpd_GetPostDataAsync''' ''sock varName blockSize cmd'': Activates the asynchronous reading of posted data from the socket ''sock'', as it arrives. Whenever more posted data arrives on the socket ''sock'' the data is appended to the specified variable (''varName'') and specified command prefix '''cmd''' will be called. The data is read in ''blocksize'' chunks. The specified command prefix ''cmd'' is called with three additional arguments, the ''sock'', the ''varName'', and an additional string, either empty or containing an error message, in this order. '''Httpd_CopyPostData''' ''sock channel cmd'': An alternative to '''Httpd_GetPostDataAsync'''. Sets up the asynchronous copying of the data posted to the socket ''sock'' to the ''channel''. The command prefix ''cmd'' is called when the copying completed, with two additional argument, ''sock'' and ''channel'', in this order. '''Httpd_GetPostChannel''' ''sock sizeName'': Returns the socket ''sock'' containing the posted data, as long as there is POST data to read for the connection over this socket. If no data is present (anymore) an error will be thrown. The number of bytes present is written into the variable ''sizeName''. ---- '''Result Management and Generation''' The commands listed here technically belong to the section '''Connection Management''', but are important enough to warrant their own section. They deal with the generation of replies in general, predefined and generic. The latter ones can to be used by the packages implementing the handling of urls '''Httpd_SetCookie''' ''sock cookie'' ?''modify''?: Add the encoded ''cookie'' to the reply for the current request on connection ''sock''. This command has to be called before using either '''Httpd_ReturnFile''' or '''Httpd_ReturnData'''. See ''http://wp.netscape.com/newsref/std/cookie_spec.html'' for the specification of what cookies are and how they work. See package '''httpd::cookie''' for commands to help in the creation of cookies. '''Httpd_RemoveCookies''' ''sock pattern'': Remove previously set cookies from the reply for the current request on connection ''sock''. Any cookies that match the glob ''pattern'' are removed. This is useful for expiring a cookie that was previously set. '''Httpd_ReturnFile''' ''sock type path'' ?''offset''?: Sends the contents of the file with name ''path'' and mime type ''type'' as the reply to the current request on the connection ''sock''. If an ''offset'' is specified that number of bytes are skipped from the start of the file. The request will be completed by the time this command returns. This implies that completion callback have been called and that ''sock'' has been closed. '''Httpd_ReturnData''' ''sock type content'' ?''code''? ?''close''?: Like '''Httpd_ReturnFile''', except that the content is specified directly as an argument to the command. This command also allows the specification of an HTTP return code. If none is specified it will default to '''200''' (Data follows). Beyond that the caller can order the command to keep the connection ''sock'' open after the data was sent ("''close'' == 1"). By default the connection would be closed, like it is done by '''Httpd_ReturnFile'''. '''Httpd_ReturnCacheableData''' ''sock type content date'' ?''code''?: Like '''Httpd_ReturnData''', except that a Last-Modified header is part of the reply so that proxy servers can cache it. The information for this header line is taken from ''date''. In contrast to '''Httpd_ReturnData''' the connection is always closed. This is like for '''Httpd_ReturnFile'''. -- ''date is in seconds.'' '''Httpd_Error''' ''sock code'' ?''detail''?: Send the error message ''detail'' with HTTP response ''code'', log it, and close the connection ''sock''. This is the most basic error response the server can generate. Other packages may generate their own error responses. The package '''httpd::doc''' is an example of this. '''Httpd_Redirect''' ''newurl sock'': This command generates a redirect to ''newurl'' reply (code 302) and then closes the connection ''sock''. It assumes that ''newurl'' contains an absolute url. '''Httpd_RedirectSelf''' ''newurl sock'': A wrapper around '''Httpd_Redirect''' for a ''newurl'' which is on this server. In other words, this commands expects a server relative url, and not an absolute one. '''Httpd_RedirectDir''' ''sock'': Generate a redirect reply for the connection ''sock'' because the trailing slash is not present on a URL that corresponds to a directory. '''Httpd_NotModified''' ''sock'': This command generates a "Not modified" reply (code 304) and then closes the connection ''sock''. '''Httpd_RequestAuth''' ''sock type realm'': Generates a "Authorization required" reply (code 401) and then closes the connection ''sock''. The type is usually '''basic'''. The data in ''realm'' is used by browsers to cache credentials. ---- '''SEE ALSO''' http::log, httpd::config, httpd::cookie, httpd::counter, httpd::logstd, httpd::threadmgr, httpd::url, httpd::version ---- '''KEYWORDS''' http, tclhttpd, web server ---- '''COPYRIGHT''' Copyright (c) 2003 Andreas Kupries ---- [AK] ---- Where does one find this code? - httpd.tcl is part of the [TclHttpd] distribution. ---- [ECS] At least in CVS head data(uri) == data(url) == path. ---- [ECS] Handy function (available in version 1.7 (CVS)) Httpd_AddHeaders sock tag value ?tag value? ... ---- [AL] If I want to create a simple web server without all bells and whistles of tclhttpd, what would be a simple example using httpd.tcl ? Is there a code somewhere ? ---- [[ [Category TclHttpd] ]]