├── Examples
├── aolserver
│ ├── servers
│ │ └── tclws
│ │ │ ├── pages
│ │ │ ├── global
│ │ │ │ ├── server-error.tcl
│ │ │ │ └── file-not-found.tcl
│ │ │ ├── favicon.ico
│ │ │ ├── ws
│ │ │ │ ├── echoexample
│ │ │ │ │ └── index.tcl
│ │ │ │ └── mathexample
│ │ │ │ │ └── index.tcl
│ │ │ └── index.adp
│ │ │ └── modules
│ │ │ └── tcl
│ │ │ └── tclws
│ │ │ └── init.tcl
│ ├── lib
│ │ └── aolserver-log
│ │ │ ├── pkgIndex.tcl
│ │ │ └── log.tcl
│ └── tclws.tcl
├── redirect_test
│ ├── redirect_call.tcl
│ └── redirect_server.tcl
├── tclhttpd
│ ├── custom
│ │ ├── dodirs.tcl
│ │ ├── hello.tcl
│ │ ├── mypage.tcl
│ │ ├── EchoWebService.tcl
│ │ ├── faq.tcl
│ │ └── MathWebService.tcl
│ └── htdocs
│ │ ├── test.tml
│ │ ├── templates
│ │ ├── simple.subst
│ │ ├── form.tml
│ │ ├── self.tml
│ │ ├── faqfaq.tml
│ │ └── index.tml
│ │ ├── version_history.tml
│ │ ├── service
│ │ └── index.tml
│ │ ├── register.tml
│ │ ├── hacks.tml
│ │ └── index.tml
├── Echo
│ ├── EchoWibbleStart.tcl
│ ├── EchoRivetService.rvt
│ ├── EchoWebService.tcl
│ ├── EchoWibbleService.tcl
│ ├── EchoEmbeddedService.tcl
│ └── CallEchoWebService.tcl
├── README.txt
├── wub
│ └── WubApp.tcl
└── Math
│ ├── CallMathWebService.tcl
│ └── MathWebService.tcl
├── Makefile
├── pkgIndex.tcl
├── WubServer.tcl
├── License.txt
├── license.terms
├── docs
├── Rest_flavor_service_response.html
├── Dictionary_Representation_of_XML_Arrays.html
├── index.html
├── Tcl_Web_Service_Math_Example.html
├── Tcl_Web_Service_Example.html
├── Embedded_Web_Service.html
├── Defining_Types.html
├── Creating_a_Web_Service_Type.html
├── Using_Options.html
├── Creating_a_Tcl_Web_Service.html
└── style.css
├── AOLserver.tcl
├── ChannelServer.tcl
└── Wub.tcl
/Examples/aolserver/servers/tclws/pages/global/server-error.tcl:
--------------------------------------------------------------------------------
1 | global errorInfo
2 |
3 | ns_return 500 text/plain "Oops screwed up: $errorInfo"
4 |
--------------------------------------------------------------------------------
/Examples/aolserver/servers/tclws/pages/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcltk/tclws/master/Examples/aolserver/servers/tclws/pages/favicon.ico
--------------------------------------------------------------------------------
/Examples/aolserver/lib/aolserver-log/pkgIndex.tcl:
--------------------------------------------------------------------------------
1 | package ifneeded log 2.4.0 [list source [file normalize [file join [file dirname [info script]] log.tcl]]]
2 |
--------------------------------------------------------------------------------
/Examples/aolserver/lib/aolserver-log/log.tcl:
--------------------------------------------------------------------------------
1 | namespace eval ::log {
2 |
3 | proc log {level args} {
4 | ::ns_log [string totitle $level] [join $args " "]
5 | }
6 |
7 | namespace export *
8 | }
9 |
10 | package provide log 2.4.0
11 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # "make install" to copy all the stuff into a dir where Tcl can find it
3 | #
4 | # $Id$
5 | #
6 |
7 | TARGETDIR=/usr/local/lib/tclws
8 |
9 | all:
10 | @echo "Use \"make install\" to deploy files."
11 |
12 | install:
13 | mkdir -p $(TARGETDIR)
14 | cp -v *.tcl $(TARGETDIR)
15 |
16 |
--------------------------------------------------------------------------------
/Examples/redirect_test/redirect_call.tcl:
--------------------------------------------------------------------------------
1 | # Call redirect server
2 | # 2015-11-09 Harald Oehlmann
3 | # Start the redirect_server.tcl and the embedded echo sample to test.
4 | set auto_path [linsert $auto_path 0 [file join [file dirname [info script]] ../..]]
5 | package require WS::Utils
6 | package require WS::Client
7 | catch {console show}
8 | ::log::lvSuppressLE debug 0
9 | ::WS::Client::GetAndParseWsdl http://localhost:8014/service/wsEchoExample/wsdl
10 |
--------------------------------------------------------------------------------
/Examples/aolserver/servers/tclws/pages/global/file-not-found.tcl:
--------------------------------------------------------------------------------
1 | # Directory Listing File.
2 | set request [ns_conn request]
3 | set url [lindex [split $request] 1]
4 | set path $url
5 | set full_path [ns_url2file $url]
6 | ns_log Notice "Running file-not-found.tcl for $request"
7 | if {![string equal "/" "$path"] && [file isdirectory "$full_path"]} {
8 | css_dirlist $full_path $path
9 | } else {
10 | ns_returnnotice 404 "Not Found" "File $path Not Found"
11 | }
12 |
--------------------------------------------------------------------------------
/Examples/tclhttpd/custom/dodirs.tcl:
--------------------------------------------------------------------------------
1 | # code to start tclhttpd modules contained in subdirs of custom/
2 |
3 | set here [file dirname [info script]]
4 | foreach dir [glob -nocomplain [file join [file normalize $here] *]] {
5 | if {[file isdirectory $dir] && [file exists [file join $dir startup.tcl]]} {
6 | if {$Config(debug)} {
7 | Stderr "Loading code from module $dir"
8 | }
9 | if {[catch {source [file join $dir startup.tcl]} err]} {
10 | Stderr "$dir: $err"
11 | } elseif {$Config(debug)} {
12 | Stderr "Loaded [file tail $dir]: $err"
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Examples/tclhttpd/custom/hello.tcl:
--------------------------------------------------------------------------------
1 | # Trivial application-direct URL for "/hello"
2 | # The URLs under /hello are implemented by procedures that begin with "::hello::"
3 |
4 | Direct_Url /hello ::hello::
5 |
6 | namespace eval ::hello {
7 | variable x [clock format [clock seconds]]
8 | }
9 |
10 | # ::hello::/ --
11 | #
12 | # This implements /hello/
13 |
14 | proc ::hello::/ {args} {
15 | return "Hello, World!"
16 | }
17 |
18 | # ::hello::/there --
19 | #
20 | # This implements /hello/there
21 |
22 | proc ::hello::/there {args} {
23 | variable x
24 | return "Hello, World!
\nThe server started at $x"
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/tclhttpd/htdocs/test.tml:
--------------------------------------------------------------------------------
1 | [mypage::header "Test Page"]
2 |
3 | Namespaces: [namespace children ::] 4 |
5 | mypage: [info vars mypage::*] 6 |
7 | Contents: [set ::mypage::contents] 8 |
9 | This is some text. The image is generated a CGI script so 10 | we can hopefully see two threads dispatched to do work as the CGI 11 | script blocks. 12 |
|
14 | |
16 |
17 | |
18 |
19 | |
5 |
46 | 47 | 48 | [mypage::footer] 49 | -------------------------------------------------------------------------------- /Examples/tclhttpd/htdocs/templates/self.tml: -------------------------------------------------------------------------------- 1 | [::learn::header "Tcl in your Page"] 2 | [Doc_Dynamic] 3 | 4 | This page shows what you can do with a little bit of Tcl code in a page. 5 | 6 | 10 | 21 | Right below the <hr> horizontal line we'll display the 22 | result of the Example1 procedure: 23 |24 |
26 | [if {[catch {interp eval learn Example1} result]} { 27 | set _ "Error
\n$result\n" 28 | } else { 29 | set _ $result 30 | }] 31 |
32 |
34 | The body of the Example1 procedure is shown here. 35 |
46 | Hint if there is no procedure, try47 | return "<b>\[clock format \[clock seconds\]\]</b>" 48 |49 | Understand that this code runs with all the powers of the 50 | web server application. If you want to halt the server, try this. 51 |
52 | exit 53 |54 | Ha! tried it, huh? This page runs Example1 in a Safe-Tcl interpreter, 55 | although the TML template system normally runs the templates in 56 | the main interpreter of your application. 57 | [mypage::footer] 58 | -------------------------------------------------------------------------------- /Examples/wub/WubApp.tcl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env tclsh 2 | lappend ::auto_path [file dirname [info script]] 3 | lappend ::auto_path ../Wub/Wub/ ;# add Wub's directory to auto_path 4 | package require WS::Server 5 | 6 | ## 7 | ## Define the service 8 | ## 9 | ::WS::Server::Service -mode wub \ 10 | -htmlhead {Wub Based Web Services} \ 11 | -service wsEchoExample \ 12 | -description {Echo Example - Tcl Web Services} \ 13 | -ports 8080 14 | 15 | ## 16 | ## Define any special types 17 | ## 18 | ::WS::Utils::ServiceTypeDef Server wsEchoExample echoReply { 19 | echoBack {type string} 20 | echoTS {type dateTime} 21 | } 22 | 23 | ## 24 | ## Define the operations available 25 | ## 26 | ::WS::Server::ServiceProc \ 27 | wsEchoExample \ 28 | {SimpleEcho {type string comment {Requested Echo}}} \ 29 | { 30 | TestString {type string comment {The text to echo back}} 31 | } \ 32 | {Echo a string back} { 33 | 34 | return [list SimpleEchoResult $TestString] 35 | } 36 | 37 | ::WS::Server::ServiceProc \ 38 | wsEchoExample \ 39 | {ComplexEcho {type echoReply comment {Requested Echo -- text and timestamp}}} \ 40 | { 41 | TestString {type string comment {The text to echo back}} 42 | } \ 43 | {Echo a string and a timestamp back} { 44 | 45 | set timeStamp [clock format [clock seconds] -format {%Y-%m-%dT%H:%M:%SZ} -gmt yes] 46 | return [list ComplexEchoResult [list echoBack $TestString echoTS $timeStamp] ] 47 | } 48 | 49 | #### Wub specific application start 50 | package require Site ;# load up the site 51 | 52 | # Initialize Site 53 | Site init home [file normalize [file dirname [info script]]] ini site.ini debug 10 54 | 55 | # this defines the mapping from URL to Wsdl interface objects 56 | package require Nub 57 | package require WS::Wub 58 | Nub domain /service/wsEchoExample Wsdl -service wsEchoExample 59 | Nub domain /service/wsEchoExample2 Wsdl -service wsEchoExample ;# you can have multiple Wsdl instances 60 | 61 | # Start Site Server(s) 62 | Site start 63 | -------------------------------------------------------------------------------- /Examples/tclhttpd/htdocs/templates/faqfaq.tml: -------------------------------------------------------------------------------- 1 | [html::description "tclhttpd FAQ generator FAQ"] 2 | [html::keywords ] 3 | [html::author "Colin McCormack"] 4 | [mypage::header "tclhttpd FAQ generator FAQ"] 5 | 6 | [FAQinit "tclhttpd FAQ FAQ"] 7 | 8 | 52 | 53 | [FAQgen] 54 | 55 | [mypage::footer] 56 | -------------------------------------------------------------------------------- /license.terms: -------------------------------------------------------------------------------- 1 | This software is copyrighted by the Gerald W. Leser and other parties. The following terms apply to all files 2 | associated with the software unless explicitly disclaimed in 3 | individual files. 4 | 5 | The authors hereby grant permission to use, copy, modify, distribute, 6 | and license this software and its documentation for any purpose, provided 7 | that existing copyright notices are retained in all copies and that this 8 | notice is included verbatim in any distributions. No written agreement, 9 | license, or royalty fee is required for any of the authorized uses. 10 | Modifications to this software may be copyrighted by their authors 11 | and need not follow the licensing terms described here, provided that 12 | the new terms are clearly indicated on the first page of each file where 13 | they apply. 14 | 15 | IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY 16 | FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 17 | ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY 18 | DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE 19 | POSSIBILITY OF SUCH DAMAGE. 20 | 21 | THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE 24 | IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE 25 | NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 26 | MODIFICATIONS. 27 | 28 | GOVERNMENT USE: If you are acquiring this software on behalf of the 29 | U.S. government, the Government shall have only "Restricted Rights" 30 | in the software and related documentation as defined in the Federal 31 | Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you 32 | are acquiring the software on behalf of the Department of Defense, the 33 | software shall be classified as "Commercial Computer Software" and the 34 | Government shall have only "Restricted Rights" as defined in Clause 35 | 252.227-7014 (b) (3) of DFARs. Notwithstanding the foregoing, the 36 | authors grant the U.S. Government and others acting in its behalf 37 | permission to use and distribute the software in accordance with the 38 | terms specified in this license. 39 | -------------------------------------------------------------------------------- /docs/Rest_flavor_service_response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
15 | Contents16 |
|
22 | 23 |
24 | 25 |Since TCLWS 2.4, it is possible to return a response in REST style. 27 | This means, that a JSON reply is returned instead of an XML document.
28 |Our use case has only required us to accept FORM arguments and return JSON responses for everything, so we haven't implemented logic to parse any input arguments that are passed in as JSON serialized data, but this might be an area of future exploration for someone.
29 | 30 | 31 |Here's a bit of code showing how we initially start up this mode in Apache Rivet, which is actually pretty similar to how you'd use tclws in SOAP mode from Apache Rivet:
33 |
34 | # Capture the info from the request into an array.
35 | load_headers hdrArray
36 | set sock [pid]; # an arbitrary value
37 | array unset ::Httpd$sock
38 |
39 | # Prepare the CGI style arguments into a list
40 | load_response formArray
41 | set opname $formArray(call)
42 | unset formArray(call)
43 | set queryarg [list $opname [array get formArray]]
44 |
45 | # Invoke the the method
46 | array set ::Httpd$sock [list query $queryarg ipaddr [env REMOTE_ADDR] headerlist [array get hdrArray]]
47 |
48 | # Invoke the method in REST mode.
49 | set result [catch {::WS::Server::callOperation $svcname $sock -rest} error]
50 | array unset ::Httpd$sock
51 | if {$result} {
52 | headers numeric 500
53 | puts "Operation failed: $error"
54 | abort_page
55 | }
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/Examples/tclhttpd/htdocs/hacks.tml:
--------------------------------------------------------------------------------
1 | [mypage::header "Tcl Server Info"]
2 |
3 |
8 | This server has the interesting ability to reload parts of its implementation
9 | dynamically. This lets you add features and fix bugs without ever
10 | restarting.
11 | It is even possible to setup a debug session with TclPro.
12 | This is made possible with the help of the /debug URL. The debug module
13 | has e.g. several useful URLs that let you examine variable values and other internal state.
14 |
15 |
16 | The /debug URLs are:
17 |
18 | /debug/source?source=<value>&thread=<value>
19 |
20 | /debug/package?package=<value>
21 |
22 | /debug/pvalue?aname=<value>
23 |
24 | /debug/parray?aname=<value>
25 |
26 | /debug/raise?args
27 |
28 | /debug/after
29 |
30 | /debug/echo?title=<value>&args
31 |
32 | /debug/errorInfo?title=<value>&errorInfo=<value>&no=<value>
33 |
34 | /debug/dbg?host=<value>&port=<value>
35 |
36 | /debug/showproc?showproc=<value>
37 |
38 | /debug/disable
39 |
40 | For more specific information about the calls see the debug module.
41 |
42 | Some examples: 43 |
44 |
47 |48 |
51 | 52 |53 |
56 |57 |
9 | XML arrays are represented in dictionary format as a list of values. 10 | Lets consider what this looks like for a 11 | simple type and for a 12 | complex type;. 13 |
14 | 15 |18 | Lets assume we have an element with the following definition: 19 |
<xs:element minOccurs="0" maxOccurs="unbounded" name="Primes" type="xs:integer" /> 20 |21 | Lets also assume that we will have that element in our dictionary with 22 | the first four prime numbers, thus the dictionary representation for 23 | that element would look like: 24 |
Primes {2 3 5 7}
25 |
26 | Or, if we have are using attributes (i.e. parseInAttr and/or genOutAttr are set), it would look like:
27 | Primes {{} {2 3 5 7}}
28 |
29 |
30 |
31 | 34 | Lets assume we have the type definition: 35 |
<xs:element name="Person"> 36 | <xs:complexType> 37 | <xs:sequence> 38 | <xs:element name="FristName" type="xs:string"/> 39 | <xs:element name="LastName" type="xs:integer"/> 40 | </xs:sequence> 41 | </xs:complexType> 42 | </xs:element> 43 |44 | Lets assume we have the following definition: 45 |
<xs:element minOccurs="0" maxOccurs="unbounded" name="Attendees" type="Person" /> 46 |47 | Now lets assume the following people are are attending: 48 |
Attendees {
54 | {FirstName {John} LastName {Doe}}
55 | {FirstName {Jane} LastName {Doe}}
56 | }
57 |
58 | Or, if we have are using attributes (i.e. parseInAttr and/or genOutAttr are set), it would look like:
59 | Attendees {
60 | {{} {FirstName {{} {John}} LastName {{} {Doe}}}}
61 | {{} {FirstName {{} {Jane}} LastName {{} {Doe}}}}
62 | }
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Examples/aolserver/servers/tclws/pages/ws/mathexample/index.tcl:
--------------------------------------------------------------------------------
1 | package require WS::AOLserver
2 |
3 | ::WS::AOLserver::Init
4 |
5 |
6 | ##
7 | ## Define the service
8 | ##
9 | ::WS::Server::Service \
10 | -service $service \
11 | -mode aolserver \
12 | -prefix $prefix \
13 | -description {Math Example - Tcl Web Services} \
14 | -host $host \
15 | -ports $port
16 |
17 | ##
18 | ## Define the operations available
19 | ##
20 | ::WS::Server::ServiceProc \
21 | $service \
22 | {Add {type string comment {Sum of two number}}} \
23 | {
24 | N1 {type double comment {First number to add}}
25 | N2 {type double comment {Second number to add}}
26 | } \
27 | {Add two numbers} {
28 |
29 | return [list AddResult [expr {$N1 + $N2}]]
30 | }
31 |
32 | ::WS::Server::ServiceProc \
33 | $service \
34 | {Subtract {type string comment {Difference of two number}}} \
35 | {
36 | Minuend {type double comment {Number to subtrack from}}
37 | Subtrahend {type double comment {Number to be subtracked}}
38 | } \
39 | {Subtract one number from another} {
40 |
41 | return [list SubtractResult [expr {$Minuend - $Subtrahend}]]
42 | }
43 |
44 | ::WS::Server::ServiceProc \
45 | $service \
46 | {Multiply {type string comment {Product of two number}}} \
47 | {
48 | N1 {type double comment {First number to multiply}}
49 | N2 {type double comment {Second number to multiply}}
50 | } \
51 | {Multiply two numbers} {
52 |
53 | return [list MultiplyResult [expr {$N1 * $N2}]]
54 | }
55 |
56 | ::WS::Server::ServiceProc \
57 | $service \
58 | {Divide {type string comment {Quotient of two number}}} \
59 | {
60 | Dividend {type double comment {Number that is being divided}}
61 | Divisor {type double comment {Number dividing}}
62 | } \
63 | {Divide one number by another} {
64 |
65 | if {$Divisor == 0.0} {
66 | return \
67 | -code error \
68 | -errorcode [list MATH DIVBYZERO] \
69 | "Can not divide by zero"
70 | }
71 |
72 | return [list DivideResult [expr {$Dividend + $Divisor}]]
73 | }
74 |
75 | ::WS::Server::ServiceProc \
76 | $service \
77 | {Sqrt {type string comment {Square root of a non-negative number}}} \
78 | {
79 | X {type double comment {Number raised to the half power}}
80 | } \
81 | {The the square root of a number} {
82 |
83 | if {$X < 0.0} {
84 | return \
85 | -code error \
86 | -errorcode [list MATH RANGERR] \
87 | "Can not take the square root of a negative number, $X"
88 | }
89 |
90 | return [list SqrtResult [expr {sqrt($X)}]]
91 | }
92 |
93 | ::WS::AOLserver::Return
--------------------------------------------------------------------------------
/AOLserver.tcl:
--------------------------------------------------------------------------------
1 | package require Tcl 8.6-
2 |
3 | namespace eval ::WS::AOLserver {
4 |
5 | if {![info exists logVersion]} {
6 | variable logVersion [package require log]
7 | }
8 | if {![info exists wsVersion]} {
9 | variable wsVersion [package require WS::Server]
10 | }
11 |
12 | namespace import -force ::log::log
13 | }
14 |
15 | proc ::WS::AOLserver::ReturnData {sock type data code} {
16 |
17 | log debug "AOLserver::ReturnData returning $code $type $data"
18 | ns_return $code $type $data
19 |
20 | }
21 |
22 | proc ::WS::AOLserver::AddHandler {args} {
23 | log debug "AOLserver::AddHandler added '$args'"
24 | }
25 |
26 | proc ::WS::AOLserver::Init { } {
27 |
28 | uplevel 1 {
29 | set server [ns_info server]
30 | set nsset [ns_configsection "ns/server/$server/module/nssock"]
31 | set headerSet [ns_conn headers]
32 | set host [string tolower [ns_set iget $headerSet host]]
33 | set hostList [split $host :]
34 | set peeraddr [ns_conn peeraddr]
35 |
36 | if {[llength $hostList] == 1} {
37 | set port 80
38 | } else {
39 | set port [lindex $hostList 1]
40 | }
41 |
42 | set url [lindex [split [lindex [ns_conn request] 1] ?] 0]
43 | set urlv [split $url /]
44 |
45 | switch -exact -- [lindex $urlv end] {
46 | "" {
47 | # get service description
48 | set requestType doc
49 | }
50 | "wsdl" {
51 | # return wsdl
52 | set requestType wsdl
53 | }
54 | "op" {
55 | set requestType op
56 | }
57 | default {
58 | set requestType [lindex $urlv end]
59 | }
60 | }
61 |
62 | set prefix [join [lrange $urlv 0 end-1] /]
63 | set service [lindex $urlv end-1]
64 |
65 | ::log::log debug "prefix = $prefix service = $service requestType = $requestType"
66 | }
67 | }
68 |
69 | proc ::WS::AOLserver::Return {} {
70 |
71 | uplevel 1 {
72 |
73 | set sock nosock
74 |
75 | switch -exact -- $requestType {
76 |
77 | doc {
78 | ::WS::Server::generateInfo $service $sock
79 | }
80 | wsdl {
81 | ::WS::Server::generateWsdl $service $sock
82 | }
83 | op {
84 | upvar #0 Httpd$sock data
85 |
86 | # Copy Headers/ip
87 | set headerLength [ns_set size $headerSet]
88 | for {set i 0} {$i < $headerLength} {incr i} {
89 | lappend headers [ns_set key $headerSet $i] [ns_set value $headerSet $i]
90 | }
91 | set data(ipaddr) $peeraddr
92 | set data(headerlist) $headers
93 |
94 | # Get POSTed data
95 | set length [ns_set iget $headerSet "Content-length"]
96 | set tmpFile [ns_tmpnam]
97 | ::log::log debug "Using tmpFile = $tmpFile"
98 | set fp [ns_openexcl $tmpFile]
99 | fconfigure $fp -translation binary
100 | ns_conn copy 0 $length $fp
101 | seek $fp 0
102 | set data(query) [read $fp]
103 | close $fp
104 |
105 | # Run request
106 | ::WS::Server::callOperation $service $sock
107 | }
108 | default {
109 | ns_return 200 text/plain "prefix = $prefix service = $service requestType = $requestType"
110 | }
111 | }
112 | }
113 | }
114 |
115 | package provide WS::AOLserver 2.5.0
116 |
--------------------------------------------------------------------------------
/Examples/tclhttpd/htdocs/templates/index.tml:
--------------------------------------------------------------------------------
1 | [mypage::header "HTML/Tcl Templates"]
2 | 3 | A Tcl template works by mixing Tcl code into normal HTML pages. 4 | The server uses the Tcl subst command to replace the Tcl code and 5 | variable references with their results and values. 6 | Here are a few examples: 7 |
| Tcl fragment | Result |
|---|---|
| $code | [subst $code] |
19 | There are two template systems provided by the Doc module: 20 | tml and subst templates. They both work 21 | in a similar way to replace in-line Tcl, 22 | but they differ in the setup done before a page is processed. 23 | 24 |
39 | The ".tml" template system provides caching of template results 40 | in static ".html" files. This saves the cost of re-processing the 41 | template each time you access the file. 42 | By default, the file page.html contains the cached results 43 | of processing the file page.tml. If the page.tml 44 | page is modified, the cached copy is regenerated. To get the 45 | cache, you have to ask for the page.html file. The server 46 | automatically checks to see if there is a corresponding page.tml 47 | file, processes the template, caches the result in page.html, 48 | and returns the result. 49 |
50 | However, you don't want 51 | to cache if the page must be processed on each access. 52 | If you don't want your templates cached, put a call to 53 |
\[Doc_Dynamic\]54 | into your page. That surpresses the caching of the template results. 55 | 56 |
58 | Before processing a page.tml page, the server loads 59 | any file named ".tml" (no prefix) in the same directory. 60 | This allows you to put procedure and variable definitions in 61 | the ".tml" file that are shared among the pages in that directory. 62 |
63 | The server looks up the directory hierarchy to the document root 64 | for additional ".tml" files. These are all loaded in order from the 65 | root down towards the directory containing the template file page.tml. 66 | If you look at the sample htdocs tree that comes with the server, 67 | you can see how these .tml files are used. 68 | 69 |
| [html::font]]] |