Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Refactor the command-line argument. Update documentation accordingly. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
69cae4edc3b78fcaaf50f4cab9b9d803 |
User & Date: | drh 2017-12-13 13:00:41.953 |
Context
2017-12-13
| ||
15:09 | SCGI processing now working on Nginx. (check-in: 788f9d0118 user: drh tags: trunk) | |
13:00 | Refactor the command-line argument. Update documentation accordingly. (check-in: 69cae4edc3 user: drh tags: trunk) | |
12:32 | Add the CGI test script and fix auto-detection of CGI. (check-in: 820bdf0f00 user: drh tags: trunk) | |
Changes
Changes to README.md.
1 | Wapp - A Web-Application Framework for TCL | | | | | | | | | | | | > > | | > | > | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | Wapp - A Web-Application Framework for TCL ========================================== 1.0 Introduction ---------------- Wapp is a lightweight framework that strives to simplify the construction of web application written in TCL. The same Wapp-based application can be launched in multiple ways: 1. From the command-line (ex: "<tt>tclsh app.tcl</tt>"). In this mode, The wapp finds an available TCL port on localhost, starts an in-process web server listening on that port, and then launches the users default web browser directed at localhost:$port 2. As a stand-alone web server 3. As a CGI script 4. As an SCGI program All four methods use the same application code and present the same interface to the application user. An application can be developed on the desktop using stand-alone mode (1), then deployed as a stand-alone server (2), or a CGI script (3), or as an SCGI program (4). 2.0 Hello World! ---------------- Wapp is designed to be easy to use. A hello-world program is as follows: > package require wapp proc wapp-default {req} { wapp "<h1>Hello, World!</h1>\n" } wapp-start $::argv The application defines one or more procedures that accept HTTP requests and generate appropriate replies. For an HTTP request where the initial portion of the URI is "abcde", the procedure named "wapp-page-abcde" will be invoked to construct the reply. If no such procedure exists, "wapp-default" is invoked instead. The latter technique is used for the hello-world example above. The procedure generates a reply using one or more calls to the "wapp" command. Each "wapp" command appends new text to the reply. The "wapp-start" command starts up the application. To run this application, copy the code above into a file named "main.tcl" and then enter the following command: > tclsh main.tcl That command will start up a web-server bound to the loopback IP address, then launch a web-browser pointing at that web-server. The result is that the "Hello, World!" page will automatically appear in your web browser. To run this same program as a traditional web-server on TCP port 8080, enter: > tclsh main.tcl --server 8080 Here the built-in web-server listens on all IP addresses and so the web page is available on other machines. But the web-broswer is not automatically started in this case, so you will have to manually enter "http://localhost:8080/" into your web-browser in order to see the page. To run this program as CGI, put the main.tcl script in your web-servers file hierarchy, in the appropriate place for CGI scripts, and make any other web-server specific configuration changes so that the web-server understands that the main.tcl file is a CGI script. Then point your web-browser at that script. Run the hello-world program as SCGI like this: > tclsh main.tcl --scgi 9000 Then configure your web-server to send SCGI requests to TCL port 9000 for some specific URI, and point your web-browser at that URI. 3.0 A Slightly Longer Example ----------------------------- Information about each HTTP request is encoded in the global ::wapp dict variable. The following sample program shows the information available in ::wapp. > package require wapp |
︙ | ︙ | |||
87 88 89 90 91 92 93 | The /env page is implemented by the "wapp-page-env" proc. This proc generates an HTML that describes the content of the ::wapp dict. Keys that begin with "." are for internal use by Wapp and are skipped for this display. The "wapp-escape-html" command is like "wapp" and "wapp-unsafe" except that "wapp-escape-html" escapes HTML markup so that it displays correctly in the output. | | > | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | The /env page is implemented by the "wapp-page-env" proc. This proc generates an HTML that describes the content of the ::wapp dict. Keys that begin with "." are for internal use by Wapp and are skipped for this display. The "wapp-escape-html" command is like "wapp" and "wapp-unsafe" except that "wapp-escape-html" escapes HTML markup so that it displays correctly in the output. 4.0 The ::wapp Global Dict -------------------------- To better understand how the ::wapp dict works, try running the previous sample program, but extend the /env URL with extra path elements and query parameters. For example: <http://localhost:8080/env/longer/path?q1=5&title=hello+world%21> Notice how the query parameters in the input URL are decoded and become elements of the ::wapp dict. The same thing occurs with POST parameters and cookies - they are all converted into entries in the ::wapp dict variable so that the parameters are easily accessible to page generation procedures. The ::wapp dict contains additional information about the request, roughly corresponding to CGI environment variables. To prevent environment information from overlapping and overwriting query parameters, all the environment information uses upper-case names and all query parameters are required to be lower case. If an input URL contains an upper-case query parameter (or POST parameter or cookie), that parameter is silently omitted from the ::wapp dict. The ::wapp dict contains the following environment values: + **HTTP\_HOST** The hostname (or IP address) and port that the client used to create the current HTTP request. This is the first part of the request URL, right after the "http://" or "https://". The format for this value |
︙ | ︙ | |||
185 186 187 188 189 190 191 | All of PATH\_INFO that follows PATH\_HEAD. + **SELF\_URL** The URL for the current page, stripped of query parameter. This is useful for filling in the action= attribute of forms. | | | > | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | All of PATH\_INFO that follows PATH\_HEAD. + **SELF\_URL** The URL for the current page, stripped of query parameter. This is useful for filling in the action= attribute of forms. ### 4.1 URL Parsing Example For the input URL "http://example.com/cgi-bin/script/method/extra/path?q1=5" and for a CGI script named "script" in the /cgi-bin/ directory, the following CGI environment values are generated: + **HTTP\_HOST** → "example.com:80" + **SCRIPT\_NAME** → "/cgi-bin/script" + **PATH\_INFO** → "/method/extra/path" + **REQUEST\_URI** → "/cgi-bin/script/method/extra/path" + **QUERY\_STRING** → "q1=5" + **BASE\_URL** → "http://example.com/cgi-bin/script" + **SELF\_URL** → "http://example.com/cgi-bin/script/method" + **PATH\_HEAD** → "method" + **PATH\_TAIL** → "extra/path" The first five elements of the example above, HTTP\_HOST through QUERY\_STRING, are standard CGI. The final four elements are Wapp extensions. 5.0 Wapp Commands ----------------- The following utility commands are available for use by applications built on Wapp: + **wapp-start** _ARGLIST_ Start up the application. _ARGLIST_ is typically the value of $::argv, though it might be some subset of $::argv if the containing application |
︙ | ︙ | |||
288 289 290 291 292 293 294 | command should only be used during debugging, as otherwise it introduces a severe security vulnerability into the application. * **wapp-safety-check** Examine all TCL procedures in the application and report errors about unsafe usage of "wapp". | | > | 324 325 326 327 328 329 330 331 332 333 334 335 336 | command should only be used during debugging, as otherwise it introduces a severe security vulnerability into the application. * **wapp-safety-check** Examine all TCL procedures in the application and report errors about unsafe usage of "wapp". 6.0 Design Rules ---------------- All global procs and variables used by Wapp begin with the four character prefix "wapp". Procs and variable intended for internal use begin with the seven character prefix "wappInt". |
Changes to wapp.tcl.
︙ | ︙ | |||
94 95 96 97 98 99 100 | } return $res } # Start up the wapp framework. Parameters are a list passed as the # single argument. # | > > | < | > > > > > > | | > | | | | > | < < | > > > | > | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | } return $res } # Start up the wapp framework. Parameters are a list passed as the # single argument. # # -server $PORT Listen for HTTP requests on this TCP port $PORT # # -scgi $PORT Listen for SCGI requests on TCP port $PORT # # -cgi Perform a single CGI request # # With no arguments, the behavior is called "auto". In "auto" mode, # if the GATEWAY_INTERFACE environment variable indicates CGI, then run # as CGI. Otherwise, start an HTTP server bound to the loopback address # only, on an arbitrary TCP port, and automatically launch a web browser # on that TCP port. # proc wapp-start {arglist} { global env set mode auto set port 0 set n [llength $arglist] for {set i 0} {$i<$n} {incr i} { set term [lindex $arglist $i] if {[string match --* $term]} {set term [string range $term 1 end]} switch -- $term { -server { incr i; set mode "server" set port [lindex $arglist $i] } -scgi { incr i; set mode "scgi" set port [lindex $arglist $i] } -cgi { set mode "cgi" } default { error "unknown option: $term" } } } if {($mode=="auto" && [info exists env(GATEWAY_INTERFACE)] && $env(GATEWAY_INTERFACE)=="CGI/1.0") || $mode=="cgi" } { |
︙ | ︙ |