Wapp

Check-in [e605df67a3]
Login

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

Overview
Comment:Add the optional wapp-before-dispatch-hook and the test05.tcl test case to demonstrate how to use it.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e605df67a3ffc0e3bc09cb8d0274b7dce44a97d220d9506625c7f4a2e95ea7a2
User & Date: drh 2018-01-27 16:09:50.098
Context
2018-01-27
22:17
Enable JSON1 in wapptclsh (check-in: a763b12070 user: drh tags: trunk)
16:09
Add the optional wapp-before-dispatch-hook and the test05.tcl test case to demonstrate how to use it. (check-in: e605df67a3 user: drh tags: trunk)
2018-01-26
21:26
Update the built-in SQLite to the 3.22.0 release. (check-in: a700937563 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Added test05.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
# Invoke as "tclsh test05.tcl" and then surf the website that pops up
# to verify the logic in wapp.
#
# This script demonstrates how to use a wapp-before-dispatch-hook to
# rewrite some of the environment variables such that the URL begins with
# an object name and the method follows the object name.
#
source wapp.tcl
proc wapp-default {} {
  global wapp
  wapp-set-cookie env-cookie simple
  wapp-subst {<h1>Wapp Environment</h1>\n}
  wapp-subst {<form method='GET' action='%html([dict get $wapp SELF_URL])'>\n}
  wapp-subst {<input type='checkbox' name='showhdr'}
  if {[dict exists $wapp showhdr]} {
    wapp-subst { checked}
  }
  wapp-subst {> Show Header\n}
  wapp-subst {<input type='submit' value='Go'>\n}
  wapp-subst {</form>}
  wapp-subst {<pre>\n}
  foreach var [lsort [dict keys $wapp]] {
    if {[string index $var 0]=="." &&
         ($var!=".header" || ![dict exists $wapp showhdr])} continue
    wapp-escape-html "$var = [list [dict get $wapp $var]]\n"
  }
  wapp {</pre>}
  wapp-subst {<p><a href='%html([dict get $wapp BASE_URL])/x001/method1/arg'>}
  wapp-subst {The "method1" method on object "x001"</a></p>\n}
}
proc wapp-page-method1 {} {
  global wapp
  wapp-subst {<h1>The xyzzy page for }
  wapp-subst {object "%html([dict get $wapp OBJECT])"</h1>\n}
  wapp-subst {<pre>\n}
  foreach var [lsort [dict keys $wapp]] {
    if {[string index $var 0]=="."} continue
    wapp-escape-html "$var = [list [dict get $wapp $var]]\n"
  }
  wapp-subst {</pre>\n}
}
proc wapp-before-dispatch-hook {} {
  global wapp
  set objname [dict get $wapp PATH_HEAD]
  # always set ROOT_URL to the original BASE_URL
  dict set wapp ROOT_URL [dict get $wapp BASE_URL]
  # If the first term of REQUEST_URI is a valid object name, make it
  # the OBJECT and shift a new PATH_HEAD out of PATH_TAIL.
  if {![regexp {^x\d+$} $objname]} {
    dict set wapp OBJECT {}
    return
  }
  if {$objname=="x000"} {error "unauthorized object"}
  dict set wapp OBJECT $objname
  dict set wapp OBJECT_URL [dict get $wapp BASE_URL]/$objname
  if {[regexp {^([^/]+)(.*)$} [dict get $wapp PATH_TAIL] all head tail]} {
    dict set wapp PATH_HEAD $head
    dict set wapp PATH_TAIL [string trimleft $tail /]
  } else {
    dict set wapp PATH_HEAD {}
    dict set wapp PATH_TAIL {}
  }
}
wapp-start $::argv
Changes to wapp.tcl.
507
508
509
510
511
512
513

514
515
516
517
518
519
520
  # by application code using a separate helper function, like
  # "wapp_decode_multipart_formdata" or somesuch.

  # Invoke the application-defined handler procedure for this page
  # request.  If an error occurs while running that procedure, generate
  # an HTTP reply that contains the error message.
  #

  set mname [dict get $wapp PATH_HEAD]
  if {[catch {
    if {$mname!="" && [llength [info commands wapp-page-$mname]]>0} {
      wapp-page-$mname
    } else {
      wapp-default
    }







>







507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
  # by application code using a separate helper function, like
  # "wapp_decode_multipart_formdata" or somesuch.

  # Invoke the application-defined handler procedure for this page
  # request.  If an error occurs while running that procedure, generate
  # an HTTP reply that contains the error message.
  #
  wapp-before-dispatch-hook
  set mname [dict get $wapp PATH_HEAD]
  if {[catch {
    if {$mname!="" && [llength [info commands wapp-page-$mname]]>0} {
      wapp-page-$mname
    } else {
      wapp-default
    }
554
555
556
557
558
559
560






561
562
563
564
565
566
567
    puts $chan [encoding convertto utf-8 [dict get $wapp .reply]]
  } else {
    puts $chan [dict get $wapp .reply]
  }
  flush $chan
  wappInt-close-channel $chan
}







# Process a single CGI request
#
proc wappInt-handle-cgi-request {} {
  global wapp env
  foreach key {
    CONTENT_LENGTH







>
>
>
>
>
>







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
    puts $chan [encoding convertto utf-8 [dict get $wapp .reply]]
  } else {
    puts $chan [dict get $wapp .reply]
  }
  flush $chan
  wappInt-close-channel $chan
}

# This routine runs just prior to request-handler dispatch.  The
# default implementation is a no-op, but applications can override
# to do additional transformations or checks.
#
proc wapp-before-dispatch-hook {} {return}

# Process a single CGI request
#
proc wappInt-handle-cgi-request {} {
  global wapp env
  foreach key {
    CONTENT_LENGTH