Wapp

Check-in [ba9c27b26a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the wapp-trim command.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ba9c27b26a552089feb6bffe0fce80f4b1512f502786e2b4c2aaf685a59daced
User & Date: drh 2018-01-28 20:04:55.356
Context
2018-01-28
20:54
Updates to the README.md file. (check-in: 05cf577f9f user: drh tags: trunk)
20:04
Add the wapp-trim command. (check-in: ba9c27b26a user: drh tags: trunk)
19:46
Add a Makefile for MacOS. Add wapp-param. Add the %string(...) substitution for wapp-subst. (check-in: 1b25f9e6ed user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to README.md.
88
89
90
91
92
93
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
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
    proc wapp-default {} {
      wapp-subst {<h1>Hello, World!</h1>\n}
      set B [wapp-param BASE_URL]


      wapp-subst {<p>See the <a href='%html($B)/env'>Wapp }
      wapp-subst {Environment</a></p>\n}

    }
    proc wapp-page-env {} {
      global wapp
      wapp-subst {<h1>Wapp Environment</h1>\n<pre>\n}
      foreach var [lsort [dict keys $wapp]] {
        if {[string index $var 0]=="."} continue
        wapp-subst {%html($var) = %html([list [dict get $wapp $var]])\n}
      }
      wapp-subst {</pre>\n}
    }
    wapp-start $::argv

In this application, the default "Hello, World!" page has been extended
with a hyperlink to the /env page.  The "wapp-subst" command now contains



a "%html(...)" substitution.  The "..." argument is expanded using the
usual TCL rules, but then the result is escaped so that it is safe to include
in an HTML document.  Other supported substitutions are "%url(...)" for
URLs on the href= and src= attributes of HTML entities, and "%unsafe(...)"

for direct literal substitution.  As its name implies, the %unsafe()
substitution should be avoid whenever possible.

The /env page is implemented by the "wapp-page-env" proc.  This proc
generates 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.  Notice the use of "wapp-subst" to safely escape text
for inclusion in an HTML document.








<

>
>
|
|
>













|
>
>
>



|
>
|
|







88
89
90
91
92
93
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
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
    proc wapp-default {} {

      set B [wapp-param BASE_URL]
      wapp-trim {
        <h1>Hello, World!</h1>
        <p>See the <a href='%html($B)/env'>Wapp
        Environment</a></p>
      }
    }
    proc wapp-page-env {} {
      global wapp
      wapp-subst {<h1>Wapp Environment</h1>\n<pre>\n}
      foreach var [lsort [dict keys $wapp]] {
        if {[string index $var 0]=="."} continue
        wapp-subst {%html($var) = %html([list [dict get $wapp $var]])\n}
      }
      wapp-subst {</pre>\n}
    }
    wapp-start $::argv

In this application, the default "Hello, World!" page has been extended
with a hyperlink to the /env page.  The "wapp-subst" command has been
replaced by "wapp-trim", which works the same way with the addition that
it removes surplus whitespace from the left margin, so that the generated
HTML text does not come out indented.  The "wapp-index" command uses
a "%html(...)" substitution.  The "..." argument is expanded using the
usual TCL rules, but then the result is escaped so that it is safe to include
in an HTML document.  Other supported substitutions are "%url(...)" for
URLs on the href= and src= attributes of HTML entities, "%qp(...)" for
query parameters, "%string(...)" for string literals within javascript,
and "%unsafe(...)" for direct literal substitution.  As its name implies,
the %unsafe() substitution should be avoid whenever possible.

The /env page is implemented by the "wapp-page-env" proc.  This proc
generates 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.  Notice the use of "wapp-subst" to safely escape text
for inclusion in an HTML document.

262
263
264
265
266
267
268








269
270
271
272
273
274
275
     The "wapp-subst" command itself will do all necessary backslash
     substitutions.  Command and variable substitutions only occur within
     "%html(...)", "%url(...)", "%qp(...)", "%string(...)", and
     "%unsafe(...)".  The substitutions are escaped (except in the case of
     "%unsafe(...)") so that the result is safe for inclusion within the
     body of an HTML document, a URL, a query parameter, or a javascript
     string literal, respectively.









  +  **wapp-mimetype** _MIMETYPE_  
     Set the MIME-type for the generated web page.  The default is "text/html".

  +  **wapp-reply-code** _CODE_
     Set the reply-code for the HTTP request.  The default is "200 Ok".








>
>
>
>
>
>
>
>







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
     The "wapp-subst" command itself will do all necessary backslash
     substitutions.  Command and variable substitutions only occur within
     "%html(...)", "%url(...)", "%qp(...)", "%string(...)", and
     "%unsafe(...)".  The substitutions are escaped (except in the case of
     "%unsafe(...)") so that the result is safe for inclusion within the
     body of an HTML document, a URL, a query parameter, or a javascript
     string literal, respectively.

  +  **wapp-trim** _TEXT_  
     Just like wapp-subst, this routine appends _TEXT_ to the web page
     under construction, using the %html, %url, %qp, %string, and %unsafe
     substitutions.  In addition, this routine removes surplus whitespace
     from the left margin, so that if the _TEXT_ argument is intended in
     the source script, it will appear at the left margin in the generated
     output.

  +  **wapp-mimetype** _MIMETYPE_  
     Set the MIME-type for the generated web page.  The default is "text/html".

  +  **wapp-reply-code** _CODE_
     Set the reply-code for the HTTP request.  The default is "200 Ok".

Changes to test01.tcl.
8
9
10
11
12
13
14
15

16
17
18
19

20
21
22
23
24
25
26
  set R [wapp-param SCRIPT_NAME]
  wapp "<h1>Hello, World!</h1>\n"
  wapp "<ol>"
  wapp-unsafe "<li><p><a href='$R/env'>Wapp Environment</a></p>\n"
  wapp-subst {<li><p><a href='%html($B)/fullenv'>Full Environment</a>\n}
  set crazy [lsort [dict keys $wapp]]
  wapp-subst {<li><p><a href='%html($B)/env?keys=%url($crazy)'>}
  wapp "Environment with crazy URL\n"

  wapp-subst {<li><p><a href='%html($B)/lint'>Lint</a>\n}
  wapp-subst {<li><p><a href='%html($B)/errorout'>Deliberate error</a>\n}
  wapp-subst {<li><p><a href='%html($B)/encodings'>Encoding checks</a>\n}
  wapp-subst {<li><p><a href='%html($B)/redirect'>Redirect to env</a>\n}

  set x "%string(...)"
  set v abc'def\"ghi\\jkl
  wapp-subst {<li>%html($x) substitution test: "%string($v)"\n}
  wapp "</ol>"
  if {[dict exists $wapp showenv]} {
    wapp-page-env
  }







|
>
|
|
|
|
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  set R [wapp-param SCRIPT_NAME]
  wapp "<h1>Hello, World!</h1>\n"
  wapp "<ol>"
  wapp-unsafe "<li><p><a href='$R/env'>Wapp Environment</a></p>\n"
  wapp-subst {<li><p><a href='%html($B)/fullenv'>Full Environment</a>\n}
  set crazy [lsort [dict keys $wapp]]
  wapp-subst {<li><p><a href='%html($B)/env?keys=%url($crazy)'>}
  wapp "Environment with crazy URL</a>\n"
  wapp-trim {
    <li><p><a href='%html($B)/lint'>Lint</a>
    <li><p><a href='%html($B)/errorout'>Deliberate error</a>
    <li><p><a href='%html($B)/encodings'>Encoding checks</a>
    <li><p><a href='%html($B)/redirect'>Redirect to env</a>
  }
  set x "%string(...)"
  set v abc'def\"ghi\\jkl
  wapp-subst {<li>%html($x) substitution test: "%string($v)"\n}
  wapp "</ol>"
  if {[dict exists $wapp showenv]} {
    wapp-page-env
  }
Changes to wapp.tcl.
108
109
110
111
112
113
114












115
116
117
118
119
120
121
    set s [subst -novar -noback $s]
  }
  return $s
}
proc wappInt-enc-string {s} {
  return [string map {\\ \\\\ \" \\\" ' \\'} $s]
}













# This is a helper routine for wappInt-enc-url and wappInt-enc-qp.  It returns
# an appropriate %HH encoding for the single character c.  If c is a unicode
# character, then this routine might return multiple bytes:  %HH%HH%HH
#
proc wappInt-%HHchar {c} {
  if {$c==" "} {return +}







>
>
>
>
>
>
>
>
>
>
>
>







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
    set s [subst -novar -noback $s]
  }
  return $s
}
proc wappInt-enc-string {s} {
  return [string map {\\ \\\\ \" \\\" ' \\'} $s]
}

# Works like wapp-subst, but also removes whitespace from the beginning
# of lines.
#
proc wapp-trim {txt} {
  global wapp
  regsub -all {\n\s+} [string trim $txt] \n txt
  regsub -all {%(html|url|qp|string|unsafe)\(([^)]+)\)} $txt \
         {[wappInt-enc-\1 "\2"]} txt
  dict append wapp .reply [uplevel 1 [list subst -novariables $txt]]
}


# This is a helper routine for wappInt-enc-url and wappInt-enc-qp.  It returns
# an appropriate %HH encoding for the single character c.  If c is a unicode
# character, then this routine might return multiple bytes:  %HH%HH%HH
#
proc wappInt-%HHchar {c} {
  if {$c==" "} {return +}