1 2[//000000001]: # (httpd \- Tcl Web Server) 3[//000000002]: # (Generated from file 'httpd\.man' by tcllib/doctools with format 'markdown') 4[//000000003]: # (Copyright © 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> | <a 8href="../../../toc.md">Table Of Contents</a> | <a 9href="../../../../index.md">Keyword Index</a> | <a 10href="../../../../toc0.md">Categories</a> | <a 11href="../../../../toc1.md">Modules</a> | <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 © 2018 Sean Woods <yoda@etoyoc\.com> 855