1
2[//000000001]: # (httpd \- Tcl Web Server)
3[//000000002]: # (Generated from file 'httpd\.man' by tcllib/doctools with format 'markdown')
4[//000000003]: # (Copyright &copy; 2018 Sean Woods <yoda@etoyoc\.com>)
5[//000000004]: # (httpd\(n\) 4\.3\.4 tcllib "Tcl Web Server")
6
7<hr> [ <a href="../../../../toc.md">Main Table Of Contents</a> &#124; <a
8href="../../../toc.md">Table Of Contents</a> &#124; <a
9href="../../../../index.md">Keyword Index</a> &#124; <a
10href="../../../../toc0.md">Categories</a> &#124; <a
11href="../../../../toc1.md">Modules</a> &#124; <a
12href="../../../../toc2.md">Applications</a> ] <hr>
13
14# NAME
15
16httpd \- A TclOO and coroutine based web server
17
18# <a name='toc'></a>Table Of Contents
19
20  - [Table Of Contents](#toc)
21
22  - [Synopsis](#synopsis)
23
24  - [Description](#section1)
25
26  - [Minimal Example](#section2)
27
28  - [Classes](#section3)
29
30      - [Class httpd::mime](#subsection1)
31
32      - [Class httpd::reply](#subsection2)
33
34      - [Class httpd::server](#subsection3)
35
36      - [Class httpd::server::dispatch](#subsection4)
37
38      - [Class httpd::content\.redirect](#subsection5)
39
40      - [Class httpd::content\.cache](#subsection6)
41
42      - [Class httpd::content\.template](#subsection7)
43
44      - [Class httpd::content\.file](#subsection8)
45
46      - [Class httpd::content\.exec](#subsection9)
47
48      - [Class httpd::content\.proxy](#subsection10)
49
50      - [Class httpd::content\.cgi](#subsection11)
51
52      - [Class httpd::protocol\.scgi](#subsection12)
53
54      - [Class httpd::content\.scgi](#subsection13)
55
56      - [Class httpd::server\.scgi](#subsection14)
57
58      - [Class httpd::content\.websocket](#subsection15)
59
60      - [Class httpd::plugin](#subsection16)
61
62      - [Class httpd::plugin\.dict\_dispatch](#subsection17)
63
64      - [Class httpd::reply\.memchan](#subsection18)
65
66      - [Class httpd::plugin\.local\_memchan](#subsection19)
67
68  - [AUTHORS](#section4)
69
70  - [Bugs, Ideas, Feedback](#section5)
71
72  - [Keywords](#keywords)
73
74  - [Category](#category)
75
76  - [Copyright](#copyright)
77
78# <a name='synopsis'></a>SYNOPSIS
79
80package require Tcl 8\.6
81package require uuid
82package require clay
83package require coroutine
84package require fileutil
85package require fileutil::magic::filetype
86package require websocket
87package require mime
88package require cron
89package require uri
90package require Markdown
91
92[method __ChannelCopy__ *in* *out* ?*args*?](#1)
93[method __html\_header__ ?*title* ____? ?*args*?](#2)
94[method __html\_footer__ ?*args*?](#3)
95[method __http\_code\_string__ *code*](#4)
96[method __HttpHeaders__ *sock* ?*debug* ____?](#5)
97[method __HttpHeaders\_Default__](#6)
98[method __HttpServerHeaders__](#7)
99[method __MimeParse__ *mimetext*](#8)
100[method __Url\_Decode__ *data*](#9)
101[method __Url\_PathCheck__ *urlsuffix*](#10)
102[method __wait__ *mode* *sock*](#11)
103[variable __ChannelRegister__](#12)
104[variable __reply__](#13)
105[variable __request__](#14)
106[delegate __<server>__](#15)
107[method __constructor__ *ServerObj* ?*args*?](#16)
108[method __destructor__ ?*dictargs*?](#17)
109[method __ChannelRegister__ ?*args*?](#18)
110[method __close__](#19)
111[method __Log\_Dispatched__](#20)
112[method __dispatch__ *newsock* *datastate*](#21)
113[method __Dispatch__](#22)
114[method __html\_header__ *title* ?*args*?](#23)
115[method __html\_footer__ ?*args*?](#24)
116[method __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ *code* ?*msg* ____? ?*errorInfo* ____?](#25)
117[method __content__](#26)
118[method __EncodeStatus__ *status*](#27)
119[method __[log](\.\./log/log\.md)__ *type* ?*info* ____?](#28)
120[method __CoroName__](#29)
121[method __DoOutput__](#30)
122[method __FormData__](#31)
123[method __PostData__ *length*](#32)
124[method __Session\_Load__](#33)
125[method __puts__ *line*](#34)
126[method __RequestFind__ *field*](#35)
127[method __request__ *subcommand* ?*args*?](#36)
128[method __reply__ *subcommand* ?*args*?](#37)
129[method __reset__](#38)
130[method __timeOutCheck__](#39)
131[method __[timestamp](\.\./\.\./\.\./\.\./index\.md\#timestamp)__](#40)
132[variable __template__](#41)
133[variable __url\_patterns__](#42)
134[method __constructor__ *args* ?*port* __auto__? ?*myaddr* __127\.0\.0\.1__? ?*string* __auto__? ?*name* __auto__? ?*doc\_root* ____? ?*reverse\_dns* __0__? ?*configuration\_file* ____? ?*protocol* __HTTP/1\.1__?](#43)
135[method __destructor__ ?*dictargs*?](#44)
136[method __connect__ *sock* *ip* *port*](#45)
137[method __ServerHeaders__ *ip* *http\_request* *mimetxt*](#46)
138[method __Connect__ *uuid* *sock* *ip*](#47)
139[method __[counter](\.\./counter/counter\.md)__ *which*](#48)
140[method __CheckTimeout__](#49)
141[method __[debug](\.\./debug/debug\.md)__ ?*args*?](#50)
142[method __dispatch__ *data*](#51)
143[method __Dispatch\_Default__ *reply*](#52)
144[method __Dispatch\_Local__ *data*](#53)
145[method __Headers\_Local__ *varname*](#54)
146[method __Headers\_Process__ *varname*](#55)
147[method __HostName__ *ipaddr*](#56)
148[method __[log](\.\./log/log\.md)__ ?*args*?](#57)
149[method __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ *slot* ?*class* ____?](#58)
150[method __port\_listening__](#59)
151[method __PrefixNormalize__ *prefix*](#60)
152[method __[source](\.\./\.\./\.\./\.\./index\.md\#source)__ *filename*](#61)
153[method __start__](#62)
154[method __stop__](#63)
155[method __SubObject \{\} db__](#64)
156[method __SubObject \{\} default__](#65)
157[method __template__ *page*](#66)
158[method __TemplateSearch__ *page*](#67)
159[method __Thread\_start__](#68)
160[method __Uuid\_Generate__](#69)
161[method __Validate\_Connection__ *sock* *ip*](#70)
162[method __reset__](#71)
163[method __content__](#72)
164[method __Dispatch__](#73)
165[method __content__](#74)
166[method __FileName__](#75)
167[method __DirectoryListing__ *local\_file*](#76)
168[method __content__](#77)
169[method __Dispatch__](#78)
170[variable __exename__](#79)
171[method __CgiExec__ *execname* *script* *arglist*](#80)
172[method __Cgi\_Executable__ *script*](#81)
173[method __proxy\_channel__](#82)
174[method __proxy\_path__](#83)
175[method __ProxyRequest__ *chana* *chanb*](#84)
176[method __ProxyReply__ *chana* *chanb* ?*args*?](#85)
177[method __Dispatch__](#86)
178[method __FileName__](#87)
179[method __proxy\_channel__](#88)
180[method __ProxyRequest__ *chana* *chanb*](#89)
181[method __ProxyReply__ *chana* *chanb* ?*args*?](#90)
182[method __DirectoryListing__ *local\_file*](#91)
183[method __EncodeStatus__ *status*](#92)
184[method __scgi\_info__](#93)
185[method __proxy\_channel__](#94)
186[method __ProxyRequest__ *chana* *chanb*](#95)
187[method __ProxyReply__ *chana* *chanb* ?*args*?](#96)
188[method __[debug](\.\./debug/debug\.md)__ ?*args*?](#97)
189[method __Connect__ *uuid* *sock* *ip*](#98)
190[method __Dispatch\_Dict__ *data*](#99)
191[method __uri \{\} add__ *vhosts* *patterns* *info*](#100)
192[method __uri \{\} direct__ *vhosts* *patterns* *info* *body*](#101)
193[method __output__](#102)
194[method __DoOutput__](#103)
195[method __close__](#104)
196[method __local\_memchan__ *command* ?*args*?](#105)
197[method __Connect\_Local__ *uuid* *sock* ?*args*?](#106)
198
199# <a name='description'></a>DESCRIPTION
200
201This module implements a web server, suitable for embedding in an application\.
202The server is object oriented, and contains all of the fundamentals needed for a
203full service website\.
204
205# <a name='section2'></a>Minimal Example
206
207Starting a web service requires starting a class of type __httpd::server__,
208and providing that server with one or more URIs to service, and
209__httpd::reply__ derived classes to generate them\.
210
211    oo::class create ::reply.hello {
212      method content {} {
213        my puts "<HTML><HEAD><TITLE>IRM Dispatch Server</TITLE></HEAD><BODY>"
214        my puts "<h1>Hello World!</h1>"
215        my puts </BODY></HTML>
216      }
217    }
218    ::httpd::server create HTTPD port 8015 myaddr 127.0.0.1 doc_root ~/htdocs
219    HTTPD plugin dispatch httpd::server::dispatch
220    HTTPD uri add * /hello [list mixin reply.hello]
221
222The bare module does have facilities to hose a files from a file system\. Files
223that end in a \.tml will be substituted in the style of Tclhttpd:
224
225    <!-- hello.tml -->
226    [my html_header {Hello World!}]
227    Your Server is running.
228    <p>
229    The time is now [clock format [clock seconds]]
230    [my html_footer]
231
232A complete example of an httpd server is in the /examples directory of Tcllib\.
233It also show how to dispatch URIs to other processes via SCGI and HTTP proxies\.
234
235    cd ~/tcl/sandbox/tcllib
236    tclsh examples/httpd.tcl
237
238# <a name='section3'></a>Classes
239
240## <a name='subsection1'></a>Class  httpd::mime
241
242A metaclass for MIME handling behavior across a live socket
243
244__Methods__
245
246  - <a name='1'></a>method __ChannelCopy__ *in* *out* ?*args*?
247
248  - <a name='2'></a>method __html\_header__ ?*title* ____? ?*args*?
249
250    Returns a block of HTML
251
252  - <a name='3'></a>method __html\_footer__ ?*args*?
253
254  - <a name='4'></a>method __http\_code\_string__ *code*
255
256  - <a name='5'></a>method __HttpHeaders__ *sock* ?*debug* ____?
257
258  - <a name='6'></a>method __HttpHeaders\_Default__
259
260  - <a name='7'></a>method __HttpServerHeaders__
261
262  - <a name='8'></a>method __MimeParse__ *mimetext*
263
264    Converts a block of mime encoded text to a key/value list\. If an exception
265    is encountered, the method will generate its own call to the
266    __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ method, and immediately
267    invoke the __output__ method to produce an error code and close the
268    connection\.
269
270  - <a name='9'></a>method __Url\_Decode__ *data*
271
272    De\-httpizes a string\.
273
274  - <a name='10'></a>method __Url\_PathCheck__ *urlsuffix*
275
276  - <a name='11'></a>method __wait__ *mode* *sock*
277
278## <a name='subsection2'></a>Class  httpd::reply
279
280*ancestors*: __httpd::mime__
281
282A class which shephards a request through the process of generating a reply\. The
283socket associated with the reply is available at all times as the *chan*
284variable\. The process of generating a reply begins with an __httpd::server__
285generating a __http::class__ object, mixing in a set of behaviors and then
286invoking the reply object's __dispatch__ method\. In normal operations the
287__dispatch__ method:
288
289  1. Invokes the __reset__ method for the object to populate default
290     headers\.
291
292  1. Invokes the __HttpHeaders__ method to stream the MIME headers out of
293     the socket
294
295  1. Invokes the __request parse__ method to convert the stream of MIME
296     headers into a dict that can be read via the __request__ method\.
297
298  1. Stores the raw stream of MIME headers in the *rawrequest* variable of the
299     object\.
300
301  1. Invokes the __content__ method for the object, generating an call to
302     the __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ method if an exception
303     is raised\.
304
305  1. Invokes the __output__ method for the object
306
307Developers have the option of streaming output to a buffer via the __puts__
308method of the reply, or simply populating the *reply\_body* variable of the
309object\. The information returned by the __content__ method is not
310interpreted in any way\. If an exception is thrown \(via the
311__[error](\.\./\.\./\.\./\.\./index\.md\#error)__ command in Tcl, for example\) the
312caller will auto\-generate a 500 \{Internal Error\} message\. A typical
313implementation of __content__ look like:
314
315    clay::define ::test::content.file {
316    	superclass ::httpd::content.file
317    	# Return a file
318    	# Note: this is using the content.file mixin which looks for the reply_file variable
319    	# and will auto-compute the Content-Type
320    	method content {} {
321    	  my reset
322        set doc_root [my request get DOCUMENT_ROOT]
323        my variable reply_file
324        set reply_file [file join $doc_root index.html]
325    	}
326    }
327    clay::define ::test::content.time {
328      # return the current system time
329    	method content {} {
330    		my variable reply_body
331        my reply set Content-Type text/plain
332    		set reply_body [clock seconds]
333    	}
334    }
335    clay::define ::test::content.echo {
336    	method content {} {
337    		my variable reply_body
338        my reply set Content-Type [my request get CONTENT_TYPE]
339    		set reply_body [my PostData [my request get CONTENT_LENGTH]]
340    	}
341    }
342    clay::define ::test::content.form_handler {
343    	method content {} {
344    	  set form [my FormData]
345    	  my reply set Content-Type {text/html; charset=UTF-8}
346        my puts [my html_header {My Dynamic Page}]
347        my puts "<BODY>"
348        my puts "You Sent<p>"
349        my puts "<TABLE>"
350        foreach {f v} $form {
351          my puts "<TR><TH>$f</TH><TD><verbatim>$v</verbatim></TD>"
352        }
353        my puts "</TABLE><p>"
354        my puts "Send some info:<p>"
355        my puts "<FORM action=/[my request get REQUEST_PATH] method POST>"
356        my puts "<TABLE>"
357        foreach field {name rank serial_number} {
358          set line "<TR><TH>$field</TH><TD><input name=\"$field\" "
359          if {[dict exists $form $field]} {
360            append line " value=\"[dict get $form $field]\"""
361          }
362          append line " /></TD></TR>"
363          my puts $line
364        }
365        my puts "</TABLE>"
366        my puts [my html footer]
367    	}
368    }
369
370__Variable__
371
372  - <a name='12'></a>variable __ChannelRegister__
373
374  - <a name='13'></a>variable __reply__
375
376    A dictionary which will converted into the MIME headers of the reply
377
378  - <a name='14'></a>variable __request__
379
380    A dictionary containing the SCGI transformed HTTP headers for the request
381
382__Delegate__
383
384  - <a name='15'></a>delegate __<server>__
385
386    The server object which spawned this reply
387
388__Methods__
389
390  - <a name='16'></a>method __constructor__ *ServerObj* ?*args*?
391
392  - <a name='17'></a>method __destructor__ ?*dictargs*?
393
394    clean up on exit
395
396  - <a name='18'></a>method __ChannelRegister__ ?*args*?
397
398    Registers a channel to be closed by the close method
399
400  - <a name='19'></a>method __close__
401
402    Close channels opened by this object
403
404  - <a name='20'></a>method __Log\_Dispatched__
405
406    Record a dispatch event
407
408  - <a name='21'></a>method __dispatch__ *newsock* *datastate*
409
410    Accept the handoff from the server object of the socket *newsock* and feed
411    it the state *datastate*\. Fields the *datastate* are looking for in
412    particular are:
413
414    \* __mixin__ \- A key/value list of slots and classes to be mixed into the
415    object prior to invoking __Dispatch__\.
416
417    \* __http__ \- A key/value list of values to populate the object's
418    *request* ensemble
419
420    All other fields are passed along to the __clay__ structure of the
421    object\.
422
423  - <a name='22'></a>method __Dispatch__
424
425  - <a name='23'></a>method __html\_header__ *title* ?*args*?
426
427  - <a name='24'></a>method __html\_footer__ ?*args*?
428
429  - <a name='25'></a>method __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ *code* ?*msg* ____? ?*errorInfo* ____?
430
431  - <a name='26'></a>method __content__
432
433    REPLACE ME: This method is the "meat" of your application\. It writes to the
434    result buffer via the "puts" method and can tweak the headers via "clay put
435    header\_reply"
436
437  - <a name='27'></a>method __EncodeStatus__ *status*
438
439    Formulate a standard HTTP status header from he string provided\.
440
441  - <a name='28'></a>method __[log](\.\./log/log\.md)__ *type* ?*info* ____?
442
443  - <a name='29'></a>method __CoroName__
444
445  - <a name='30'></a>method __DoOutput__
446
447    Generates the the HTTP reply, streams that reply back across *chan*, and
448    destroys the object\.
449
450  - <a name='31'></a>method __FormData__
451
452    For GET requests, converts the QUERY\_DATA header into a key/value list\. For
453    POST requests, reads the Post data and converts that information to a
454    key/value list for application/x\-www\-form\-urlencoded posts\. For multipart
455    posts, it composites all of the MIME headers of the post to a singular
456    key/value list, and provides MIME\_\* information as computed by the
457    __[mime](\.\./mime/mime\.md)__ package, including the MIME\_TOKEN, which
458    can be fed back into the mime package to read out the contents\.
459
460  - <a name='32'></a>method __PostData__ *length*
461
462    Stream *length* bytes from the *chan* socket, but only of the request is
463    a POST or PUSH\. Returns an empty string otherwise\.
464
465  - <a name='33'></a>method __Session\_Load__
466
467    Manage session data
468
469  - <a name='34'></a>method __puts__ *line*
470
471    Appends the value of *string* to the end of *reply\_body*, as well as a
472    trailing newline character\.
473
474  - <a name='35'></a>method __RequestFind__ *field*
475
476  - <a name='36'></a>method __request__ *subcommand* ?*args*?
477
478  - <a name='37'></a>method __reply__ *subcommand* ?*args*?
479
480  - <a name='38'></a>method __reset__
481
482    Clear the contents of the *reply\_body* variable, and reset all headers in
483    the __reply__ structure back to the defaults for this object\.
484
485  - <a name='39'></a>method __timeOutCheck__
486
487    Called from the __http::server__ object which spawned this reply\. Checks
488    to see if too much time has elapsed while waiting for data or generating a
489    reply, and issues a timeout error to the request if it has, as well as
490    destroy the object and close the *chan* socket\.
491
492  - <a name='40'></a>method __[timestamp](\.\./\.\./\.\./\.\./index\.md\#timestamp)__
493
494    Return the current system time in the format:
495
496    %a, %d %b %Y %T %Z
497
498## <a name='subsection3'></a>Class  httpd::server
499
500*ancestors*: __httpd::mime__
501
502__Variable__
503
504  - <a name='41'></a>variable __template__
505
506  - <a name='42'></a>variable __url\_patterns__
507
508__Methods__
509
510  - <a name='43'></a>method __constructor__ *args* ?*port* __auto__? ?*myaddr* __127\.0\.0\.1__? ?*string* __auto__? ?*name* __auto__? ?*doc\_root* ____? ?*reverse\_dns* __0__? ?*configuration\_file* ____? ?*protocol* __HTTP/1\.1__?
511
512  - <a name='44'></a>method __destructor__ ?*dictargs*?
513
514  - <a name='45'></a>method __connect__ *sock* *ip* *port*
515
516    Reply to an open socket\. This method builds a coroutine to manage the
517    remainder of the connection\. The coroutine's operations are driven by the
518    __Connect__ method\.
519
520  - <a name='46'></a>method __ServerHeaders__ *ip* *http\_request* *mimetxt*
521
522  - <a name='47'></a>method __Connect__ *uuid* *sock* *ip*
523
524    This method reads HTTP headers, and then consults the __dispatch__
525    method to determine if the request is valid, and/or what kind of reply to
526    generate\. Under normal cases, an object of class __::http::reply__ is
527    created, and that class's __dispatch__ method\. This action passes
528    control of the socket to the reply object\. The reply object manages the rest
529    of the transaction, including closing the socket\.
530
531  - <a name='48'></a>method __[counter](\.\./counter/counter\.md)__ *which*
532
533    Increment an internal counter\.
534
535  - <a name='49'></a>method __CheckTimeout__
536
537    Check open connections for a time out event\.
538
539  - <a name='50'></a>method __[debug](\.\./debug/debug\.md)__ ?*args*?
540
541  - <a name='51'></a>method __dispatch__ *data*
542
543    Given a key/value list of information, return a data structure describing
544    how the server should reply\.
545
546  - <a name='52'></a>method __Dispatch\_Default__ *reply*
547
548    Method dispatch method of last resort before returning a 404 NOT FOUND
549    error\. The default behavior is to look for a file in *DOCUMENT\_ROOT* which
550    matches the query\.
551
552  - <a name='53'></a>method __Dispatch\_Local__ *data*
553
554    Method dispatch method invoked prior to invoking methods implemented by
555    plugins\. If this method returns a non\-empty dictionary, that structure will
556    be passed to the reply\. The default is an empty implementation\.
557
558  - <a name='54'></a>method __Headers\_Local__ *varname*
559
560    Introspect and possibly modify a data structure destined for a reply\. This
561    method is invoked before invoking Header methods implemented by plugins\. The
562    default implementation is empty\.
563
564  - <a name='55'></a>method __Headers\_Process__ *varname*
565
566    Introspect and possibly modify a data structure destined for a reply\. This
567    method is built dynamically by the
568    __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ method\.
569
570  - <a name='56'></a>method __HostName__ *ipaddr*
571
572    Convert an ip address to a host name\. If the server/ reverse\_dns flag is
573    false, this method simply returns the IP address back\. Internally, this
574    method uses the *dns* module from tcllib\.
575
576  - <a name='57'></a>method __[log](\.\./log/log\.md)__ ?*args*?
577
578    Log an event\. The input for args is free form\. This method is intended to be
579    replaced by the user, and is a noop for a stock http::server object\.
580
581  - <a name='58'></a>method __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ *slot* ?*class* ____?
582
583    Incorporate behaviors from a plugin\. This method dynamically rebuilds the
584    __Dispatch__ and __Headers__ method\. For every plugin, the server
585    looks for the following entries in *clay plugin/*:
586
587    *load* \- A script to invoke in the server's namespace during the
588    __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ method invokation\.
589
590    *dispatch* \- A script to stitch into the server's __Dispatch__ method\.
591
592    *headers* \- A script to stitch into the server's __Headers__ method\.
593
594    *thread* \- A script to stitch into the server's __Thread\_start__
595    method\.
596
597  - <a name='59'></a>method __port\_listening__
598
599    Return the actual port that httpd is listening on\.
600
601  - <a name='60'></a>method __PrefixNormalize__ *prefix*
602
603    For the stock version, trim trailing /'s and \*'s from a prefix\. This method
604    can be replaced by the end user to perform any other transformations needed
605    for the application\.
606
607  - <a name='61'></a>method __[source](\.\./\.\./\.\./\.\./index\.md\#source)__ *filename*
608
609  - <a name='62'></a>method __start__
610
611    Open the socket listener\.
612
613  - <a name='63'></a>method __stop__
614
615    Shut off the socket listener, and destroy any pending replies\.
616
617  - <a name='64'></a>method __SubObject \{\} db__
618
619  - <a name='65'></a>method __SubObject \{\} default__
620
621  - <a name='66'></a>method __template__ *page*
622
623    Return a template for the string *page*
624
625  - <a name='67'></a>method __TemplateSearch__ *page*
626
627    Perform a search for the template that best matches *page*\. This can
628    include local file searches, in\-memory structures, or even database lookups\.
629    The stock implementation simply looks for files with a \.tml or \.html
630    extension in the ?doc\_root? directory\.
631
632  - <a name='68'></a>method __Thread\_start__
633
634    Built by the __[plugin](\.\./\.\./\.\./\.\./index\.md\#plugin)__ method\.
635    Called by the __start__ method\. Intended to allow plugins to spawn
636    worker threads\.
637
638  - <a name='69'></a>method __Uuid\_Generate__
639
640    Generate a GUUID\. Used to ensure every request has a unique ID\. The default
641    implementation is:
642
643    return [::clay::uuid generate]
644
645  - <a name='70'></a>method __Validate\_Connection__ *sock* *ip*
646
647    Given a socket and an ip address, return true if this connection should be
648    terminated, or false if it should be allowed to continue\. The stock
649    implementation always returns 0\. This is intended for applications to be
650    able to implement black lists and/or provide security based on IP address\.
651
652## <a name='subsection4'></a>Class  httpd::server::dispatch
653
654*ancestors*: __httpd::server__
655
656Provide a backward compadible alias
657
658## <a name='subsection5'></a>Class  httpd::content\.redirect
659
660__Methods__
661
662  - <a name='71'></a>method __reset__
663
664  - <a name='72'></a>method __content__
665
666## <a name='subsection6'></a>Class  httpd::content\.cache
667
668__Methods__
669
670  - <a name='73'></a>method __Dispatch__
671
672## <a name='subsection7'></a>Class  httpd::content\.template
673
674__Methods__
675
676  - <a name='74'></a>method __content__
677
678## <a name='subsection8'></a>Class  httpd::content\.file
679
680Class to deliver Static content When utilized, this class is fed a local
681filename by the dispatcher
682
683__Methods__
684
685  - <a name='75'></a>method __FileName__
686
687  - <a name='76'></a>method __DirectoryListing__ *local\_file*
688
689  - <a name='77'></a>method __content__
690
691  - <a name='78'></a>method __Dispatch__
692
693## <a name='subsection9'></a>Class  httpd::content\.exec
694
695__Variable__
696
697  - <a name='79'></a>variable __exename__
698
699__Methods__
700
701  - <a name='80'></a>method __CgiExec__ *execname* *script* *arglist*
702
703  - <a name='81'></a>method __Cgi\_Executable__ *script*
704
705## <a name='subsection10'></a>Class  httpd::content\.proxy
706
707*ancestors*: __httpd::content\.exec__
708
709Return data from an proxy process
710
711__Methods__
712
713  - <a name='82'></a>method __proxy\_channel__
714
715  - <a name='83'></a>method __proxy\_path__
716
717  - <a name='84'></a>method __ProxyRequest__ *chana* *chanb*
718
719  - <a name='85'></a>method __ProxyReply__ *chana* *chanb* ?*args*?
720
721  - <a name='86'></a>method __Dispatch__
722
723## <a name='subsection11'></a>Class  httpd::content\.cgi
724
725*ancestors*: __httpd::content\.proxy__
726
727__Methods__
728
729  - <a name='87'></a>method __FileName__
730
731  - <a name='88'></a>method __proxy\_channel__
732
733  - <a name='89'></a>method __ProxyRequest__ *chana* *chanb*
734
735  - <a name='90'></a>method __ProxyReply__ *chana* *chanb* ?*args*?
736
737  - <a name='91'></a>method __DirectoryListing__ *local\_file*
738
739    For most CGI applications a directory list is vorboten
740
741## <a name='subsection12'></a>Class  httpd::protocol\.scgi
742
743Return data from an SCGI process
744
745__Methods__
746
747  - <a name='92'></a>method __EncodeStatus__ *status*
748
749## <a name='subsection13'></a>Class  httpd::content\.scgi
750
751*ancestors*: __httpd::content\.proxy__
752
753__Methods__
754
755  - <a name='93'></a>method __scgi\_info__
756
757  - <a name='94'></a>method __proxy\_channel__
758
759  - <a name='95'></a>method __ProxyRequest__ *chana* *chanb*
760
761  - <a name='96'></a>method __ProxyReply__ *chana* *chanb* ?*args*?
762
763## <a name='subsection14'></a>Class  httpd::server\.scgi
764
765*ancestors*: __httpd::server__
766
767Act as an SCGI Server
768
769__Methods__
770
771  - <a name='97'></a>method __[debug](\.\./debug/debug\.md)__ ?*args*?
772
773  - <a name='98'></a>method __Connect__ *uuid* *sock* *ip*
774
775## <a name='subsection15'></a>Class  httpd::content\.websocket
776
777Upgrade a connection to a websocket
778
779## <a name='subsection16'></a>Class  httpd::plugin
780
781httpd plugin template
782
783## <a name='subsection17'></a>Class  httpd::plugin\.dict\_dispatch
784
785A rudimentary plugin that dispatches URLs from a dict data structure
786
787__Methods__
788
789  - <a name='99'></a>method __Dispatch\_Dict__ *data*
790
791    Implementation of the dispatcher
792
793  - <a name='100'></a>method __uri \{\} add__ *vhosts* *patterns* *info*
794
795  - <a name='101'></a>method __uri \{\} direct__ *vhosts* *patterns* *info* *body*
796
797## <a name='subsection18'></a>Class  httpd::reply\.memchan
798
799*ancestors*: __httpd::reply__
800
801__Methods__
802
803  - <a name='102'></a>method __output__
804
805  - <a name='103'></a>method __DoOutput__
806
807  - <a name='104'></a>method __close__
808
809## <a name='subsection19'></a>Class  httpd::plugin\.local\_memchan
810
811__Methods__
812
813  - <a name='105'></a>method __local\_memchan__ *command* ?*args*?
814
815  - <a name='106'></a>method __Connect\_Local__ *uuid* *sock* ?*args*?
816
817    A modified connection method that passes simple GET request to an object and
818    pulls data directly from the reply\_body data variable in the object Needed
819    because memchan is bidirectional, and we can't seem to communicate that the
820    server is one side of the link and the reply is another
821
822# <a name='section4'></a>AUTHORS
823
824Sean Woods
825
826# <a name='section5'></a>Bugs, Ideas, Feedback
827
828This document, and the package it describes, will undoubtedly contain bugs and
829other problems\. Please report such in the category *network* of the [Tcllib
830Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
831for enhancements you may have for either package and/or documentation\.
832
833When proposing code changes, please provide *unified diffs*, i\.e the output of
834__diff \-u__\.
835
836Note further that *attachments* are strongly preferred over inlined patches\.
837Attachments can be made by going to the __Edit__ form of the ticket
838immediately after its creation, and then using the left\-most button in the
839secondary navigation bar\.
840
841# <a name='keywords'></a>KEYWORDS
842
843[TclOO](\.\./\.\./\.\./\.\./index\.md\#tcloo), [WWW](\.\./\.\./\.\./\.\./index\.md\#www),
844[http](\.\./\.\./\.\./\.\./index\.md\#http), [httpd](\.\./\.\./\.\./\.\./index\.md\#httpd),
845[httpserver](\.\./\.\./\.\./\.\./index\.md\#httpserver),
846[services](\.\./\.\./\.\./\.\./index\.md\#services)
847
848# <a name='category'></a>CATEGORY
849
850Networking
851
852# <a name='copyright'></a>COPYRIGHT
853
854Copyright &copy; 2018 Sean Woods <yoda@etoyoc\.com>
855