├── 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 | 13 | 20 |
14 | 15 | 16 | 17 | 18 | 19 |
21 | [mypage::footer] 22 | -------------------------------------------------------------------------------- /pkgIndex.tcl: -------------------------------------------------------------------------------- 1 | package ifneeded WS::AOLserver 2.5.0 [list source [file join $dir AOLserver.tcl]] 2 | package ifneeded WS::Channel 2.5.0 [list source [file join $dir ChannelServer.tcl]] 3 | package ifneeded WS::Client 3.1.0 [list source [file join $dir ClientSide.tcl]] 4 | package ifneeded WS::Embeded 3.4.0 [list source [file join $dir Embedded.tcl]] 5 | package ifneeded WS::Server 3.5.0 [list source [file join $dir ServerSide.tcl]] 6 | package ifneeded WS::Utils 3.2.0 [list source [file join $dir Utilities.tcl]] 7 | package ifneeded WS::Wub 2.5.0 [list source [file join $dir WubServer.tcl]] 8 | package ifneeded Wsdl 2.4.0 [list source [file join $dir WubServer.tcl]] 9 | -------------------------------------------------------------------------------- /Examples/aolserver/servers/tclws/modules/tcl/tclws/init.tcl: -------------------------------------------------------------------------------- 1 | # Require WS::AOLserver and record version 2 | # Note: All required packages must be in a lib directory. 3 | 4 | namespace eval ::WS::AOLserver { 5 | 6 | variable logVersion [ns_ictl package require log] 7 | variable wsVersion [ns_ictl package require WS::Server] 8 | variable version [ns_ictl package require WS::AOLserver] 9 | } 10 | 11 | ns_register_filter preauth GET /*/wsdl ::ws_aolserver_redirect wsdl 12 | ns_register_filter preauth POST /*/op ::ws_aolserver_redirect op 13 | 14 | proc ::ws_aolserver_redirect { why } { 15 | 16 | set urlv [split [ns_conn url] /] 17 | 18 | set new_url "[join [lrange $urlv 0 end-1] /]/index.tcl" 19 | ns_log Notice "WS::AOLserver::Redirect: from [lindex $urlv end] to '$new_url'" 20 | ns_rewriteurl $new_url 21 | 22 | return filter_ok 23 | } 24 | -------------------------------------------------------------------------------- /Examples/Echo/EchoWibbleStart.tcl: -------------------------------------------------------------------------------- 1 | ############# tclws.tcl, start script for wibble 24 (not included) ######## 2 | # Adjust auto_path to your needs 3 | lappend auto_path [file dir [info script]] lib 4 | source wibble.tcl 5 | # Set the root directory. 6 | set root html 7 | set ::Config(host) 127.0.0.1 8 | set ::Config(port) 8015 9 | 10 | source EchoWebService.tcl 11 | 12 | # Define zone handlers. 13 | ::wibble::handle /vars vars 14 | ::wibble::handle / dirslash root $root 15 | ::wibble::handle / indexfile root $root indexfile index.html 16 | ::wibble::handle / static root $root 17 | ::wibble::handle / template root $root 18 | ::wibble::handle / script root $root 19 | ::wibble::handle / dirlist root $root 20 | ::wibble::handle / notfound 21 | 22 | 23 | # Start a server and enter the event loop. 24 | catch { 25 | ::wibble::listen 8015 26 | vwait forever 27 | } 28 | -------------------------------------------------------------------------------- /Examples/tclhttpd/htdocs/templates/simple.subst: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tcl-based Templates 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Tcl-based Templates

13 | This page shows the very simple processing done 14 | for page.subst pages. 15 | These pages process Tcl embedded in pages, 16 | but don't have the more sophisticated support developed 17 | for the page.tml pages. 18 | 19 |

The time is [clock format [clock seconds]]

20 |
21 | Here is a look inside the httpd server module. 22 | This is generated with the html::tableFromArray command 23 | applied to the Httpd array variable in the server. 24 |
25 | [html::tableFromArray Httpd] 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Examples/README.txt: -------------------------------------------------------------------------------- 1 | The file EchoWebService.tcl defines a service and should be sourced in by the web services server. Normally this is done by placing it in the custom directory. 2 | 3 | 4 | The file CallEchoWebService.tcl is a Tcl script (i.e. non-GUI) designed to show how calls can be made. 5 | 6 | The file htdocs/service/index.tml should be copied to service/index.tml under the document root of the web server (normally htdocs). This page when displayed in a browser as http://localhost:8015/service/ will show a nice page listing what services you have available. The page will dynamically generate links to the info and wsdl pages that the server generates and also to status pages (located in http://localhost:8015/servicestatus/$serviceName.tml) and form pages (located in http://localhost:8015/serviceforms/$serviceName.tml). 7 | 8 | This would allow you to auto generate, or hand generate, forms to call your service operations and also status pages to monitor and control your services. 9 | 10 | Alternatively, the following could be done from the current directory (assuming that httpd.tcl is in the current PATH): 11 | httpd.tcl -docRoot ./tclhttpd/htdocs -port 8015 -library ./tclhttpd/custom/ 12 | -------------------------------------------------------------------------------- /WubServer.tcl: -------------------------------------------------------------------------------- 1 | # WSWub - Wub interface to WebServices 2 | package require Tcl 8.4- 3 | # WS::Utils usable here for dict? 4 | if {![llength [info command dict]]} { 5 | package require dict 6 | } 7 | package require WS::Server 8 | 9 | package require OO 10 | package require Direct 11 | package require Debug 12 | Debug off wsdl 10 13 | 14 | package provide WS::Wub 2.5.0 15 | package provide Wsdl 2.4.0 16 | 17 | class create Wsdl { 18 | method / {r args} { 19 | return [Http Ok $r [::WS::Server::generateInfo $service 0] text/html] 20 | } 21 | 22 | method /op {r args} { 23 | if {[catch {::WS::Server::callOp $service 0 [dict get $r -entity]} result]} { 24 | return [Http Ok $r $result] 25 | } else { 26 | dict set r -code 500 27 | dict set r content-type text/xml 28 | dict set r -content $result 29 | return [NoCache $r] 30 | } 31 | } 32 | 33 | method /wsdl {r args} { 34 | return [Http Ok $r [::WS::Server::GetWsdl $service] text/xml] 35 | } 36 | 37 | mixin Direct ;# Direct mixin maps the URL to invocations of the above methods 38 | variable service 39 | constructor {args} { 40 | set service [dict get $args -service] ;# we need to remember the service name 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Examples/tclhttpd/htdocs/templates/form.tml: -------------------------------------------------------------------------------- 1 | [html::author "Brent Welch"] 2 | [mypage::header "Templates and State"] 3 | Sample Form 4 |

5 |

6 | 7 | [html::row "General Info" ""] 8 | [html::row "Exclusive Choice" \ 9 | [html::radioSet somevariable { } { 10 | orange Orange 11 | blue Blue 12 | green Green 13 | "violet red" "Violet Red" 14 | }]] 15 | [html::row "Selection" \ 16 | [html::select mutli 1 { 17 | "" "Please Select" 18 | orange Orange 19 | blue Blue 20 | green Green 21 | "violet red" "Violet Red" 22 | }]] 23 | [html::row "Multiple Choice " \ 24 | [html::checkSet check " " { 25 | orange Orange 26 | blue Blue 27 | green Green 28 | "violet red" "Violet Red" 29 | }]] 30 |
31 | Hit this page with form data: 32 | 33 | 34 |

35 | When a template is processed, information about the CGI values 36 | is available via the ncgi module, 37 | and the html module used to create the above form 38 | automatically initializes the form elements to match the CGI values. 39 |

40 | CGI Values
41 | [html::tableFromList [ncgi::nvlist] "border=1"] 42 |

43 | Environment
44 | [html::tableFromArray ::env "border=1" *] 45 | 46 | [mypage::footer] 47 | -------------------------------------------------------------------------------- /Examples/tclhttpd/htdocs/version_history.tml: -------------------------------------------------------------------------------- 1 | [html::author "Brent Welch"] 2 | [mypage::header "TclHttpd Version History"] 3 |

4 | Current versions running in this server: 5 |
6 | TclHttpd $Httpd(version) 7 |
8 | Tcl $tcl_patchLevel 9 |

10 | TclHttpd has been tested on Tcl 8.3, Tcl 8.4, and early versions 11 | of Tcl 8.5. 12 | For information about Tcl distributions, 13 | visit www.tcl.tk. 14 |

15 | The server also depends on the Standard Tcl Library. The server 16 | should work with tcllib version >= 1.2. The current tcllib version is 1.5. 17 | For the latest tcllib, see the tcllib SourceForge project. 18 | 19 |

20 | Using older verions: 21 |

30 | 31 |

32 | FTP site 33 |

34 | ftp://ftp.tcl.tk/pub/tcl/httpd 35 |

36 | [mypage::footer] 37 | -------------------------------------------------------------------------------- /Examples/aolserver/servers/tclws/pages/ws/echoexample/index.tcl: -------------------------------------------------------------------------------- 1 | 2 | package require WS::AOLserver 3 | 4 | ::WS::AOLserver::Init 5 | 6 | ::WS::Server::Service \ 7 | -mode aolserver \ 8 | -prefix $prefix \ 9 | -service $service \ 10 | -description {Tcl Example Web Services} \ 11 | -host $host \ 12 | -ports $port 13 | 14 | ## 15 | ## Define any special types 16 | ## 17 | ::WS::Utils::ServiceTypeDef Server $service echoReply { 18 | echoBack {type string} 19 | echoTS {type dateTime} 20 | } 21 | 22 | ## 23 | ## Define the operations available 24 | ## 25 | ::WS::Server::ServiceProc \ 26 | $service \ 27 | {SimpleEcho {type string comment {Requested Echo}}} \ 28 | { 29 | TestString {type string comment {The text to echo back}} 30 | } \ 31 | {Echo a string back} { 32 | return [list SimpleEchoResult $TestString] 33 | } 34 | 35 | 36 | ::WS::Server::ServiceProc \ 37 | $service \ 38 | {ComplexEcho {type echoReply comment {Requested Echo -- text and timestamp}}} \ 39 | { 40 | TestString {type string comment {The text to echo back}} 41 | } \ 42 | {Echo a string and a timestamp back} { 43 | set timeStamp [clock format [clock seconds] -format {%Y-%m-%dT%H:%M:%SZ} -gmt yes] 44 | return [list ComplexEchoResult [list echoBack $TestString echoTS $timeStamp] ] 45 | } 46 | 47 | ::WS::AOLserver::Return -------------------------------------------------------------------------------- /Examples/tclhttpd/htdocs/service/index.tml: -------------------------------------------------------------------------------- 1 | [Doc_Dynamic] 2 | 3 | 4 | [::html::init] 5 | [::html::head {Web Services for Tcl - Available Services}] 6 | 7 | [::html::bodyTag] 8 | [mypage::contents {}] 9 | [::html::h1 {Web Services for Tcl - Available Services}] 10 | 11 | [::html::openTag TABLE border=10 ] 12 | [::html::hdrRow {Service} {Description} {Info Link} {WSDL Link} {Status} {Forms}] 13 | 14 | [ 15 | set data {} 16 | foreach serviceName [array names ::WS::Server::serviceArr] { 17 | set statusFile [file normalize [file join $Config(docRoot) servicestatus $serviceName.tml]] 18 | if {[file exist $statusFile]} { 19 | set statusLink "Status" 20 | } else { 21 | set statusLink {None} 22 | } 23 | set formsFile [file normalize [file join $Config(docRoot) serviceforms $serviceName.tml]] 24 | if {[file exist $formsFile]} { 25 | set formsLink "Forms" 26 | } else { 27 | set formsLink {None} 28 | } 29 | append data [::html::row $serviceName \ 30 | [dict get $::WS::Server::serviceArr($serviceName) -description] \ 31 | [format {Infomation} $serviceName]\ 32 | [format {WSDL} $serviceName] \ 33 | $statusLink \ 34 | $formsLink] 35 | } 36 | set data 37 | ] 38 | 39 | [mypage::footer] 40 | 41 | [::html::end] 42 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2006-2013, Gerald W. Lester 3 | Copyright (c) 2006, Visiprise Software, Inc 4 | Copyright (c) 2006, Colin McCormack 5 | Copyright (c) 2006, Rolf Ade 6 | Copyright (c) 2001-2006, Pat Thoyts 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 13 | * Neither the name of the Visiprise Software, Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 | -------------------------------------------------------------------------------- /Examples/redirect_test/redirect_server.tcl: -------------------------------------------------------------------------------- 1 | # Test tclws redirection 2 | # 2015-11-09 by Harald Oehlmann 3 | # 4 | # If (set loop 1), infinite redirect is tested, otherwise one redirect. 5 | # Start the embedded test server and use redirect_call to call. 6 | # 7 | set auto_path [linsert $auto_path 0 [file join [file dirname [info script]] ../..]] 8 | catch {console show} 9 | package require uri 10 | 11 | proc ::Listen {port} { 12 | return [socket -server ::Accept $port] 13 | } 14 | 15 | 16 | proc ::Accept {sock ip clientport} { 17 | if {1 == [catch { 18 | gets $sock line 19 | set request {} 20 | while {[gets $sock temp] > 0 && ![eof $sock]} { 21 | if {[regexp {^([^:]*):(.*)$} $temp -> key data]} { 22 | dict set request header [string tolower $key] [string trim $data] 23 | } 24 | } 25 | if {[eof $sock]} { 26 | puts "Connection closed from $ip" 27 | return 28 | } 29 | if {![regexp {^([^ ]+) +([^ ]+) ([^ ]+)$} $line -> method url version]} { 30 | puts "Wrong request: $line" 31 | return 32 | } 33 | array set uri [::uri::split $url] 34 | if {[info exists ::loop]} { 35 | set uri(host) "localhost:8014" 36 | } else { 37 | set uri(host) "localhost:8015" 38 | } 39 | set url [eval ::uri::join [array get uri]] 40 | puts "Redirecting to $url" 41 | puts $sock "HTTP/1.1 301 Moved Permanently" 42 | puts $sock "Location: $url" 43 | puts $sock "Content-Type: text/html" 44 | puts $sock "Content-Length: 0\n\n" 45 | close $sock 46 | } Err]} { 47 | puts "Socket Error: $Err" 48 | return 49 | } 50 | } 51 | 52 | Listen 8014 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Examples/tclhttpd/htdocs/register.tml: -------------------------------------------------------------------------------- 1 | [mypage::header "Tcl Web Server Registration"] 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

10 | If you are unable to post the registration form, an informal 11 | note to [html::mailto welch@acm.org "Register WebServer"] would be appreciated. 12 | 13 |

14 | Ahem, this form is all great and everything, but I don't have a good 15 | "email this form data" handler running, so the mail will go into 16 | the bit bucket. The best thing to do is introduce yourself on 17 | the tclhttpd mailing list. 18 | 19 |

20 |

User Registration

21 | 22 | [html::textInputRow "Name" name] 23 | [html::textInputRow "Email" emailaddr] 24 | [html::cell colspan=2 [html::checkSet noemail {} { 25 | "Do not contact me about new releases" 1 26 | }]] 27 | [html::textInputRow "Title" title] 28 | [html::textInputRow "Company" company] 29 |
30 |

How do you plan to use the server?
31 | 33 |

34 | 35 | For more general comments, please send email to 36 | welch@acm.org. 37 | There is also a mailing list for users of the Tcl Web Server. 38 | You can join this list by 39 | visiting 40 | http://lists.sourceforge.net/mailman/listinfo/tclhttpd-users. 41 | Send mail to the list at [html::mailto tclhttpd-users@lists.sourceforge.net] 42 |

43 | [html::submit "Register (test)"] 44 |
45 |

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 |


25 |

26 | [if {[catch {interp eval learn Example1} result]} { 27 | set _ "Error

\n$result\n
" 28 | } else { 29 | set _ $result 30 | }] 31 |

32 |


33 |

34 | The body of the Example1 procedure is shown here. 35 |

36 | 43 |

44 | 45 |

46 | Hint if there is no procedure, try
47 | 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 | Rest-flavor service reply 4 | 5 | 6 | 7 | 8 |

Rest-flavor service reply

9 | 10 |
11 | 12 | 13 | 14 |
15 |

Contents

16 |
21 |

22 | 23 |

24 | 25 |

Overview

26 |

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 |

Rivet Example

32 |

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 |

Status

4 | [StatusMenu] 5 | 6 |

Debugging

7 |

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 |

45 | 46 |
47 |

48 |

49 | 50 |
51 | 52 |

53 |

54 | 55 |
56 |

57 |

TclPro

58 | It is also possible to debug tclhttpd with TclPro. 59 | Briefly you have to perform following steps: 60 |
61 | Enable the tclhttpd server for debugging (see httpdthread.tcl). 62 |
63 | Setup a Project in TclPro with Debugging Type "Remote Debugging"; 64 | define the portnumber; start TclPro by calling 65 |

66 | http://yourserver:port/debug/dbg?host=<hostname>&port=<portnumber> 67 |

68 | The tclhttpd server will connect to a TclPro Session running on host <hostname> 69 | listening for remote connections on port number <portnumber> 70 |
71 | In case TclPro is running on the "localhost" listening for the default portnumber "2576" 72 | it is enough to call 73 |

74 | http://yourserver:port/debug/dbg 75 | 76 | [mypage::footer] 77 | -------------------------------------------------------------------------------- /docs/Dictionary_Representation_of_XML_Arrays.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Web Services for Tcl (aka tclws): Dictionary Representation of XML Arrays 5 | 6 | 7 | 8 |

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 |

16 |

Array of Simple Type

17 |

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 |

32 |

Array of Complex Type

33 |

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 | 52 | Thus the dictionary representation for that element would look like: 53 |
    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 | 8 | 9 | [html::foreach {code} { 10 | {[Httpd_Version]} 11 | {[clock format [clock seconds]]} 12 | {$Doc(root)} 13 | {[expr 7 * 826]} 14 | } { 15 | 16 | }] 17 |
Tcl fragmentResult
$code[subst $code]
18 |

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 |

Simple "subst" Templates

25 | 26 | If you have a file 27 | that ends with ".subst", 28 | then it is processed every time the page is fetched. 29 | There is relatively little setup done before processing the page. 30 | 31 | 32 |

tml Templates

33 | The ".tml" template system is similar to the ".subst" system, 34 | but it provides caching and additional 35 | setup before pages are processed. 36 | 37 |

Caching Template Results

38 |

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 |

Per-directory .tml files

57 |

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 |

More Examples

70 | 84 | 85 | [mypage::footer] 86 | -------------------------------------------------------------------------------- /Examples/aolserver/tclws.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # $Header: /cvsroot/aolserver/aolserver/examples/config/base.tcl,v 1.4 2007/08/01 21:35:26 michael_andrews Exp $ 3 | # $Name: $ 4 | # 5 | # base.tcl -- 6 | # 7 | # A simple example of a Tcl based AOLserver configuration file. 8 | # 9 | # Results: 10 | # 11 | # HTTP (nssock): 12 | # 13 | # http://
:8000/ 14 | # 15 | # Server Page Root: 16 | # 17 | # $AOLSERVER/servers/server1/pages 18 | # 19 | # Server Access Log: 20 | # 21 | # $AOLSERVER/servers/server1/modules/nslog/access.log 22 | # 23 | # Notes: 24 | # 25 | # To start AOLserver, make sure you are in the AOLserver 26 | # installation directory, usually /usr/local/aolserver, and 27 | # execute the following command: 28 | # 29 | # % bin/nsd -ft sample-config.tcl 30 | # 31 | 32 | set server tclws 33 | set home [file dirname [ns_info config]] 34 | set pageRoot $home/servers/$server/pages 35 | 36 | 37 | ns_section "ns/parameters" 38 | ns_param home $home 39 | ns_param logdebug true 40 | ns_param logusec true 41 | 42 | 43 | ns_section "ns/mimetypes" 44 | ns_param default "*/*" 45 | ns_param .adp "text/html; charset=iso-8859-1" 46 | 47 | ns_section "ns/encodings" 48 | ns_param adp "iso8859-1" 49 | 50 | ns_section "ns/threads" 51 | ns_param stacksize [expr 128 * 1024] 52 | 53 | ns_section "ns/servers" 54 | ns_param $server "$server" 55 | 56 | ns_section "ns/server/$server" 57 | ns_param directoryfile "index.tcl,index.htm,index.html,index.adp" 58 | ns_param pageroot $pageRoot 59 | ns_param maxthreads 20 60 | ns_param minthreads 5 61 | ns_param maxconnections 20 62 | ns_param urlcharset "utf-8" 63 | ns_param outputcharset "utf-8" 64 | ns_param inputcharset "utf-8" 65 | ns_param enabletclpages true 66 | ns_param chunked true 67 | ns_param nsvbuckets 8 68 | ns_param errorminsize 514 69 | 70 | ns_section "ns/server/$server/adp" 71 | ns_param map "/*.adp" 72 | ns_param defaultparser fancy ; # adp 73 | ns_param cachesize 40 74 | 75 | ns_section ns/server/${server}/adp/parsers 76 | ns_param fancy ".adp" 77 | 78 | ns_section ns/server/${server}/tcl 79 | ns_param autoclose "on" 80 | ns_param debug "true" ;# false 81 | ns_param nsvbuckets "8" 82 | 83 | ns_section "ns/server/$server/modules" 84 | ns_param nssock nssock.so 85 | ns_param nslog nslog.so 86 | ns_param nscp nscp.so 87 | ns_param nsrewrite nsrewrite.so 88 | ns_param tclws tcl 89 | 90 | ns_section "ns/server/$server/module/nssock" 91 | ns_param location http://127.0.0.1:8080 92 | ns_param hostname 127.0.0.1:8080 93 | ns_param address 127.0.0.1 94 | ns_param port 8080 95 | 96 | ns_section "ns/server/$server/module/nslog" 97 | ns_param rolllog true 98 | ns_param rollonsignal true 99 | ns_param rollhour 0 100 | ns_param maxbackup 2 101 | 102 | ns_section "ns/server/$server/module/nscp" 103 | ns_param address "127.0.0.1" 104 | ns_param port 8081 105 | ns_param cpcmdlogging "false" 106 | 107 | ns_section "ns/server/$server/module/nscp/users" 108 | ns_param user ":" 109 | ns_param user "tom:1.7MASVQIxdCA" 110 | 111 | # Testing 112 | # Server url, Proxy & Redirects 113 | ns_section "ns/server/${server}/redirects" 114 | ns_param 404 "global/file-not-found.tcl" 115 | #ns_param 403 "global/forbidden.html" 116 | ns_param 500 "global/server-error.tcl" 117 | 118 | -------------------------------------------------------------------------------- /Examples/Echo/EchoRivetService.rvt: -------------------------------------------------------------------------------- 1 | 119 | -------------------------------------------------------------------------------- /Examples/tclhttpd/custom/mypage.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Tcl Httpd local site templates 3 | # 4 | # SCCS: @(#) mypage.tcl 1.5 97/12/23 21:11:10 5 | # 6 | 7 | package provide mypage 1.0 8 | 9 | namespace eval mypage { 10 | namespace export * 11 | } 12 | 13 | # mypage::contents 14 | # 15 | # Define the site contents 16 | # 17 | # Arguments: 18 | # list List of URL, labels for each page in the site 19 | # 20 | # Side Effects: 21 | # Records the site structure 22 | 23 | proc mypage::contents {list} { 24 | variable contents $list 25 | } 26 | 27 | # mypage::header 28 | # 29 | # Generate HTML for the standard page header 30 | # 31 | # Arguments: 32 | # title The page title 33 | # 34 | # Results: 35 | # HTML for the page header. 36 | 37 | proc mypage::header {title} { 38 | mypage::SetLevels $title 39 | set html [html::head $title]\n 40 | append html [html::bodyTag]\n 41 | 42 | append html "\n" 43 | append html " \ 44 | [html::cell align=left "\"Home\""] \ 45 | [html::cell "" "

$title

"] \ 46 | " 47 | append html [mypage::thinrule] 48 | append html "
" 49 | append html [html::font]\n 50 | 51 | return $html 52 | } 53 | 54 | # mypage::thinrule 55 | # 56 | # Generate a thin horizontal rule, expect to be in full width table. 57 | # 58 | # Arguments: 59 | # bgcolor (optional) color 60 | # 61 | # Results: 62 | # HTML for the table row containing the rule. 63 | 64 | proc mypage::thinrule {{param {colspan=2}}} { 65 | set color [html::default thinrule.bgcolor $param] 66 | append html "[html::cell "$param $color" \ 67 | ""]\n" 68 | return $html 69 | } 70 | 71 | # mypage::SetLevels 72 | # 73 | # Map the page title to a hierarchy location in the site for the page. 74 | # 75 | # Arguments: 76 | # title The page title 77 | # 78 | # Side Effects: 79 | # Sets the level namespace variables 80 | 81 | proc mypage::SetLevels {title} { 82 | variable level 83 | } 84 | 85 | # mypage::footer 86 | # 87 | # Generate HTML for the standard page footer 88 | # 89 | # Arguments: 90 | # none 91 | # 92 | # Results: 93 | # HTML for the page footer. 94 | 95 | proc mypage::footer {} { 96 | variable contents 97 | if {![info exists contents]} { 98 | set contents {} 99 | } 100 | append html "\n" 101 | append html "\n" 102 | append html [thinrule colspan=[expr {[llength $contents]/2}]] 103 | append html [html::cell "" [html::minorMenu $contents \n 104 | append html
[html::font]]]
\n 105 | append html "\n\n" 106 | return $html 107 | } 108 | 109 | # mypage::README_links 110 | # 111 | # Generate optional links to distribution README files. 112 | # 113 | # Arguments: 114 | # none 115 | # 116 | # Results: 117 | # HTML for some links 118 | 119 | proc mypage::README_links {} { 120 | set html "" 121 | foreach f [lsort [glob -nocomplain [file join [Doc_Root] links/*]]] { 122 | if {[file tail $f] == "CVS"} { 123 | continue 124 | } 125 | if {[file exists $f]} { 126 | # Symlink is not broken 127 | set t [file tail $f] 128 | append html "
  • $t\n" 129 | } 130 | } 131 | if {[string length $html]} { 132 | set html 133 | } 134 | return $html 135 | } 136 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tcl Web Services 5 | 6 | 7 | 8 | 9 | 10 | 11 |

    Tcl Web Services

    12 | 13 |

    Summary

    14 | 15 |

    16 | The distribution provides both client side access to Web Services and server 17 | side creation of Web Services. Currently only document/literal and rpc/encoded 18 | with HTTP Soap transport are supported on the client side. The server side 19 | currently works only with TclHttpd or embedded into an application. 20 | The server side provides all services as document/literal 21 | over HTTP Soap transport. Documentation for the package, including examples can 22 | be found here. 23 |

    24 | 25 | 36 | 37 |

    38 | The client is known to work with #C and Java based Web Services (your mileage 39 | may very). 40 |

    41 | 42 |

    License

    43 | 44 |

    45 | Standard BSD. 46 |

    Web Servers

    47 | 48 |

    49 | The server side works with the following web servers: 50 |

    58 |

    59 | 60 |

    Packages Required

    61 | 62 |

    63 | The following packages are used: 64 |

    65 | 66 | 76 | 77 | 78 |

    79 | If you are running the TclHttpd on Windows, it is highly recommended that you use the iocpsock extension. 80 |

    81 | 82 |

    83 | The following packages are additionally used in Embedded Server mode: 84 |

    90 | 91 | 92 | -------------------------------------------------------------------------------- /Examples/Echo/EchoWebService.tcl: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## ## 3 | ## Copyright (c) 2006, Visiprise Software, Inc ## 4 | ## All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions ## 8 | ## are met: ## 9 | ## ## 10 | ## * Redistributions of source code must retain the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer. ## 12 | ## * Redistributions in binary form must reproduce the above ## 13 | ## copyright notice, this list of conditions and the following ## 14 | ## disclaimer in the documentation and/or other materials provided ## 15 | ## with the distribution. ## 16 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 17 | ## of its contributors may be used to endorse or promote products ## 18 | ## derived from this software without specific prior written ## 19 | ## permission. ## 20 | ## ## 21 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 22 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 23 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 24 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 25 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 26 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 27 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 29 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 30 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 31 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 32 | ## POSSIBILITY OF SUCH DAMAGE. ## 33 | ## ## 34 | ############################################################################### 35 | 36 | package require WS::Server 37 | package require WS::Utils 38 | 39 | ## 40 | ## Define the service 41 | ## 42 | ::WS::Server::Service \ 43 | -service wsEchoExample \ 44 | -description {Echo Example - Tcl Web Services} \ 45 | -host $::Config(host):$::Config(port) 46 | 47 | ## 48 | ## Define any special types 49 | ## 50 | ::WS::Utils::ServiceTypeDef Server wsEchoExample echoReply { 51 | echoBack {type string} 52 | echoTS {type dateTime} 53 | } 54 | 55 | ## 56 | ## Define the operations available 57 | ## 58 | ::WS::Server::ServiceProc \ 59 | wsEchoExample \ 60 | {SimpleEcho {type string comment {Requested Echo}}} \ 61 | { 62 | TestString {type string comment {The text to echo back}} 63 | } \ 64 | {Echo a string back} { 65 | 66 | return [list SimpleEchoResult $TestString] 67 | } 68 | 69 | 70 | ::WS::Server::ServiceProc \ 71 | wsEchoExample \ 72 | {ComplexEcho {type echoReply comment {Requested Echo -- text and timestamp}}} \ 73 | { 74 | TestString {type string comment {The text to echo back}} 75 | } \ 76 | {Echo a string and a timestamp back} { 77 | 78 | set timeStamp [clock format [clock seconds] -format {%Y-%m-%dT%H:%M:%SZ} -gmt yes] 79 | return [list ComplexEchoResult [list echoBack $TestString echoTS $timeStamp] ] 80 | } 81 | -------------------------------------------------------------------------------- /Examples/tclhttpd/custom/EchoWebService.tcl: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## ## 3 | ## Copyright (c) 2006, Visiprise Software, Inc ## 4 | ## All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions ## 8 | ## are met: ## 9 | ## ## 10 | ## * Redistributions of source code must retain the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer. ## 12 | ## * Redistributions in binary form must reproduce the above ## 13 | ## copyright notice, this list of conditions and the following ## 14 | ## disclaimer in the documentation and/or other materials provided ## 15 | ## with the distribution. ## 16 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 17 | ## of its contributors may be used to endorse or promote products ## 18 | ## derived from this software without specific prior written ## 19 | ## permission. ## 20 | ## ## 21 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 22 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 23 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 24 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 25 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 26 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 27 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 29 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 30 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 31 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 32 | ## POSSIBILITY OF SUCH DAMAGE. ## 33 | ## ## 34 | ############################################################################### 35 | 36 | package require WS::Server 37 | package require WS::Utils 38 | 39 | ## 40 | ## Define the service 41 | ## 42 | ::WS::Server::Service \ 43 | -service wsEchoExample \ 44 | -description {Echo Example - Tcl Web Services} \ 45 | -host $::Config(host):$::Config(port) 46 | 47 | ## 48 | ## Define any special types 49 | ## 50 | ::WS::Utils::ServiceTypeDef Server wsEchoExample echoReply { 51 | echoBack {type string} 52 | echoTS {type dateTime} 53 | } 54 | 55 | ## 56 | ## Define the operations available 57 | ## 58 | ::WS::Server::ServiceProc \ 59 | wsEchoExample \ 60 | {SimpleEcho {type string comment {Requested Echo}}} \ 61 | { 62 | TestString {type string comment {The text to echo back}} 63 | } \ 64 | {Echo a string back} { 65 | 66 | return [list SimpleEchoResult $TestString] 67 | } 68 | 69 | 70 | ::WS::Server::ServiceProc \ 71 | wsEchoExample \ 72 | {ComplexEcho {type echoReply comment {Requested Echo -- text and timestamp}}} \ 73 | { 74 | TestString {type string comment {The text to echo back}} 75 | } \ 76 | {Echo a string and a timestamp back} { 77 | 78 | set timeStamp [clock format [clock seconds] -format {%Y-%m-%dT%H:%M:%SZ} -gmt yes] 79 | return [list ComplexEchoResult [list echoBack $TestString echoTS $timeStamp] ] 80 | } 81 | -------------------------------------------------------------------------------- /Examples/Echo/EchoWibbleService.tcl: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## ## 3 | ## Copyright (c) 2006, Visiprise Software, Inc ## 4 | ## All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions ## 8 | ## are met: ## 9 | ## ## 10 | ## * Redistributions of source code must retain the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer. ## 12 | ## * Redistributions in binary form must reproduce the above ## 13 | ## copyright notice, this list of conditions and the following ## 14 | ## disclaimer in the documentation and/or other materials provided ## 15 | ## with the distribution. ## 16 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 17 | ## of its contributors may be used to endorse or promote products ## 18 | ## derived from this software without specific prior written ## 19 | ## permission. ## 20 | ## ## 21 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 22 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 23 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 24 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 25 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 26 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 27 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 29 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 30 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 31 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 32 | ## POSSIBILITY OF SUCH DAMAGE. ## 33 | ## ## 34 | ############################################################################### 35 | 36 | package require WS::Server 37 | package require WS::Utils 38 | 39 | ## 40 | ## Define the service 41 | ## 42 | ::WS::Server::Service \ 43 | -service wsEchoExample \ 44 | -description {Echo Example - Tcl Web Services} \ 45 | -mode wibble \ 46 | -host $::Config(host):$::Config(port) 47 | 48 | ## 49 | ## Define any special types 50 | ## 51 | ::WS::Utils::ServiceTypeDef Server wsEchoExample echoReply { 52 | echoBack {type string} 53 | echoTS {type dateTime} 54 | } 55 | 56 | ## 57 | ## Define the operations available 58 | ## 59 | ::WS::Server::ServiceProc \ 60 | wsEchoExample \ 61 | {SimpleEcho {type string comment {Requested Echo}}} \ 62 | { 63 | TestString {type string comment {The text to echo back}} 64 | } \ 65 | {Echo a string back} { 66 | 67 | return [list SimpleEchoResult $TestString] 68 | } 69 | 70 | 71 | ::WS::Server::ServiceProc \ 72 | wsEchoExample \ 73 | {ComplexEcho {type echoReply comment {Requested Echo -- text and timestamp}}} \ 74 | { 75 | TestString {type string comment {The text to echo back}} 76 | } \ 77 | {Echo a string and a timestamp back} { 78 | 79 | set timeStamp [clock format [clock seconds] -format {%Y-%m-%dT%H:%M:%SZ} -gmt yes] 80 | return [list ComplexEchoResult [list echoBack $TestString echoTS $timeStamp] ] 81 | } 82 | -------------------------------------------------------------------------------- /Examples/tclhttpd/htdocs/index.tml: -------------------------------------------------------------------------------- 1 | [html::description "TclHttpd, the Tcl Web Server, is an extensible 2 | platform for web application development."] 3 | [html::keywords Tcl TclHttpd Tcl/Tk "Tcl Web Server" "Web Server"] 4 | [html::author "Brent Welch"] 5 | [mypage::header "TclHttpd Home Page"] 6 | [Doc_Dynamic] 7 | 8 | 9 | 10 | 111 | 112 |
    11 | 12 | 13 | [clock format [clock seconds] -format "%B %d, %Y %H:%M:%S"] 14 | 15 | [if {[Url_PrefixExists /tclpro]} { 16 | set _ " 17 | 18 | 19 |
    TclPro Documentation
    " 20 | }] 21 |

    22 | The TclHttpd is a pure Tcl implementation of a Web server. 23 | It runs as a Tcl script on top of 24 | Tcl. 25 | This server is running Tcl $tcl_patchLevel. 26 | There is more TclHttpd version information 27 | about using other versions of Tcl and the Standard Tcl Library (tcllib). 28 |

    29 | 30 | While this server works fine as a stand alone web server, the 31 | intent is to embed the server in other applications in order to 32 | "web enable" them. 33 | A Tcl-based web server is ideal for embedding 34 | because Tcl was designed from the start 35 | to support embedding into other applications. 36 | The interpreted nature of Tcl allows dynamic reconfiguration of the 37 | server. Once the core interface between the web server and the hosting 38 | application is defined, it is possible to manage the web server, upload 39 | Safe-Tcl control scripts, download logging information, and otherwise 40 | debug the Tcl part of the application without restarting the hosting 41 | application. 42 |

    43 | [html::if {[file exists [file join $Doc(root) license.terms]]} { 44 | The server is distributed under a copyright that allows free use. 45 | }] 46 | 47 |

    48 | The tclhttpd-users@lists.sourceforge.net mailing list is the best source of current 49 | information about TclHttpd. 50 | 51 | 55 | 56 |

    Related Articles

    57 | 58 | [mypage::README_links] 59 | 60 | The main TclHttpd Information Page. 61 |

    62 | A Tcl Httpd Book Chapter from the 63 | 3rd Edition of 64 | Practical Programming in Tcl and Tk 65 | by Brent Welch. 66 |

    67 | The white 68 | paper presents a case for an embedded web server from more of a 69 | business angle. 70 | 71 | 72 |

    73 | 74 | 75 |

    Control/Status Pages

    76 | 81 |

    Documentation

    82 | 96 | 97 |

    Test Pages

    98 | 108 | 109 | 110 |
    113 | 114 | 115 | [mypage::footer] 116 | -------------------------------------------------------------------------------- /docs/Tcl_Web_Service_Math_Example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tcl Web Service Math Example 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |

    Tcl Web Service Math Example

    12 | 13 | 14 |

    Server Side

    15 | 16 |

    17 | The following is placed in the httpdthread.tcl: 18 |

    19 | 20 |
     21 |    package require WS::Server
     22 |    package require WS::Utils
     23 | 
    24 | 25 |

    26 | The following is placed in the a file in the custom directory: 27 |

    28 | 29 |
     30 |     ##
     31 |     ## Define the service
     32 |     ##
     33 |     ::WS::Server::Service \
     34 |         -service wsMathExample \
     35 |         -description  {Tcl Web Services Math Example} \
     36 |         -host         $::Config(host):$::Config(port)
     37 | 
     38 |     ##
     39 |     ## Define any special types
     40 |     ##
     41 |     ::WS::Utils::ServiceTypeDef Server wsMathExample Term {
     42 |        `coef         {type float}
     43 |         powerTerms   {type PowerTerm()}
     44 |     }
     45 |     ::WS::Utils::ServiceTypeDef Server wsMathExample PowerTerm {
     46 |         var          {type string}
     47 |         exponet      {type float}
     48 |     }
     49 |     ::WS::Utils::ServiceTypeDef Server wsMathExample Variables {
     50 |         var          {type string}
     51 |         value        {type float}
     52 |     }
     53 | 
     54 |    ##
     55 |    ## Define the operations available
     56 |    ##
     57 |    ::WS::Server::ServiceProc \
     58 |         wsMathExample \
     59 |         {EvaluatePolynomial {type float comment {Result of evaluating a polynomial}}} \
     60 |         {
     61 |             varList       {type Variables() comment {The variables to be substitued into the polynomial}}
     62 |             polynomial    {type Term() comment {The polynomial}}
     63 |         } \
     64 |         {Evaluate a polynomial} {
     65 |         set equation {0 }
     66 |         foreach varDict $varList {
     67 |             set var [dict get $varDict var]
     68 |             set val [dict get $varDict value]
     69 |             set vars($var) $val
     70 |         }
     71 |         foreach term $polynomial {
     72 |             if {[dict exists $term coef]} {
     73 |                 set coef [dict get $term coef]
     74 |             } else {
     75 |                 set coef 1
     76 |             }
     77 |             append equation "+ ($coef"
     78 |             foreach pow [dict get $term powerTerms] {
     79 |                 if {[dict exists $pow exponet]} {
     80 |                     set exp [dict get $pow exponet]
     81 |                 } else {
     82 |                     set exp 1
     83 |                 }
     84 |                 append equation [format { * pow($vars(%s),%s} [dict get $pow var] $exp]
     85 |             }
     86 |             append equation ")"
     87 |         }
     88 |         set result [expr $equation]
     89 |         return [list SimpleEchoResult $result]
     90 |     }
     91 | 
    92 |


    93 | 94 | 95 |

    Client Side

    96 |
     97 |     package require WS::Client
     98 |     ##
     99 |     ## Get Definition of the offered services
    100 |     ##
    101 |     ::WS::Client::GetAndParseWsdl http://localhost:8015/service/wsMathExamples/wsdl
    102 | 
    103 |     dict set term var X
    104 |     dict set term value 2.0
    105 |     dict lappend varList $term
    106 |     dict set term var Y
    107 |     dict set term value 3.0
    108 |     dict lappend varList $term
    109 | 
    110 |     set term {}
    111 |     set powerTerm {}
    112 |     dict set powerTerm coef 2.0
    113 |     dict set term var X
    114 |     dict set term pow 2.0
    115 |     dict lappend terms $term
    116 |     dict set term var Y
    117 |     dict set term pow 3.0
    118 |     dict lappend terms $term
    119 |     dict set powerTerm powerTerms $terms
    120 | 
    121 |     dict set powerTerm coef -2.0
    122 |     dict set term var X
    123 |     dict set term pow 3.0
    124 |     dict lappend terms $term
    125 |     dict set term var Y
    126 |     dict set term pow 2.0
    127 |     dict lappend terms $term
    128 |     dict set powerTerm powerTerms $terms
    129 |     dict lappend polynomial powerTerms $powerTerm
    130 | 
    131 |     dict set input [list varList $varList polynomial $polynomial]
    132 |     ##
    133 |     ## Call service
    134 |     ##
    135 |     puts stdout "Calling EvaluatePolynomial wiht {$input}"
    136 |     set resultsDict [::WS::Client::DoCall wsMathExample EvaluatePolynomial $input]
    137 |     puts stdout "Results are {$resultsDict}"
    138 | 
    139 |


    140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /Examples/tclhttpd/custom/faq.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Faq generation tool 3 | # (for use in .tml->.html files) 4 | # 5 | # Laurent Demailly 6 | # 7 | # SCCS: @(#) faq.tcl 1.5 97/12/23 21:13:33 8 | # 9 | 10 | package provide faq 1.2 11 | 12 | global FAQ 13 | 14 | proc FAQinit {{title ""}} { 15 | global FAQ 16 | if {[info exists FAQ]} { 17 | unset FAQ 18 | } 19 | set FAQ(section) 0 20 | set FAQ(question) 0 21 | set FAQ(currentSection) S0 22 | set FAQ(sections) [list S0] 23 | set result {} 24 | if {[string length $title]} { 25 | append result [FAQ_H1 $title] 26 | } 27 | append result "\n" 28 | return $result 29 | } 30 | 31 | proc FAQsection {section {ref ""}} { 32 | global FAQ 33 | if {$FAQ(section) == 0} { 34 | # Reset the section list, we have a FAQ with actual sections: 35 | set FAQ(sections) {} 36 | } 37 | incr FAQ(section) 38 | set label $FAQ(section) 39 | if {[string compare $ref ""] == 0} { 40 | set ref "S$label" 41 | } 42 | if {[info exists FAQ(label$ref)]} { 43 | error "ref \"$ref\" not unique!" 44 | } 45 | lappend FAQ(sections) $ref $section 46 | set FAQ(currentSection) $ref 47 | set FAQ($ref) {} 48 | set FAQ(label$ref) $label 49 | set FAQ(question) 0 50 | return $ref 51 | } 52 | 53 | proc FAQ {question answer {ref ""}} { 54 | global FAQ 55 | set sectionRef $FAQ(currentSection) 56 | incr FAQ(question) 57 | if {$FAQ(section)} { 58 | set label "$FAQ(section).$FAQ(question)" 59 | } else { 60 | set label "$FAQ(question)" 61 | } 62 | if {[string compare $ref ""] == 0} { 63 | set ref "Q$label" 64 | } 65 | if {[info exists FAQ(label$ref)]} { 66 | error "ref \"$ref\" not unique!" 67 | } 68 | lappend FAQ($sectionRef) $ref $question $answer 69 | set FAQ(label$ref) $label 70 | return $ref 71 | } 72 | 73 | proc FAQlink {ref {label ""}} { 74 | global FAQ 75 | if {[string compare $label ""] == 0} { 76 | set label %%FAQ$ref%% 77 | } 78 | return "$label" 79 | } 80 | 81 | # Quotes chars that are special to regsub : To be implemented 82 | proc FAQregQuote {str} { 83 | return $str 84 | } 85 | 86 | proc FAQlinkResolve {text} { 87 | global FAQ 88 | while {[regexp {%%FAQ(.+)%%} $text all ref]} { 89 | regsub "%%FAQ[FAQregQuote $ref]%%" $text [FAQregQuote $FAQ(label$ref)] text 90 | } 91 | return $text 92 | } 93 | 94 | proc FAQgenSec {ref section} { 95 | global FAQ page 96 | set result {} 97 | if {[info exists page(opendl)]} { 98 | append result "\n" 99 | } 100 | append result [FAQ_H2 "$FAQ(label$ref). $section"] 101 | append result "
    \n" 102 | set page(opendl) 1 103 | return $result 104 | } 105 | 106 | proc FAQgenQ {ref question answer} { 107 | global FAQ 108 | set result {} 109 | append result "

    $FAQ(label$ref). $question\n" 110 | append result "
    [FAQlinkResolve $answer]\n" 111 | return $result 112 | } 113 | proc FAQgen {} { 114 | global FAQ page 115 | set result {} 116 | 117 | set hasSections $FAQ(section) 118 | # Table of content 119 | append result [FAQ_H2 "FAQ Index"] 120 | append result "\n" 121 | foreach {secRef section} $FAQ(sections) { 122 | if {$hasSections} { 123 | append result "
  • $FAQ(label$secRef).\ 124 | $section\n" 125 | append result "\n" 126 | } 127 | foreach {qref question answer} $FAQ($secRef) { 128 | append result "
  • $FAQ(label$qref).\ 129 | $question\n" 130 | } 131 | if {$hasSections} { 132 | append result "
  • \n" 133 | } 134 | } 135 | append result "
  • " 136 | 137 | # Actual content 138 | foreach {secRef section} $FAQ(sections) { 139 | if {$hasSections} { 140 | append result [FAQgenSec $secRef $section] 141 | } else { 142 | append result [FAQ_H2 "Questions and Answers"] 143 | append result "
    \n" 144 | set page(opendl) 1 145 | } 146 | foreach {qref question answer} $FAQ($secRef) { 147 | append result [FAQgenQ $qref $question $answer] 148 | } 149 | } 150 | if {[info exists page(opendl)]} { 151 | append result "
    \n" 152 | } 153 | return $result 154 | } 155 | 156 | proc FAQ_H1 {title} { 157 | return "

    $title

    \n" 158 | } 159 | 160 | proc FAQ_H2 {title} { 161 | return "

    $title

    \n" 162 | } 163 | -------------------------------------------------------------------------------- /docs/Tcl_Web_Service_Example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tcl Web Service Example 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |

    Tcl Web Service Example

    12 | 13 | 14 |

    Server Side

    15 | 16 |

    17 | The following is placed in the httpdthread.tcl: 18 |

    19 | 20 |
       package require WS::Server
     21 |    package require WS::Utils
     22 | 
    23 | 24 |

    25 | The following is placed in the a file in the custom directory: 26 |

    27 | 28 |
     29 |    ##
     30 |    ## Define the service
     31 |    ##
     32 |    ::WS::Server::Service \
     33 |        -service wsExamples \
     34 |        -description  {Tcl Example Web Services} \
     35 |        -host         $::Config(host):$::Config(port)
     36 | 
       ##
     37 |    ## Define any special types
     38 |    ##
     39 |    ::WS::Utils::ServiceTypeDef Server wsExamples echoReply {
     40 |        echoBack     {type string}
     41 |        echoTS       {type dateTime}
     42 |    }
     43 | 
       ##
     44 |    ## Define the operations available
     45 |    ##
     46 |    ::WS::Server::ServiceProc \
     47 |        wsExamples \
     48 |        {SimpleEcho {type string comment {Requested Echo}}} \
     49 |        {
     50 |            TestString      {type string comment {The text to echo back}}
     51 |        } \
     52 |        {Echo a string back} {
     53 | 
           return [list SimpleEchoResult $TestString]
     54 |    }
     55 | 
    56 |


       ::WS::Server::ServiceProc \
     57 |        wsExamples \
     58 |        {ComplexEcho {type echoReply comment {Requested Echo -- text and timestamp}}} \
     59 |        {
     60 |            TestString      {type string comment {The text to echo back}}
     61 |        } \
     62 |        {Echo a string and a timestamp back} {
     63 | 
           set timeStamp [clock format [clock seconds] -format {%Y-%m-%dT%H:%M:%SZ} -gmt yes]
     64 |        return [list ComplexEchoResult [list echoBack $TestString echoTS $timeStamp]  ]
     65 |    }
     66 | 
    67 |


    68 | 69 | 70 |

    Client Side

       package require WS::Client
     71 | 
       ##
     72 |    ## Get Definition of the offered services
     73 |    ##
     74 |    ::WS::Client::GetAndParseWsdl http://localhost:8015/service/wsExamples/wsdl
     75 | 
       set testString "This is a test"
     76 |    set inputs [list TestString $testString]
     77 | 
       ##
     78 |    ## Call synchronously
     79 |    ##
     80 |    puts stdout "Calling SimpleEcho via DoCalls!"
     81 |    set results [::WS::Client::DoCall wsExamples SimpleEcho $inputs]
     82 |    puts stdout "\t Received: {$results}"
     83 | 
       puts stdout "Calling ComplexEcho via DoCalls!"
     84 |    set results [::WS::Client::DoCall wsExamples ComplexEcho $inputs]
     85 |    puts stdout "\t Received: {$results}"
     86 | 
    87 |


       ##
     88 |    ## Generate stubs and use them for the calls
     89 |    ##
     90 |    ::WS::Client::CreateStubs wsExamples
     91 |    puts stdout "Calling SimpleEcho via Stubs!"
     92 |    set results [::wsExamples::SimpleEcho $testString]
     93 |    puts stdout "\t Received: {$results}"
     94 | 
       puts stdout "Calling ComplexEcho via Stubs!"
     95 |    set results [::wsExamples::ComplexEcho $testString]
     96 |    puts stdout "\t Received: {$results}"
     97 | 
       ##
     98 |    ## Call asynchronously
     99 |    ##
    100 |    proc success {service operation result} {
    101 |        global waitVar
    102 | 
           puts stdout "A call to $operation of $service was successful and returned $result"
    103 |        set waitVar 1
    104 |    }
    105 | 
       proc hadError {service operation errorCode errorInfo} {
    106 |        global waitVar
    107 | 
           puts stdout "A call to $operation of $service was failed with {$errorCode} {$errorInfo}"
    108 |        set waitVar 1
    109 |    }
    110 | 
       set waitVar 0
    111 |    puts stdout "Calling SimpleEcho via DoAsyncCall!"
    112 |    ::WS::Client::DoAsyncCall wsExamples SimpleEcho $inputs \
    113 |            [list success wsExamples SimpleEcho] \
    114 |            [list hadError wsExamples SimpleEcho]
    115 |    vwait waitVar
    116 | 
       puts stdout "Calling ComplexEcho via DoAsyncCall!"
    117 |    ::WS::Client::DoAsyncCall wsExamples ComplexEcho $inputs \
    118 |            [list success wsExamples SimpleEcho] \
    119 |            [list hadError wsExamples SimpleEcho]
    120 |    vwait waitVar
    121 | 
       exit
    122 | 
    123 |


    124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /Examples/Echo/EchoEmbeddedService.tcl: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## ## 3 | ## Copyright (c) 2006, Visiprise Software, Inc ## 4 | ## All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions ## 8 | ## are met: ## 9 | ## ## 10 | ## * Redistributions of source code must retain the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer. ## 12 | ## * Redistributions in binary form must reproduce the above ## 13 | ## copyright notice, this list of conditions and the following ## 14 | ## disclaimer in the documentation and/or other materials provided ## 15 | ## with the distribution. ## 16 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 17 | ## of its contributors may be used to endorse or promote products ## 18 | ## derived from this software without specific prior written ## 19 | ## permission. ## 20 | ## ## 21 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 22 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 23 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 24 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 25 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 26 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 27 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 29 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 30 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 31 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 32 | ## POSSIBILITY OF SUCH DAMAGE. ## 33 | ## ## 34 | ############################################################################### 35 | 36 | set auto_path [linsert $auto_path 0 [file join [file dirname [info script]] ../..]] 37 | package require WS::Server 38 | package require WS::Utils 39 | package require WS::Embeded 40 | catch {console show} 41 | 42 | ## 43 | ## Define the service 44 | ## 45 | ::WS::Server::Service \ 46 | -service wsEchoExample \ 47 | -description {Echo Example - Tcl Web Services} \ 48 | -host localhost:8015 \ 49 | -mode embedded \ 50 | -ports [list 8015] 51 | 52 | ## 53 | ## Define any special types 54 | ## 55 | ::WS::Utils::ServiceTypeDef Server wsEchoExample echoReply { 56 | echoBack {type string} 57 | echoTS {type dateTime} 58 | } 59 | 60 | ## 61 | ## Define the operations available 62 | ## 63 | ::WS::Server::ServiceProc \ 64 | wsEchoExample \ 65 | {SimpleEcho {type string comment {Requested Echo}}} \ 66 | { 67 | TestString {type string comment {The text to echo back}} 68 | } \ 69 | {Echo a string back} { 70 | ::log::lvSuppressLE debug 0 71 | return [list SimpleEchoResult $TestString] 72 | } 73 | 74 | 75 | ::WS::Server::ServiceProc \ 76 | wsEchoExample \ 77 | {ComplexEcho {type echoReply comment {Requested Echo -- text and timestamp}}} \ 78 | { 79 | TestString {type string comment {The text to echo back}} 80 | } \ 81 | {Echo a string and a timestamp back} { 82 | 83 | set timeStamp [clock format [clock seconds] -format {%Y-%m-%dT%H:%M:%SZ} -gmt yes] 84 | return [list ComplexEchoResult [list echoBack $TestString echoTS $timeStamp] ] 85 | } 86 | 87 | set ::errorInfo {} 88 | set SocketHandle [::WS::Embeded::Listen 8015] 89 | set ::errorInfo {} 90 | 91 | proc x {} { 92 | close $::SocketHandle 93 | exit 94 | } 95 | 96 | puts stdout {Server started. Press x and Enter to stop} 97 | flush stdout 98 | fileevent stdin readable {set QuitNow 1} 99 | vwait QuitNow 100 | x 101 | -------------------------------------------------------------------------------- /Examples/Echo/CallEchoWebService.tcl: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## ## 3 | ## Copyright (c) 2006, Visiprise Software, Inc ## 4 | ## All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions ## 8 | ## are met: ## 9 | ## ## 10 | ## * Redistributions of source code must retain the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer. ## 12 | ## * Redistributions in binary form must reproduce the above ## 13 | ## copyright notice, this list of conditions and the following ## 14 | ## disclaimer in the documentation and/or other materials provided ## 15 | ## with the distribution. ## 16 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 17 | ## of its contributors may be used to endorse or promote products ## 18 | ## derived from this software without specific prior written ## 19 | ## permission. ## 20 | ## ## 21 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 22 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 23 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 24 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 25 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 26 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 27 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 29 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 30 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 31 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 32 | ## POSSIBILITY OF SUCH DAMAGE. ## 33 | ## ## 34 | ############################################################################### 35 | 36 | set auto_path [linsert $auto_path 0 [file join [file dirname [info script]] ../..]] 37 | package require WS::Utils 38 | package require WS::Client 39 | 40 | ## 41 | ## Get Definition of the offered services 42 | ## 43 | ::WS::Client::GetAndParseWsdl http://localhost:8015/service/wsEchoExample/wsdl 44 | 45 | set testString "This is a test" 46 | set inputs [list TestString $testString] 47 | 48 | ## 49 | ## Call synchronously 50 | ## 51 | puts stdout "Calling SimpleEcho via DoCalls!" 52 | set results [::WS::Client::DoCall wsEchoExample SimpleEcho $inputs] 53 | puts stdout "\t Received: {$results}" 54 | 55 | puts stdout "Calling ComplexEcho via DoCalls!" 56 | set results [::WS::Client::DoCall wsEchoExample ComplexEcho $inputs] 57 | puts stdout "\t Received: {$results}" 58 | 59 | 60 | ## 61 | ## Generate stubs and use them for the calls 62 | ## 63 | ::WS::Client::CreateStubs wsEchoExample 64 | puts stdout "Calling SimpleEcho via Stubs!" 65 | set results [::wsEchoExample::SimpleEcho $testString] 66 | puts stdout "\t Received: {$results}" 67 | 68 | puts stdout "Calling ComplexEcho via Stubs!" 69 | set results [::wsEchoExample::ComplexEcho $testString] 70 | puts stdout "\t Received: {$results}" 71 | 72 | ## 73 | ## Call asynchronously 74 | ## 75 | proc success {service operation result} { 76 | global waitVar 77 | 78 | puts stdout "A call to $operation of $service was successful and returned $result" 79 | set waitVar 1 80 | } 81 | 82 | proc hadError {service operation errorCode errorInfo} { 83 | global waitVar 84 | 85 | puts stdout "A call to $operation of $service was failed with {$errorCode} {$errorInfo}" 86 | set waitVar 1 87 | } 88 | 89 | set waitVar 0 90 | puts stdout "Calling SimpleEcho via DoAsyncCall!" 91 | ::WS::Client::DoAsyncCall wsEchoExample SimpleEcho $inputs \ 92 | [list success wsEchoExample SimpleEcho] \ 93 | [list hadError wsEchoExample SimpleEcho] 94 | vwait waitVar 95 | 96 | puts stdout "Calling ComplexEcho via DoAsyncCall!" 97 | ::WS::Client::DoAsyncCall wsEchoExample ComplexEcho $inputs \ 98 | [list success wsEchoExample SimpleEcho] \ 99 | [list hadError wsEchoExample SimpleEcho] 100 | vwait waitVar 101 | 102 | exit 103 | -------------------------------------------------------------------------------- /Examples/Math/CallMathWebService.tcl: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## ## 3 | ## Copyright (c) 2006, Visiprise Software, Inc ## 4 | ## All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions ## 8 | ## are met: ## 9 | ## ## 10 | ## * Redistributions of source code must retain the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer. ## 12 | ## * Redistributions in binary form must reproduce the above ## 13 | ## copyright notice, this list of conditions and the following ## 14 | ## disclaimer in the documentation and/or other materials provided ## 15 | ## with the distribution. ## 16 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 17 | ## of its contributors may be used to endorse or promote products ## 18 | ## derived from this software without specific prior written ## 19 | ## permission. ## 20 | ## ## 21 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 22 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 23 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 24 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 25 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 26 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 27 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 29 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 30 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 31 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 32 | ## POSSIBILITY OF SUCH DAMAGE. ## 33 | ## ## 34 | ############################################################################### 35 | 36 | package require WS::Client 37 | 38 | ## 39 | ## Get Definition of the offered services 40 | ## 41 | ::WS::Client::GetAndParseWsdl http://localhost:8015/service/wsMathExample/wsdl 42 | 43 | ## 44 | ## Add two numbers 45 | ## 46 | puts stdout "Calling Add via DoCalls!" 47 | set inputs [list N1 12 N2 34] 48 | set results [::WS::Client::DoCall wsMathExample Add $inputs] 49 | puts stdout "\t Received: {$results}" 50 | 51 | ## 52 | ## Divide two numbers 53 | ## 54 | puts stdout "Calling Divide via DoCalls!" 55 | set inputs [list Dividend 34 Divisor 12] 56 | set results [::WS::Client::DoCall wsMathExample Divide $inputs] 57 | puts stdout "\t Received: {$results}" 58 | 59 | ## 60 | ## Multiply two numbers 61 | ## 62 | puts stdout "Calling Multiply via DoCalls!" 63 | set inputs [list N1 12.0 N2 34] 64 | set results [::WS::Client::DoCall wsMathExample Multiply $inputs] 65 | puts stdout "\t Received: {$results}" 66 | 67 | ## 68 | ## Subtract two numbers 69 | ## 70 | puts stdout "Calling Subtract via DoCalls!" 71 | set inputs [list Subtrahend 12 Minuend 34] 72 | set results [::WS::Client::DoCall wsMathExample Subtract $inputs] 73 | puts stdout "\t Received: {$results}" 74 | 75 | ## 76 | ## Sqrt a number 77 | ## 78 | puts stdout "Calling Sqrt via DoCalls!" 79 | set inputs [list X 12] 80 | set results [::WS::Client::DoCall wsMathExample Sqrt $inputs] 81 | puts stdout "\t Received: {$results}" 82 | 83 | 84 | 85 | ## 86 | ## Set up to evaluate a polynomial 87 | ## 88 | dict set term var X 89 | dict set term value 2.0 90 | dict lappend varList $term 91 | dict set term var Y 92 | dict set term value 3.0 93 | dict lappend varList $term 94 | 95 | 96 | set term {} 97 | set powerTerm {} 98 | dict set powerTerm coef 2.0 99 | dict set term var X 100 | dict set term pow 2.0 101 | dict lappend terms $term 102 | dict set term var Y 103 | dict set term pow 3.0 104 | dict lappend terms $term 105 | dict set powerTerm powerTerms $terms 106 | 107 | 108 | dict set powerTerm coef -2.0 109 | dict set term var X 110 | dict set term pow 3.0 111 | dict lappend terms $term 112 | dict set term var Y 113 | dict set term pow 2.0 114 | dict lappend terms $term 115 | dict set powerTerm powerTerms $terms 116 | dict lappend polynomial powerTerms $powerTerm 117 | 118 | 119 | dict set input varList $varList 120 | dict set input polynomial $polynomial 121 | ## 122 | ## Call service 123 | ## 124 | puts stdout "Calling EvaluatePolynomial with {$input}" 125 | set resultsDict [::WS::Client::DoCall wsMathExample EvaluatePolynomial $input] 126 | puts stdout "Results are {$resultsDict}" 127 | -------------------------------------------------------------------------------- /docs/Embedded_Web_Service.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Embeding a Web Service 4 | 5 | 6 | 7 | 8 | 9 |

    Embeding a Web Service

    10 | 11 | 12 | 13 | 30 | 31 |
    14 |
    15 |

    Contents

    16 | 29 |
    32 | 33 | 34 |

    Loading the Webservices Server Package

    35 | 36 |

    To load the webservices server package, do:

     package require WS::Embeded
     37 | 
    38 |

    This command will only load the server the first time it is used, so it 39 | causes no ill effects to put this in each file declaring a service or service 40 | procedure.

    41 | 42 |
    43 | 44 | 45 |

    Specify a Port to Receive Request on

    46 | 47 |

    The following command opens a listener socket in the specified port. 48 | The webservice functionality may be added by a call to ::WS::Server::Service with the -mode parameter set to embedded. 49 | 50 |

    Procedure Name : ::WS::Embeded::Listen

    51 |

    Description : Instruct the module to listen on a Port, security information. 52 |

    Arguments : this procedure uses position dependent arguments, 53 | they are:

    54 |
     55 |      port     -- Port number to listen on.
     56 |      certfile -- Name of the certificate file or a pfx archive for twapi.
     57 |                  Defaults to {}.
     58 |      keyfile  -- Name of the key file. Defaults to {}.
     59 |                  To use twapi TLS, specify a list with the following elements:
     60 |                  -- "-twapi": Flag, that TWAPI TLS should be used
     61 |                  -- password: password of PFX file passed by
     62 |                     [::twapi::conceal]. The concealing makes sure that the
     63 |                     password is not readable in the error stack trace
     64 |                  -- ?subject?: optional search string in pfx file, if
     65 |                     multiple certificates are included.
     66 |      userpwds -- A list of username:password. Defaults to {}.
     67 |      realm    -- The seucrity realm. Defaults to {}.
     68 |      timeout  -- A time in ms the sender may use to send the request.
     69 |                  If a sender sends wrong data (Example: TLS if no TLS is
     70 |                  used), the process will just stand and a timeout is required
     71 |                  to clear the connection. Set to 0 to not use a timeout.
     72 |                  Default: 60000 (1 Minuit).
     73 | 
    74 |

    Returns : Handle of socket

    75 |

    Side-Effects : None

    76 |

    Exception Conditions :  : None

    77 |

    Pre-requisite Conditions : None

    78 |
    79 | 80 | 81 |

    Run the event queue

    82 | 83 |

    To serve any requests, the interpreter must run the event queue using. 84 | If this is not anyway the case (Tk present etc.), one may call:

    85 |
     86 |      vwait waitVariable
     87 | 
    88 | 89 |

    To stop the event queue after server shutdown, one may execute:

    90 |
     91 |      set waitVariable 1
     92 | 
    93 |
    94 | 95 | 96 |

    Close a port

    97 | 98 |

    Procedure Name : ::WS::Embeded::Close

    99 |

    Description : Close a formerly opened listener port and stop all running requests on this port. 100 |

    Arguments : this procedure uses position dependent arguments, 101 | they are:

    102 |
    103 |      port     -- Port number to close.
    104 | 
    105 |

    Returns : None

    106 |

    Side-Effects : None

    107 |

    Exception Conditions :  : None

    108 |

    Pre-requisite Conditions : None

    109 |
    110 | 111 | 112 |

    Close all ports

    113 | 114 |

    Procedure Name : ::WS::Embeded::CloseAll

    115 |

    Description : Close all formerly opened listener port and stop all running requests. 116 |

    Arguments : this procedure uses no arguments

    117 |

    Returns : None

    118 |

    Side-Effects : None

    119 |

    Exception Conditions :  : None

    120 |

    Pre-requisite Conditions : None

    121 | 122 | 123 | -------------------------------------------------------------------------------- /Examples/tclhttpd/custom/MathWebService.tcl: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## ## 3 | ## Copyright (c) 2006, Visiprise Software, Inc ## 4 | ## All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions ## 8 | ## are met: ## 9 | ## ## 10 | ## * Redistributions of source code must retain the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer. ## 12 | ## * Redistributions in binary form must reproduce the above ## 13 | ## copyright notice, this list of conditions and the following ## 14 | ## disclaimer in the documentation and/or other materials provided ## 15 | ## with the distribution. ## 16 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 17 | ## of its contributors may be used to endorse or promote products ## 18 | ## derived from this software without specific prior written ## 19 | ## permission. ## 20 | ## ## 21 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 22 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 23 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 24 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 25 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 26 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 27 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 29 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 30 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 31 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 32 | ## POSSIBILITY OF SUCH DAMAGE. ## 33 | ## ## 34 | ############################################################################### 35 | 36 | package require WS::Server 37 | package require WS::Utils 38 | 39 | ## 40 | ## Define the service 41 | ## 42 | ::WS::Server::Service \ 43 | -service wsMathExample \ 44 | -description {Math Example - Tcl Web Services} \ 45 | -host $::Config(host):$::Config(port) 46 | 47 | ## 48 | ## Define the operations available 49 | ## 50 | ::WS::Server::ServiceProc \ 51 | wsMathExample \ 52 | {Add {type string comment {Sum of two number}}} \ 53 | { 54 | N1 {type double comment {First number to add}} 55 | N2 {type double comment {Second number to add}} 56 | } \ 57 | {Add two numbers} { 58 | 59 | return [list AddResult [expr {$N1 + $N2}]] 60 | } 61 | 62 | ::WS::Server::ServiceProc \ 63 | wsMathExample \ 64 | {Subtract {type string comment {Difference of two number}}} \ 65 | { 66 | Minuend {type double comment {Number to subtrack from}} 67 | Subtrahend {type double comment {Number to be subtracked}} 68 | } \ 69 | {Subtract one number from another} { 70 | 71 | return [list SubtractResult [expr {$Minuend - $Subtrahend}]] 72 | } 73 | 74 | ::WS::Server::ServiceProc \ 75 | wsMathExample \ 76 | {Multiply {type string comment {Product of two number}}} \ 77 | { 78 | N1 {type double comment {First number to multiply}} 79 | N2 {type double comment {Second number to multiply}} 80 | } \ 81 | {Multiply two numbers} { 82 | 83 | return [list MultiplyResult [expr {$N1 * $N2}]] 84 | } 85 | 86 | ::WS::Server::ServiceProc \ 87 | wsMathExample \ 88 | {Divide {type string comment {Quotient of two number}}} \ 89 | { 90 | Dividend {type double comment {Number that is being divided}} 91 | Divisor {type double comment {Number dividing}} 92 | } \ 93 | {Divide one number by another} { 94 | 95 | if {$Divisor == 0.0} { 96 | return \ 97 | -code error \ 98 | -errorcode [list MATH DIVBYZERO] \ 99 | "Can not divide by zero" 100 | } 101 | 102 | return [list DivideResult [expr {$Dividend + $Divisor}]] 103 | } 104 | 105 | ::WS::Server::ServiceProc \ 106 | wsMathExample \ 107 | {Sqrt {type string comment {Square root of a non-negative number}}} \ 108 | { 109 | X {type double comment {Number raised to the half power}} 110 | } \ 111 | {The the square root of a number} { 112 | 113 | if {$X < 0.0} { 114 | return \ 115 | -code error \ 116 | -errorcode [list MATH RANGERR] \ 117 | "Can not take the square root of a negative number, $X" 118 | } 119 | 120 | return [list SqrtResult [expr {sqrt($X)}]] 121 | } 122 | 123 | -------------------------------------------------------------------------------- /Examples/aolserver/servers/tclws/pages/index.adp: -------------------------------------------------------------------------------- 1 | <% 2 | set uptime [ns_info uptime] 3 | 4 | if {$uptime < 60} { 5 | set uptime [format %.2d $uptime] 6 | } elseif {$uptime < 3600} { 7 | set mins [expr $uptime / 60] 8 | set secs [expr $uptime - ($mins * 60)] 9 | 10 | set uptime "[format %.2d $mins]:[format %.2d $secs]" 11 | } else { 12 | set hours [expr $uptime / 3600] 13 | set mins [expr ($uptime - ($hours * 3600)) / 60] 14 | set secs [expr $uptime - (($hours * 3600) + ($mins * 60))] 15 | 16 | set uptime "${hours}:[format %.2d $mins]:[format %.2d $secs]" 17 | } 18 | 19 | set config "" 20 | 21 | lappend config "Build Date" [ns_info builddate] 22 | lappend config "Build Label" [ns_info label] 23 | lappend config "Build Platform" [ns_info platform] 24 | lappend config "Build Version" [ns_info version] 25 | lappend config "Build Patch Level" [ns_info patchlevel] 26 | lappend config " " " " 27 | lappend config "Binary" [ns_info nsd] 28 | lappend config "Process ID" [ns_info pid] 29 | lappend config "Uptime" $uptime 30 | lappend config "Host Name" [ns_info hostname] 31 | lappend config "Address" [ns_info address] 32 | lappend config "Server Config" [ns_info config] 33 | lappend config "Server Log" [ns_info log] 34 | lappend config "Access Log" [ns_accesslog file] 35 | lappend config " " " " 36 | lappend config "Tcl Version" [info tclversion] 37 | lappend config "Tcl Patch Level" [info patchlevel] 38 | lappend config " " " " 39 | lappend config "Home Directory" [ns_info home] 40 | lappend config "Page Root" [ns_info pageroot] 41 | lappend config "Tcl Library" [ns_info tcllib] 42 | %> 43 | 44 | 46 | 47 | 48 | 49 | Welcome to AOLserver 50 | 112 | 113 | 114 | 115 | 125 | 126 |

    AOLserver <%=[ns_info version]%>

    127 | 128 |

    Congratulations, you have successfully installed AOLserver <%=[ns_info version]%>!

    129 | 130 |

    Configuration

    131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | <% 139 | foreach {key value} $config { 140 | ns_adp_puts "" 141 | } 142 | %> 143 | 144 |
    KeyValue
    $key$value
    145 | 146 |

    Loaded AOLserver Modules

    147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | <% 156 | set server [ns_info server] 157 | set modSection [ns_configsection ns/server/$server/modules] 158 | set tclDir [ns_info tcllib] 159 | set binDir "[ns_info home]/bin" 160 | 161 | foreach {name binary} [ns_set array $modSection] { 162 | if {[string match "tcl" $binary]} { 163 | set type "Tcl" 164 | set location "$tclDir/$name" 165 | } else { 166 | set type "C" 167 | set location "$binDir/$binary" 168 | } 169 | 170 | ns_adp_puts "" 171 | } 172 | %> 173 | 174 |
    TypeNameLocation
    $type$name$location
    175 | 176 | <% 177 | set modules [info loaded] 178 | 179 | if {[string length $modules]} { 180 | ns_adp_puts "\ 181 |

    Loaded Tcl Modules

    182 | 183 | 184 | 185 | 186 | 187 | " 188 | 189 | foreach module [info loaded] { 190 | foreach {binary name} $module { 191 | ns_adp_puts "" 192 | } 193 | } 194 | 195 | ns_adp_puts "
    NameLocation
    $name$binary
    " 196 | } 197 | %> 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /Examples/Math/MathWebService.tcl: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## ## 3 | ## Copyright (c) 2006, Visiprise Software, Inc ## 4 | ## All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions ## 8 | ## are met: ## 9 | ## ## 10 | ## * Redistributions of source code must retain the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer. ## 12 | ## * Redistributions in binary form must reproduce the above ## 13 | ## copyright notice, this list of conditions and the following ## 14 | ## disclaimer in the documentation and/or other materials provided ## 15 | ## with the distribution. ## 16 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 17 | ## of its contributors may be used to endorse or promote products ## 18 | ## derived from this software without specific prior written ## 19 | ## permission. ## 20 | ## ## 21 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 22 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 23 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 24 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 25 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 26 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 27 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 29 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 30 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 31 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 32 | ## POSSIBILITY OF SUCH DAMAGE. ## 33 | ## ## 34 | ############################################################################### 35 | 36 | package require WS::Server 37 | package require WS::Utils 38 | 39 | ## 40 | ## Define the service 41 | ## 42 | ::WS::Server::Service \ 43 | -service wsMathExample \ 44 | -description {Math Example - Tcl Web Services} \ 45 | -host $::Config(host):$::Config(port) 46 | 47 | 48 | ## 49 | ## Define any special types 50 | ## 51 | ::WS::Utils::ServiceTypeDef Server wsMathExample Term { 52 | `coef {type float} 53 | powerTerms {type PowerTerm()} 54 | } 55 | ::WS::Utils::ServiceTypeDef Server wsMathExample PowerTerm { 56 | var {type string} 57 | exponet {type float} 58 | } 59 | ::WS::Utils::ServiceTypeDef Server wsMathExample Variables { 60 | var {type string} 61 | value {type float} 62 | } 63 | 64 | 65 | ## 66 | ## Define the operations available 67 | ## 68 | ::WS::Server::ServiceProc \ 69 | wsMathExample \ 70 | {Add {type string comment {Sum of two number}}} \ 71 | { 72 | N1 {type double comment {First number to add}} 73 | N2 {type double comment {Second number to add}} 74 | } \ 75 | {Add two numbers} { 76 | 77 | return [list AddResult [expr {$N1 + $N2}]] 78 | } 79 | 80 | ::WS::Server::ServiceProc \ 81 | wsMathExample \ 82 | {Subtract {type string comment {Difference of two number}}} \ 83 | { 84 | Minuend {type double comment {Number to subtrack from}} 85 | Subtrahend {type double comment {Number to be subtracked}} 86 | } \ 87 | {Subtract one number from another} { 88 | 89 | return [list SubtractResult [expr {$Minuend - $Subtrahend}]] 90 | } 91 | 92 | ::WS::Server::ServiceProc \ 93 | wsMathExample \ 94 | {Multiply {type string comment {Product of two number}}} \ 95 | { 96 | N1 {type double comment {First number to multiply}} 97 | N2 {type double comment {Second number to multiply}} 98 | } \ 99 | {Multiply two numbers} { 100 | 101 | return [list MultiplyResult [expr {$N1 * $N2}]] 102 | } 103 | 104 | ::WS::Server::ServiceProc \ 105 | wsMathExample \ 106 | {Divide {type string comment {Quotient of two number}}} \ 107 | { 108 | Dividend {type double comment {Number that is being divided}} 109 | Divisor {type double comment {Number dividing}} 110 | } \ 111 | {Divide one number by another} { 112 | 113 | if {$Divisor == 0.0} { 114 | return \ 115 | -code error \ 116 | -errorcode [list MATH DIVBYZERO] \ 117 | "Can not divide by zero" 118 | } 119 | 120 | return [list DivideResult [expr {$Dividend / $Divisor}]] 121 | } 122 | 123 | ::WS::Server::ServiceProc \ 124 | wsMathExample \ 125 | {Sqrt {type string comment {Square root of a non-negative number}}} \ 126 | { 127 | X {type double comment {Number raised to the half power}} 128 | } \ 129 | {The the square root of a number} { 130 | 131 | if {$X < 0.0} { 132 | return \ 133 | -code error \ 134 | -errorcode [list MATH RANGERR] \ 135 | "Can not take the square root of a negative number, $X" 136 | } 137 | 138 | return [list SqrtResult [expr {sqrt($X)}]] 139 | } 140 | 141 | ## 142 | ## Define the operations available 143 | ## 144 | ::WS::Server::ServiceProc \ 145 | wsMathExample \ 146 | {EvaluatePolynomial {type float comment {Result of evaluating a polynomial}}} \ 147 | { 148 | varList {type Variables() comment {The variables to be substitued into the polynomial}} 149 | polynomial {type Term() comment {The polynomial}} 150 | } \ 151 | {Evaluate a polynomial} { 152 | set equation {0 } 153 | foreach varDict $varList { 154 | set var dict get $varDict var 155 | set val dict get $varDict value 156 | set vars($var) $val 157 | } 158 | foreach term $polynomial { 159 | if {dict exists $term coef} { 160 | set coef dict get $term coef 161 | } else { 162 | set coef 1 163 | } 164 | append equation "+ ($coef" 165 | foreach pow dict get $term powerTerms { 166 | if {dict exists $pow exponet} { 167 | set exp dict get $pow exponet 168 | } else { 169 | set exp 1 170 | } 171 | append equation format { * pow($vars(%s),%s} [dict get $pow var $exp] 172 | } 173 | append equation ")" 174 | } 175 | set result expr $equation 176 | return list SimpleEchoResult $result 177 | } 178 | 179 | -------------------------------------------------------------------------------- /docs/Defining_Types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Web Services for Tcl (aka tclws): Defining Types 5 | 6 | 7 | 8 | 9 | 10 |
    11 | 12 |

    Contents

    13 |
    23 |

    24 | 25 |

    26 | 27 |

    28 |

    Overview

    29 |

    Webservice Type declaration is part of the Webservices Utility package.

    30 |

    When writing a web service it is often requried to write a complex type 31 | definition for an argument containing structured data.

    32 |

    When calling an operation on a web service it is sometimes convient to define 33 | a complex type to return structured data as an XML fragment even though the 34 | sevice may state that it is only expecting a string.

    35 | 36 |

    37 |

    Loading the Webservices Utility Package

    38 |

    To load the webservices server package, do:

     package require WS::Utils
     39 | 
    40 |

    This command will only load the utilities the first time it is used, so it 41 | causes no ill effects to put this in each file using the utilties.

    42 |
    43 | 44 |

    45 |

    Defining a type

    46 |

    Procedure Name : ::WS::Utils::ServiceTypeDef

    47 |

    Description : Define a type for a service.

    48 |

    Arguments :

         mode            - Client or Server
     49 |      service         - The name of the service this type definition is for
     50 |      type            - The type to be defined/redefined
     51 |      definition      - The definition of the type's fields.  This consist of one
     52 |                            or more occurance of a field definition.  Each field definition
     53 |                            consist of:  fieldName fieldInfo
     54 |                            Where field info is: {type typeName comment commentString}
     55 |                               typeName can be any simple or defined type.
     56 |                               commentString is a quoted string describing the field.
     57 | 
    58 |

    Returns : Nothing

    59 |

    Side-Effects : None

    60 |

    Exception Conditions : None

    61 |

    Pre-requisite Conditions : None

    62 |
    63 | 64 |

    65 |

    Defining a derived type

    66 |

    Procedure Name : ::WS::Utils::ServiceSimpleTypeDef

    67 |

    Description : Define a derived type for a service.

    68 |

    Arguments :

         mode            - Client or Server
     69 |      service         - The name of the service this type definition is for
     70 |      type            - The type to be defined/redefined
     71 |      definition      - The definition of the type's fields.  This consist of one
     72 |                            or more occurance of a field definition.  Each field definition
     73 |                            consist of:  fieldName fieldInfo
     74 |                            Where: {type typeName comment commentString}
     75 |                               baseType typeName - any simple or defined type.
     76 |                               comment commentString - a quoted string describing the field.
     77 |                               pattern value
     78 |                               length value
     79 |                               fixed "true"|"false"
     80 |                               maxLength value
     81 |                               minLength value
     82 |                               minInclusive value
     83 |                               maxInclusive value
     84 |                               enumeration value
     85 | 
     86 | 
    87 |

    Returns : Nothing

    88 |

    Side-Effects : None

    89 |

    Exception Conditions : None

    90 |

    Pre-requisite Conditions : None

    91 |
    92 | 93 |

    94 |

    Getting a type definition

    95 |

    Procedure Name : ::WS::Utils::GetServiceTypeDef

    96 |

    Description : Query for type definitions.

    97 |

    Arguments :

         mode            - Client or Server
     98 |      service         - The name of the service this query is for
     99 |      type            - The type to be retrieved (optional)
    100 | 
    101 |

    Returns :

         If type not provided, a dictionary object describing all of the types
    102 |      for the service.
    103 |      If type provided, a dictionary object describing the type.
    104 |        A definition consist of a dictionary object with the following key/values:
    105 |          xns         - The namespace for this type.
    106 |          definition  - The definition of the type's fields.  This consist of one
    107 |                        or more occurance of a field definition.  Each field definition
    108 |                        consist of:  fieldName fieldInfo
    109 |                        Where field info is: {type typeName comment commentString}
    110 |                          typeName can be any simple or defined type.
    111 |                          commentString is a quoted string describing the field.
    112 | 
    113 |

    Side-Effects : None

    114 |

    Exception Conditions : None

    115 |

    Pre-requisite Conditions : The service must be defined.

    116 | 117 |
    118 | 119 |

    Generating a template dictionary for a type definition

    120 |

    Procedure Name : ::WS::Utils::GenerateTemplateDict

    121 |

    Description : Generate a template dictionary object for a given type.

    122 |

    Arguments :

         mode            - Client or Server
    123 |      serviceName     - The service name the type is defined in
    124 |      type            - The name of the type
    125 |      arraySize       - Number of elements to generate in an array.  Default is 2.
    126 | 
    127 |

    Returns :

          A dictionary object for a given type.  If any circular references exist, they will have the value of <** Circular Reference **>
    128 | 
    129 |

    Side-Effects : None

    130 |

    Exception Conditions : None

    131 |

    Pre-requisite Conditions : The type and service must be defined.

    132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/Creating_a_Web_Service_Type.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Creating a Web Service Type from Tcl 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |

    Creating a Web Service Type from Tcl

    12 | 13 | 14 | 15 |
    16 |
    17 |

    Contents

    18 |
    32 |

    33 | 34 | 35 |

    36 | 37 | 38 |

    Overview

    39 |

    Webservice Type declaration is part of the Webservices Utility package.

    40 |

    When writing a web service it is often requried to write a complex type 41 | definition for an argument containing structured data.

    42 |

    When calling an operation on a web service it is sometimes convient to define 43 | a complex type to return structured data as an XML fragment even though the 44 | sevice may state that it is only expecting a string.

    45 | 46 | 47 |

    Loading the Webservices Utility Package

    48 |

    To load the webservices server package, do:

     package require WS::Utils
     49 | 
    50 |

    This command will only load the utilities the first time it is used, so it 51 | causes no ill effects to put this in each file using the utilties.

    52 |
    53 | 54 | 55 |

    Defining a type

    56 |

    Procedure Name : ::WS::Utils::ServiceTypeDef

    57 |

    Description : Define a type for a service.

    58 |

    Arguments :

         mode            - Client or Server
     59 |      service         - The name of the service this type definition is for
     60 |      type            - The type to be defined/redefined
     61 |      definition      - The definition of the type's fields.  This consist of one
     62 |                            or more occurance of a field definition.  Each field definition
     63 |                            consist of:  fieldName fieldInfo
     64 |                            Where field info is: {type typeName comment commentString}
     65 |                               typeName can be any simple or defined type.
     66 |                               commentString is a quoted string describing the field.
     67 | 
    68 |

    Returns : Nothing

    69 |

    Side-Effects : None

    70 |

    Exception Conditions : None

    71 |

    Pre-requisite Conditions : None

    72 |
    73 | 74 | 75 |

    Defining a derived type

    76 |

    Procedure Name : ::WS::Utils::ServiceSimpleTypeDef

    77 |

    Description : Define a derived type for a service.

    78 |

    Arguments :

         mode            - Client or Server
     79 |      service         - The name of the service this type definition is for
     80 |      type            - The type to be defined/redefined
     81 |      definition      - The definition of the type's fields.  This consist of one
     82 |                            or more occurance of a field definition.  Each field definition
     83 |                            consist of:  fieldName fieldInfo
     84 |                            Where: {type typeName comment commentString}
     85 |                               baseType typeName - any simple or defined type.
     86 |                               comment commentString - a quoted string describing the field.
     87 |                               pattern value
     88 |                               length value
     89 |                               fixed "true"|"false"
     90 |                               maxLength value
     91 |                               minLength value
     92 |                               minInclusive value
     93 |                               maxInclusive value
     94 |                               enumeration value
     95 | 
     96 | 
    97 |

    Returns : Nothing

    98 |

    Side-Effects : None

    99 |

    Exception Conditions : None

    100 |

    Pre-requisite Conditions : None

    101 |
    102 | 103 | 104 |

    Getting a type definition

    105 |

    Procedure Name : ::WS::Utils::GetServiceTypeDef

    106 |

    Description : Query for type definitions.

    107 |

    Arguments :

         mode            - Client or Server
    108 |      service         - The name of the service this query is for
    109 |      type            - The type to be retrieved (optional)
    110 | 
    111 |

    Returns :

         If type not provided, a dictionary object describing all of the types
    112 |      for the service.
    113 |      If type provided, a dictionary object describing the type.
    114 |        A definition consist of a dictionary object with the following key/values:
    115 |          xns         - The namespace for this type.
    116 |          definition  - The definition of the type's fields.  This consist of one
    117 |                        or more occurance of a field definition.  Each field definition
    118 |                        consist of:  fieldName fieldInfo
    119 |                        Where field info is: {type typeName comment commentString}
    120 |                          typeName can be any simple or defined type.
    121 |                          commentString is a quoted string describing the field.
    122 | 
    123 |

    Side-Effects : None

    124 |

    Exception Conditions : None

    125 |

    Pre-requisite Conditions : The service must be defined.

    126 | 127 |
    128 | 129 |

    Generating a template dictionary for a type definition

    130 |

    Procedure Name : ::WS::Utils::GenerateTemplateDict

    131 |

    Description : Generate a template dictionary object for a given type.

    132 |

    Arguments :

         mode            - Client or Server
    133 |      serviceName     - The service name the type is defined in
    134 |      type            - The name of the type
    135 |      arraySize       - Number of elements to generate in an array.  Default is 2.
    136 | 
    137 |

    Returns :

          A dictionary object for a given type.  If any circular references exist, they will have the value of <** Circular Reference **>
    138 | 
    139 |

    Side-Effects : None

    140 |

    Exception Conditions : None

    141 |

    Pre-requisite Conditions : The type and service must be defined.

    142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /docs/Using_Options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Using Web Service Options 4 | 5 | 6 | 7 | 8 |

    Using Web Service Options

    9 | 10 | 11 | 12 | 13 |
    14 |

    Contents

    15 | 32 |

    33 | 34 |

    35 | 36 |

    Overview

    37 |

    38 |

    The Webservices Client and Server packages make use of the following options: 39 |

    51 |

    52 | 53 |

    The attributes can be retrieved and set using ::WS::Utils::SetOption.

    54 | 55 |

    If called by the client side, the following options are overwritten and restored on any call: 56 |

      57 |
    • genOutAttr
    • 58 |
    • nsOnChangeOnly
    • 59 |
    • parseInAttr
    • 60 |
    • suppressNS
    • 61 |
    • UseNS
    • 62 |
    • useTypeNs
    • 63 |
    • valueAttrCompatiblityMode
    • 64 |
    65 | 66 |

    67 | 68 |
    69 | 70 |

    Loading the Webservices Utilities Package

    71 |

    To load the webservices server package, do:

     package require WS::Utils
     72 | 
    73 |

    This command will only load the utilities the first time it is used, so it 74 | causes no ill effects to put this in each file using the utilties.

    75 |
    76 | 77 | 78 |

    Access Routine

    79 |

    Procedure Name : ::WS::Utils::SetOption

    80 |

    Description : Retrieve or set an option

    81 |

    Arguments :

    82 |
     83 |     option - name of the option
     84 |     value - value of the option (optional)
     85 | 
    86 |

    Returns : The value of the option

    87 |

    Side-Effects : None

    88 |

    Exception Conditions :None

    89 |

    Pre-requisite Conditions : None

    90 |
    91 | 92 | 93 |

    genOutAttr - generate attributes on outbound tags

    94 |

    95 | The genOutAttr option, if set to a "true" value, 96 | will convert all dictionary keys of the entry for a given field tag to attribute value pairs 97 | of the tag in the outbound XML. 98 | For attributes in the "http://www.w3.org/2001/XMLSchema-instance" url, the key will be the attribute name prepended with two colons (e.g. ::type) and the value will be the value of the attribute. 99 | For attributes other than those in the "http://www.w3.org/2001/XMLSchema-instance" url, the key will be the attribute name and the value will be the value of the attribute. 100 | The value of the tag will have a key determined by the valueAttrCompatiblityMode. 101 |

    102 |

    103 | The default value, "0", is for this option to be turned off. 104 |

    105 |
    106 | 107 |

    108 |

    includeDirectory - disk directory to use for XSD includes when they can not be accessed via the Web.

    109 |

    110 | The includeDirectory option, if set, instructs TclWs to look in the specified directory for any XSD includes that can not be found via the web. 111 |

    112 |

    113 | The default value, "{}", is for this option to be turned off. 114 |

    115 |
    116 | 117 |

    118 |

    nsOnChangeOnly - only put namespace prefix when namespaces change

    119 |

    120 | The nsOnChangeOnly option, if set to a "true" value, 121 | will only place namespace prefixes when the namespaces change. 122 |

    123 |

    124 | This option is only relevant, if the option UseNS is set. 125 |

    126 |

    127 | The default value, "0", is for this option to be turned off. 128 |

    129 |
    130 | 131 | 132 |

    parseInAttr - parse attributes on inbound tags

    133 |

    134 | The parseInAttr option, if set to a "true" value, 135 | will convert all attributes of inbound field tags to dictionary entries for that tag. 136 | For attributes in the "http://www.w3.org/2001/XMLSchema-instance" url, the key will be the attribute name prepended with two colons (e.g. ::type) and the value will be the value of the attribute. 137 | For attributes other than those in the "http://www.w3.org/2001/XMLSchema-instance" url, the key will be the attribute name and the value will be the value of the attribute. 138 | The value of the tag will have a key determined by the valueAttrCompatiblityMode. 139 |

    140 |

    141 | The default value, "0", is for this option to be turned off. 142 |

    143 |
    144 | 145 |

    146 |

    queryTimeout - set http(s) query timeout

    147 |

    148 | Timeout to any network query in ms. 149 | The client side package has an option with the same functionality, which is used, when there is a call option context. 150 |

    151 |

    Default value: 60000 (1 minuite).

    152 |
    153 | 154 | 155 |

    StrictMode - WSDL processing mode

    156 |

    157 | The StrictMode option determines what happens when an error is detected in parsing a WSDL. The legal values are: 158 |

      159 |
    • debug
    • 160 |
    • warning
    • 161 |
    • error
    • 162 |
    163 |

    164 |

    165 | If the StrictMode is set to debug or warning, 166 | a message is logged using the ::log package at that level and the error is then ignored. 167 |

    168 |

    169 | If the StrictMode is set to any value other than debug or warning, 170 | a message is logged using the ::log package at the error level and exception is generated. 171 |

    172 |

    173 | The default value is error. 174 |

    175 |

    176 | A major use of this is to ignore namespace imports in a WDSL that do not actually import any definitions. 177 |

    178 |
    179 | 180 | 181 |

    UseNS - put namespaces on field tags

    182 |

    183 | The UseNS option, if set to a "true" value, will put a namespace alias on all field tags. 184 |

    185 |

    186 | The default value, "1", is for this option to be turned on. 187 |

    188 |
    189 | 190 |

    191 |

    useTypeNs - use type's namespace prefix as prefix of elements

    192 |

    193 | The useTypeNs option, if set to a "true" value, 194 | will use the prefix of the type's namespace instead of the prefix of the element's namespace. 195 |

    196 |

    197 | This option is only relevant, if the option UseNS is set. 198 |

    199 |

    200 | The default value, "0", is for this option to be turned off. 201 |

    202 |
    203 | 204 |

    205 |

    suppressNS - do not put a given namespace prefix.

    206 |

    207 | The suppressNS option, if set, will cause the given namespace 208 | to never be used as a prefix (i.e. tags that would normally have had 209 | the given prefix will not have any prefix). 210 |

    211 |

    212 | This option is only relevant, if the option UseNS is set. 213 |

    214 |

    215 | The default value, "{}", is for this option to be turned off. 216 |

    217 |
    218 | 219 | 220 |

    valueAttrCompatiblityMode - specify dictionary key for value when attributes are in use

    221 |

    222 | This option is only meaningful when the 223 | parseInAttr or genOutAttr option is set to a "true" value. 224 | When set to a "true" value, the value of the tag will have a key of the null string (i.e. {}). 225 | When set to a "false" value, the value of the tag will have a key of ::value. 226 |

    227 |

    228 | The default value, "0", is for this option to be turned off. 229 |

    230 |
    231 | 232 | 233 | 234 | -------------------------------------------------------------------------------- /ChannelServer.tcl: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## ## 3 | ## Copyright (c) 2008, Gerald W. Lester ## 4 | ## All rights reserved. ## 5 | ## ## 6 | ## Redistribution and use in source and binary forms, with or without ## 7 | ## modification, are permitted provided that the following conditions ## 8 | ## are met: ## 9 | ## ## 10 | ## * Redistributions of source code must retain the above copyright ## 11 | ## notice, this list of conditions and the following disclaimer. ## 12 | ## * Redistributions in binary form must reproduce the above ## 13 | ## copyright notice, this list of conditions and the following ## 14 | ## disclaimer in the documentation and/or other materials provided ## 15 | ## with the distribution. ## 16 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 17 | ## of its contributors may be used to endorse or promote products ## 18 | ## derived from this software without specific prior written ## 19 | ## permission. ## 20 | ## ## 21 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 22 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 23 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 24 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 25 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 26 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 27 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 28 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 29 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 30 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 31 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 32 | ## POSSIBILITY OF SUCH DAMAGE. ## 33 | ## ## 34 | ############################################################################### 35 | 36 | package require Tcl 8.6- 37 | # XXX WS::Utils usable here? (provide dict, lassign) 38 | if {![llength [info command dict]]} { 39 | package require dict 40 | } 41 | if {![llength [info command lassign]]} { 42 | proc lassign {inList args} { 43 | set numArgs [llength $args] 44 | set i -1 45 | foreach var $args { 46 | incr i 47 | uplevel 1 [list set $var [lindex $inList $i]] 48 | } 49 | return [lrange $inList $numArgs end] 50 | } 51 | } 52 | 53 | package require uri 54 | package require base64 55 | package require html 56 | 57 | package provide WS::Channel 2.5.0 58 | 59 | namespace eval ::WS::Channel { 60 | 61 | array set portInfo {} 62 | array set dataArray {} 63 | } 64 | 65 | 66 | ########################################################################### 67 | # 68 | # Public Procedure Header - as this procedure is modified, please be sure 69 | # that you update this header block. Thanks. 70 | # 71 | #>>BEGIN PUBLIC<< 72 | # 73 | # Procedure Name : ::WS::Channel::AddHandler 74 | # 75 | # Description : Register a handler for a url on a port. 76 | # 77 | # Arguments : 78 | # ports -- The port to register the callback on 79 | # operation -- {} for WSDL callback, otherwise operation callback 80 | # callback -- The callback prefix, two additionally arguments are lappended 81 | # the callback: (1) the socket (2) the null string 82 | # 83 | # Returns : Nothing 84 | # 85 | # Side-Effects : 86 | # None 87 | # 88 | # Exception Conditions : None 89 | # 90 | # Pre-requisite Conditions : ::WS::Channel::Listen must have been called for the port 91 | # 92 | # Original Author : Gerald W. Lester 93 | # 94 | #>>END PUBLIC<< 95 | # 96 | # Maintenance History - as this file is modified, please be sure that you 97 | # update this segment of the file header block by 98 | # adding a complete entry at the bottom of the list. 99 | # 100 | # Version Date Programmer Comments / Changes / Reasons 101 | # ------- ---------- ---------- ------------------------------------------- 102 | # 1 03/28/2008 G.Lester Initial version 103 | # 104 | # 105 | ########################################################################### 106 | proc ::WS::Channel::AddHandler {ports operation callback} { 107 | variable portInfo 108 | 109 | if {[llength $ports] == 2} { 110 | lassign $ports in out 111 | set portInfo(in) $in 112 | set portInfo(out) $out 113 | set portInfo(eof) [lindex [fconfigure $portInfo(out) -eofchar] end] 114 | } elseif {[llength $ports] == 1} { 115 | set portInfo(in) $ports 116 | set portInfo(out) $ports 117 | set portInfo(eof) [fconfigure $portInfo(out) -eofchar] 118 | } else { 119 | return -code error -errorcode [list ] "Invalid channel count {$ports}" 120 | } 121 | if {[string length $operation]} { 122 | set portInfo(op) $callback 123 | } else { 124 | set portInfo(wsdl) $callback 125 | } 126 | return; 127 | } 128 | 129 | 130 | ########################################################################### 131 | # 132 | # Public Procedure Header - as this procedure is modified, please be sure 133 | # that you update this header block. Thanks. 134 | # 135 | #>>BEGIN PUBLIC<< 136 | # 137 | # Procedure Name : ::WS::Channel::ReturnData 138 | # 139 | # Description : Store the information to be returned. 140 | # 141 | # Arguments : 142 | # socket -- Socket data is for 143 | # type -- Mime type of data 144 | # data -- Data 145 | # code -- Status code 146 | # 147 | # Returns : Nothing 148 | # 149 | # Side-Effects : 150 | # None 151 | # 152 | # Exception Conditions : None 153 | # 154 | # Pre-requisite Conditions : A callback on the socket should be pending 155 | # 156 | # Original Author : Gerald W. Lester 157 | # 158 | #>>END PUBLIC<< 159 | # 160 | # Maintenance History - as this file is modified, please be sure that you 161 | # update this segment of the file header block by 162 | # adding a complete entry at the bottom of the list. 163 | # 164 | # Version Date Programmer Comments / Changes / Reasons 165 | # ------- ---------- ---------- ------------------------------------------- 166 | # 1 03/28/2008 G.Lester Initial version 167 | # 168 | # 169 | ########################################################################### 170 | proc ::WS::Channel::ReturnData {sock type data code} { 171 | variable dataArray 172 | 173 | foreach var {type data code} { 174 | dict set dataArray(reply) $var [set $var] 175 | } 176 | return; 177 | } 178 | 179 | 180 | ########################################################################### 181 | # 182 | # Public Procedure Header - as this procedure is modified, please be sure 183 | # that you update this header block. Thanks. 184 | # 185 | #>>BEGIN PUBLIC<< 186 | # 187 | # Procedure Name : ::WS::Channel::Start 188 | # 189 | # Description : Start listening on all ports (i.e. enter the event loop). 190 | # 191 | # Arguments : None 192 | # 193 | # Returns : Value that event loop was exited with. 194 | # 195 | # Side-Effects : 196 | # None 197 | # 198 | # Exception Conditions : None 199 | # 200 | # Pre-requisite Conditions : 201 | # ::WS::Channel::Listen should have been called for one or more port. 202 | # 203 | # 204 | # Original Author : Gerald W. Lester 205 | # 206 | #>>END PUBLIC<< 207 | # 208 | # Maintenance History - as this file is modified, please be sure that you 209 | # update this segment of the file header block by 210 | # adding a complete entry at the bottom of the list. 211 | # 212 | # Version Date Programmer Comments / Changes / Reasons 213 | # ------- ---------- ---------- ------------------------------------------- 214 | # 1 03/28/2008 G.Lester Initial version 215 | # 216 | # 217 | ########################################################################### 218 | proc ::WS::Channel::Start {} { 219 | variable portInfo 220 | variable dataArray 221 | 222 | while {1} { 223 | array unset dataArray 224 | set xml [read $portInfo(in)] 225 | if {[string length $xml]} { 226 | ## 227 | ## Call for an operation 228 | ## 229 | handler op $xml 230 | } else { 231 | ## 232 | ## Call for a WSDL 233 | ## 234 | handler wsdl {} 235 | } 236 | } 237 | } 238 | 239 | 240 | 241 | ########################################################################### 242 | # 243 | # Private Procedure Header - as this procedure is modified, please be sure 244 | # that you update this header block. Thanks. 245 | # 246 | #>>BEGIN PRIVATE<< 247 | # 248 | # Procedure Name : ::WS::Channel::respond 249 | # 250 | # Description : Send response back to user. 251 | # 252 | # Arguments : 253 | # sock -- Socket to send reply on 254 | # code -- Code to send 255 | # body -- HTML body to send 256 | # head -- HTML header to send 257 | # 258 | # Returns : 259 | # Nothing 260 | # 261 | # Side-Effects : None 262 | # 263 | # Exception Conditions : None 264 | # 265 | # Pre-requisite Conditions : None 266 | # 267 | # Original Author : Gerald W. Lester 268 | # 269 | #>>END PRIVATE<< 270 | # 271 | # Maintenance History - as this file is modified, please be sure that you 272 | # update this segment of the file header block by 273 | # adding a complete entry at the bottom of the list. 274 | # 275 | # Version Date Programmer Comments / Changes / Reasons 276 | # ------- ---------- ---------- ------------------------------------------- 277 | # 1 03/28/2008 G.Lester Initial version 278 | # 279 | # 280 | ########################################################################### 281 | proc ::WS::Channel::respond {sock code body {head ""}} { 282 | puts -nonewline $sock "HTTP/1.0 $code ???\nContent-Type: text/html; charset=ISO-8859-1\nConnection: close\nContent-length: [string length $body]\n$head\n$body" 283 | } 284 | 285 | 286 | ########################################################################### 287 | # 288 | # Private Procedure Header - as this procedure is modified, please be sure 289 | # that you update this header block. Thanks. 290 | # 291 | #>>BEGIN PRIVATE<< 292 | # 293 | # Procedure Name : ::WS::Channel::handler 294 | # 295 | # Description : Handle a request. 296 | # 297 | # Arguments : 298 | # type -- Request type 299 | # xml -- XML 300 | # 301 | # Returns : 302 | # Nothing 303 | # 304 | # Side-Effects : None 305 | # 306 | # Exception Conditions : None 307 | # 308 | # Pre-requisite Conditions : None 309 | # 310 | # Original Author : Gerald W. Lester 311 | # 312 | #>>END PRIVATE<< 313 | # 314 | # Maintenance History - as this file is modified, please be sure that you 315 | # update this segment of the file header block by 316 | # adding a complete entry at the bottom of the list. 317 | # 318 | # Version Date Programmer Comments / Changes / Reasons 319 | # ------- ---------- ---------- ------------------------------------------- 320 | # 1 03/28/2008 G.Lester Initial version 321 | # 322 | # 323 | ########################################################################### 324 | proc ::WS::Channel::handler {type xml} { 325 | variable portInfo 326 | variable dataArray 327 | upvar #0 Httpd_Channel data 328 | 329 | 330 | set ::errorInfo {} 331 | set data(query) $xml 332 | set cmd $portInfo($type) 333 | lappend cmd _Channel {} 334 | puts "Calling {$cmd}" 335 | if {[catch {eval $cmd} msg]} { 336 | respond $portInfo(out) 404 Error $msg 337 | } else { 338 | set data [dict get $dataArray(reply) data] 339 | set reply "HTTP/1.0 [dict get $dataArray(reply) code] ???\n" 340 | append reply "Content-Type: [dict get $dataArray(reply) type]; charset=UTF-8\n" 341 | append reply "Connection: close\n" 342 | append reply "Content-length: [string length $data]\n" 343 | append reply "\n" 344 | append reply $data 345 | puts -nonewline $portInfo(out) $reply 346 | } 347 | puts -nonewline $portInfo(eof) 348 | 349 | return; 350 | } 351 | -------------------------------------------------------------------------------- /docs/Creating_a_Tcl_Web_Service.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Creating a Tcl Web Service 4 | 5 | 6 | 7 | 8 | 9 |

    Creating a Tcl Web Service

    10 | 11 | 12 | 13 | 14 | 32 | 33 | 34 |
    15 |
    16 |

    Contents

    17 | 31 |
    35 | 36 | 37 |

    Loading the Webservices Server Package

    38 | 39 |

    To load the webservices server package, do:

    40 |
     package require WS::Server
    41 |

    This command will only load the server the first time it is used, so it 42 | causes no ill effects to put this in each file declaring a service or service 43 | procedure.

    44 | 45 |

    Using as part of TclHttpd

    46 | 47 |

    48 | The Web Services package, WS::Server, is not a standalone application, but rather is designed 49 | to be a "module" of TclHttpd. 50 | The following command is normally placed in httpdthread.tcl: 51 |

    52 | 53 | 54 |

    Embedding in a Standalone Application

    55 | 56 |

    57 | To embed a Web Service into an application, the application needs to be event 58 | driven and you also need to use the WS::Embeded package. You also must 59 | define the service with the -mode=embedded option. 60 |

    61 | 62 |

    63 | See also 64 | Embedding a Web Service into an application. 65 |

    66 | 67 |

    Using with Apache Rivet

    68 | 69 |

    70 | Apache Rivet is a module (mod_rivet) that can be loaded by Apache httpd server to 71 | allow web pages to run embedded Tcl commands in a way similar to PHP. To create 72 | a Web Service in Rivet, use the example EchoRivetService.rvt as a starting point 73 | by simply copying it into any directory served by your Apache instance. You should be able to 74 | immediately access that new location at the following URLs: 75 |

    76 |
                   /path/to/EchoRivetService.rvt/doc
     77 |                      Displays an HTML page describing the service
     78 |                /path/to/EchoRivetService.rvt/wsdl
     79 |                      Returns a WSDL describing the service
     80 |                /path/to/EchoRivetService.rvt/op
     81 |                      Invoke an operation
     82 | 
    83 |

    84 | If you would prefer to expose the published URLs of your service differently, you can use the 85 | standard Apache mod_rewrite or mod_alias modules to transparently map any other URL to those locations. 86 |

    87 | 88 | 89 |
    90 | 91 | 92 |

    Defining a Service

    93 | 94 |

    95 | The code that defines a service is normally placed in one or more files in the custom directory. 96 |

    97 | 98 |

    Procedure Name : ::WS::Server::Service

    99 |

    Description : Declare a Web Service, the following URLs will 100 | exist

                   /service/<ServiceName>
    101 |                      Displays an HTML page describing the service
    102 |                /service/<ServiceName>/wsdl
    103 |                      Returns a WSDL describing the service
    104 |                /service/<ServiceName>/op
    105 |                      Invoke an operation
    106 | 
    107 |

    Arguments : this procedure uses position independent arguments, 108 | they are:

    109 |              -hostcompatibility32 bool - Activate version 3.2.0 compatibility
    110 |                                mode for -host parameter.
    111 |                                Defaults to true.
    112 |              -host           - The host specification within XML namespaces
    113 |                                of the transmitted XML files.
    114 |                                This should be unique.
    115 |                                Defaults to localhost.
    116 |                                If 3.2 compatibility is activated, the default
    117 |                                value is changed to ip:port in embedded mode.
    118 |              -hostlocation   - The host name, which is promoted within the
    119 |                                generated WSDL file. Defaults to localhost.
    120 |                                If 3.2 compatibility is activated, the
    121 |                                default value is equal to the -host parameter.
    122 |              -hostlocationserver bool - If true, the host location is set by
    123 |                                the current server settings.
    124 |                                In case of httpd server, this value is imported.
    125 |                                For other servers or if this fails, the value
    126 |                                is the current ip:port.
    127 |                                The default value is true.
    128 |                                In case of 3.2 compatibility, the default
    129 |                                value is true for tclhttpd, false otherwise.
    130 |              -hostProtocol   - Define the host protocol (http, https) for the
    131 |                                WSDL location URL. The special value "server"
    132 |                                (default) follows the TCP/IP server specification.
    133 |                                This is implemented for Embedded server and tclhttpd.
    134 |                                Remark that the protocol for XML namespaces
    135 |                                is always "http".
    136 |              -description    - The HTML description for this service
    137 |              -htmlhead       - The title string of the service description
    138 |              -author         - The author property in the service description
    139 |              -xmlnamespace   - Extra XML namespaces used by the service
    140 |              -service        - The service name (this will also be used for
    141 |                                  the Tcl namespace of the procedures that implement
    142 |                                  the operations.
    143 |              -premonitor     - This is a command prefix to be called before
    144 |                                  an operation is called.  The following arguments are
    145 |                                  added to the command prefix:
    146 |                                     PRE serviceName operationName operArgList
    147 |              -postmonitor    - This is a command prefix to be called after
    148 |                                  an operation is called.  The following arguments are
    149 |                                  added to the command prefix:
    150 |                                     POST serviceName operationName OK|ERROR results
    151 |              -inheaders      - List of input header types.
    152 |              -outheaders     - List of output header types.
    153 |              -intransform    - Inbound (request) transform procedure (2.0.3 and later).
    154 |                                 The signature of the command must be:
    155 |                                      cmd \
    156 |                                          mode (REQUEST) \
    157 |                                          xml \
    158 |                                          notUsed_1 \
    159 |                                          notUsed_2
    160 |              -outtransform   - Outbound (reply) transform procedure (2.0.3 and later).
    161 |                                 The signature of the command must be:
    162 |                                      cmd \
    163 |                                          mode (REPLY) \
    164 |                                          xml \
    165 |                                          operation \
    166 |                                          resultDict
    167 |              -checkheader    - Command prefix to check headers.
    168 |                                    If the call is not to be allowed, this command
    169 |                                    should raise an error.
    170 |                                    The signature of the command must be:
    171 |                                      cmd \
    172 |                                          service \
    173 |                                          operation \
    174 |                                          caller_ipaddr \
    175 |                                          http_header_list \
    176 |                                          soap_header_list
    177 |             -mode           - Mode that service is running in.  Must be one of:
    178 |                                    tclhttpd  -- running inside of tclhttpd or an
    179 |                                                 environment that supplies a
    180 |                                                 compatible Url_PrefixInstall
    181 |                                                 and Httpd_ReturnData commands
    182 |                                    embedded  -- using the ::WS::Embedded package
    183 |                                    aolserver -- using the ::WS::AolServer package
    184 |                                    wub       -- using the ::WS::Wub package
    185 |                                    wibble    -- running inside wibble
    186 |                                    rivet     -- running inside Apache Rivet (mod_rivet)
    187 |             -ports          - List of ports for embedded mode. Default: 80
    188 |                                     NOTE -- a call should be to
    189 |                                             ::WS::Embedded::Listen for each port
    190 |                                             in this list prior to calling ::WS::Embeded::Start
    191 |             -prefix         - Path prefix used for the namespace and endpoint
    192 |                               Defaults to "/service/" plus the service name
    193 |             -traceEnabled   - Boolean to enable/disable trace being passed back in exception
    194 |                               Defaults to "Y"
    195 |             -docFormat      - Format of the documentation for operations ("text" or "html").
    196 |                               Defaults to "text"
    197 |             -stylesheet     - The CSS stylesheet URL used in the HTML documentation
    198 | 
    199 |             -errorCallback  - Callback to be invoked in the event of an error being produced
    200 |             -verifyUserArgs - Boolean to enable/disable validating user supplied arguments
    201 |                               Defaults to "N"
    202 |             -enforceRequired - Throw an error if a required field is not included in the
    203 |                                response.
    204 |                                Defaults to "N"
    205 | 
    206 |

    Returns : Nothing

    207 |

    Side-Effects : None

    208 |

    Exception Conditions :

         MISSREQARG -- Missing required arguments
    209 | 
    210 |

    Pre-requisite Conditions : None

    211 |
    212 | 213 | 214 |

    Defining an Operation (aka a Service Procedure)

    215 |

    Procedure Name : ::WS::Server::ServiceProc

    216 |

    Description : Register an operation for a service and declare the 217 | procedure to handle the operations.

    218 |

    Arguments :

         ServiceName     -- Name of the service this operation is for
    219 |      NameInfo        -- List of two elements:
    220 |                              1) OperationName -- the name of the operation
    221 |                              2) ReturnType    -- the type of the procedure return,
    222 |                                                  this can be a simple or complex type
    223 |      Arglist         -- List of argument definitions,
    224 |                          each list element must be of the form:
    225 |                              1) ArgumentName -- the name of the argument
    226 |                              2) ArgumentTypeInfo -- -- A list of:
    227 |                                     {type typeName comment commentString}
    228 |                                          typeName can be any simple or defined type.
    229 |                                          commentString is a quoted string describing the field
    230 |      Documentation   -- HTML describing what this operation does
    231 |      Body            -- The tcl code to be called when the operation is invoked. This
    232 |                             code should return a dictionary with <OperationName>Result as a
    233 |                             key and the operation's result as the value.
    234 | 
    235 | 236 | Available simple types are: 237 |
    • anyType, string, boolean, decimal, float, double, duration, dateTime, time, date, gYearMonth, gYear, gMonthDay, gDay, gMonth, hexBinary, base64Binary, anyURI, QName, NOTATION, normalizedString, token, language, NMTOKEN, NMTOKENS, Name, NCName, ID, IDREF, IDREFS, ENTITY, ENTITIES, integer, nonPositiveInteger, negativeInteger, long, int, short, byte, nonNegativeInteger, unsignedLong, unsignedInt, unsignedShort, unsignedByte, positiveInteger
    238 | 239 | 240 | The typeName may contain the following suffixes: 241 |
      242 |
    • () : type is an array
    • 243 |
    • ? : type is an optional parameter
    • 244 |
    245 | 246 |

    Returns : Nothing

    247 |

    Side-Effects :

       A procedure named "<ServiceName>::<OperationName>" defined
    248 |    A type name with the name <OperationName>Result is defined.
    249 | 
    250 |

    Exception Conditions : None

    251 |

    Pre-requisite Conditions : ::WS::Server::Server must have 252 | been called for the ServiceName

    253 |
    254 | 255 | 256 |

    Declaring Complex Types

    257 |

    See: Creating 260 | a Web Service Type from Tcl

    261 | 262 | 263 | 264 | -------------------------------------------------------------------------------- /docs/style.css: -------------------------------------------------------------------------------- 1 | /* General settings for the entire page */ 2 | body { 3 | margin: 0ex 0ex; 4 | padding: 0px; 5 | background-color: #fef3bc; 6 | font-family: sans-serif; 7 | } 8 | 9 | /* The project logo in the upper left-hand corner of each page */ 10 | div.logo { 11 | display: inline; 12 | text-align: center; 13 | vertical-align: bottom; 14 | font-weight: bold; 15 | font-size: 2.5em; 16 | color: #a09048; 17 | } 18 | 19 | /* The page title centered at the top of each page */ 20 | div.title { 21 | display: table-cell; 22 | font-size: 2em; 23 | font-weight: bold; 24 | text-align: left; 25 | padding: 0 0 0 5px; 26 | color: #a09048; 27 | vertical-align: bottom; 28 | width: 100%; 29 | } 30 | 31 | /* The login status message in the top right-hand corner */ 32 | div.status { 33 | display: table-cell; 34 | text-align: right; 35 | vertical-align: bottom; 36 | color: #a09048; 37 | padding: 5px 5px 0 0; 38 | font-size: 0.8em; 39 | font-weight: bold; 40 | } 41 | 42 | /* The header across the top of the page */ 43 | div.header { 44 | display: table; 45 | width: 100%; 46 | } 47 | 48 | /* The main menu bar that appears at the top of the page beneath 49 | ** the header */ 50 | div.mainmenu { 51 | padding: 5px 10px 5px 10px; 52 | font-size: 0.9em; 53 | font-weight: bold; 54 | text-align: center; 55 | letter-spacing: 1px; 56 | background-color: #a09048; 57 | color: black; 58 | } 59 | 60 | /* The submenu bar that *sometimes* appears below the main menu */ 61 | div.submenu, div.sectionmenu { 62 | padding: 3px 10px 3px 0px; 63 | font-size: 0.9em; 64 | text-align: center; 65 | background-color: #c0af58; 66 | color: white; 67 | } 68 | div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited, 69 | div.sectionmenu>a.button:link, div.sectionmenu>a.button:visited { 70 | padding: 3px 10px 3px 10px; 71 | color: white; 72 | text-decoration: none; 73 | } 74 | div.mainmenu a:hover, div.submenu a:hover, div.sectionmenu>a.button:hover { 75 | color: #a09048; 76 | background-color: white; 77 | } 78 | 79 | /* All page content from the bottom of the menu or submenu down to 80 | ** the footer */ 81 | div.content { 82 | padding: 1ex 5px; 83 | } 84 | div.content a { color: #706532; } 85 | div.content a:link { color: #706532; } 86 | div.content a:visited { color: #704032; } 87 | div.content a:hover { background-color: white; color: #706532; } 88 | 89 | /* Some pages have section dividers */ 90 | div.section { 91 | margin-bottom: 0px; 92 | margin-top: 1em; 93 | padding: 3px 3px 0 3px; 94 | font-size: 1.2em; 95 | font-weight: bold; 96 | background-color: #a09048; 97 | color: white; 98 | } 99 | 100 | /* The "Date" that occurs on the left hand side of timelines */ 101 | div.divider { 102 | background: #e1d498; 103 | border: 2px #a09048 solid; 104 | font-size: 1em; font-weight: normal; 105 | padding: .25em; 106 | margin: .2em 0 .2em 0; 107 | float: left; 108 | clear: left; 109 | } 110 | 111 | /* The footer at the very bottom of the page */ 112 | div.footer { 113 | font-size: 0.8em; 114 | margin-top: 12px; 115 | padding: 5px 10px 5px 10px; 116 | text-align: right; 117 | background-color: #a09048; 118 | color: white; 119 | } 120 | 121 | /* Hyperlink colors */ 122 | div.footer a { color: white; } 123 | div.footer a:link { color: white; } 124 | div.footer a:visited { color: white; } 125 | div.footer a:hover { background-color: white; color: #558195; } 126 | 127 | /* blocks */ 128 | pre.verbatim { 129 | background-color: #f5f5f5; 130 | padding: 0.5em; 131 | } 132 | 133 | /* The label/value pairs on (for example) the ci page */ 134 | table.label-value th { 135 | vertical-align: top; 136 | text-align: right; 137 | padding: 0.2ex 2ex; 138 | } 139 | 140 | /* Side-by-side diff */ 141 | table.sbsdiff { 142 | background-color: #ffffc5; 143 | font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace; 144 | font-size: 8pt; 145 | border-collapse:collapse; 146 | white-space: pre; 147 | width: 98%; 148 | border: 1px #000 dashed; 149 | } 150 | 151 | table.sbsdiff th.diffhdr { 152 | border-bottom: dotted; 153 | border-width: 1px; 154 | } 155 | 156 | table.sbsdiff tr td { 157 | white-space: pre; 158 | padding-left: 3px; 159 | padding-right: 3px; 160 | margin: 0px; 161 | } 162 | 163 | table.sbsdiff tr td.lineno { 164 | text-align: right; 165 | } 166 | 167 | table.sbsdiff tr td.meta { 168 | background-color: #a09048; 169 | text-align: center; 170 | } 171 | 172 | table.sbsdiff tr td.added { 173 | background-color: rgb(210, 210, 100); 174 | } 175 | 176 | table.sbsdiff tr td.removed { 177 | background-color: rgb(190, 200, 110); 178 | } 179 | 180 | table.sbsdiff tr td.changed { 181 | background-color: rgb(200, 210, 120); 182 | }/* The nomenclature sidebox for branches,.. */ 183 | div.sidebox { 184 | float: right; 185 | background-color: white; 186 | border-width: medium; 187 | border-style: double; 188 | margin: 10px; 189 | } 190 | /* The nomenclature title in sideboxes for branches,.. */ 191 | div.sideboxTitle { 192 | display: inline; 193 | font-weight: bold; 194 | } 195 | /* The defined element in sideboxes for branches,.. */ 196 | div.sideboxDescribed { 197 | display: inline; 198 | font-weight: bold; 199 | } 200 | /* The defined element in sideboxes for branches,.. */ 201 | span.disabled { 202 | color: red; 203 | } 204 | /* The suppressed duplicates lines in timeline, .. */ 205 | span.timelineDisabled { 206 | font-style: italic; 207 | font-size: small; 208 | } 209 | /* the format for the timeline data table */ 210 | table.timelineTable { 211 | border: 0; 212 | } 213 | /* the format for the timeline data cells */ 214 | td.timelineTableCell { 215 | vertical-align: top; 216 | text-align: left; 217 | } 218 | /* the format for the timeline leaf marks */ 219 | span.timelineLeaf { 220 | font-weight: bold; 221 | } 222 | /* the format for the timeline version links */ 223 | a.timelineHistLink { 224 | 225 | } 226 | /* the format for the timeline version display(no history permission!) */ 227 | span.timelineHistDsp { 228 | font-weight: bold; 229 | } 230 | /* the format for the timeline time display */ 231 | td.timelineTime { 232 | vertical-align: top; 233 | text-align: right; 234 | } 235 | /* the format for the grap placeholder cells in timelines */ 236 | td.timelineGraph { 237 | width: 20px; 238 | text-align: left; 239 | vertical-align: top; 240 | } 241 | /* the format for the tag links */ 242 | a.tagLink { 243 | 244 | } 245 | /* the format for the tag display(no history permission!) */ 246 | span.tagDsp { 247 | font-weight: bold; 248 | } 249 | /* the format for wiki errors */ 250 | span.wikiError { 251 | font-weight: bold; 252 | color: red; 253 | } 254 | /* the format for fixed/canceled tags,.. */ 255 | span.infoTagCancelled { 256 | font-weight: bold; 257 | text-decoration: line-through; 258 | } 259 | /* the format for fixed/cancelled tags,.. on wiki pages */ 260 | span.wikiTagCancelled { 261 | text-decoration: line-through; 262 | } 263 | /* format for the file display table */ 264 | table.browser { 265 | /* the format for wiki errors */ 266 | width: 100% ; 267 | border: 0; 268 | } 269 | /* format for cells in the file browser */ 270 | td.browser { 271 | width: 24% ; 272 | vertical-align: top; 273 | } 274 | /* format for the list in the file browser */ 275 | ul.browser { 276 | margin-left: 0.5em; 277 | padding-left: 0.5em; 278 | } 279 | /* table format for login/out label/input table */ 280 | table.login_out { 281 | text-align: left; 282 | margin-right: 10px; 283 | margin-left: 10px; 284 | margin-top: 10px; 285 | } 286 | /* captcha display options */ 287 | div.captcha { 288 | text-align: center; 289 | } 290 | /* format for the layout table, used for the captcha display */ 291 | table.captcha { 292 | margin: auto; 293 | padding: 10px; 294 | border-width: 4px; 295 | border-style: double; 296 | border-color: black; 297 | } 298 | /* format for the label cells in the login/out table */ 299 | td.login_out_label { 300 | text-align: center; 301 | } 302 | /* format for login error messages */ 303 | span.loginError { 304 | color: red; 305 | } 306 | /* format for leading text for notes */ 307 | span.note { 308 | font-weight: bold; 309 | } 310 | /* format for textarea labels */ 311 | span.textareaLabel { 312 | font-weight: bold; 313 | } 314 | /* format for the user setup layout table */ 315 | table.usetupLayoutTable { 316 | outline-style: none; 317 | padding: 0; 318 | margin: 25px; 319 | } 320 | /* format of the columns on the user setup list page */ 321 | td.usetupColumnLayout { 322 | vertical-align: top 323 | } 324 | /* format for the user list table on the user setup page */ 325 | table.usetupUserList { 326 | outline-style: double; 327 | outline-width: 1px; 328 | padding: 10px; 329 | } 330 | /* format for table header user in user list on user setup page */ 331 | th.usetupListUser { 332 | text-align: right; 333 | padding-right: 20px; 334 | } 335 | /* format for table header capabilities in user list on user setup page */ 336 | th.usetupListCap { 337 | text-align: center; 338 | padding-right: 15px; 339 | } 340 | /* format for table header contact info in user list on user setup page */ 341 | th.usetupListCon { 342 | text-align: left; 343 | } 344 | /* format for table cell user in user list on user setup page */ 345 | td.usetupListUser { 346 | text-align: right; 347 | padding-right: 20px; 348 | white-space:nowrap; 349 | } 350 | /* format for table cell capabilities in user list on user setup page */ 351 | td.usetupListCap { 352 | text-align: center; 353 | padding-right: 15px; 354 | } 355 | /* format for table cell contact info in user list on user setup page */ 356 | td.usetupListCon { 357 | text-align: left 358 | } 359 | /* layout definition for the capabilities box on the user edit detail page */ 360 | div.ueditCapBox { 361 | float: left; 362 | margin-right: 20px; 363 | margin-bottom: 20px; 364 | } 365 | /* format of the label cells in the detailed user edit page */ 366 | td.usetupEditLabel { 367 | text-align: right; 368 | vertical-align: top; 369 | white-space: nowrap; 370 | } 371 | /* color for capabilities, inherited by nobody */ 372 | span.ueditInheritNobody { 373 | color: green; 374 | } 375 | /* color for capabilities, inherited by developer */ 376 | span.ueditInheritDeveloper { 377 | color: red; 378 | } 379 | /* color for capabilities, inherited by reader */ 380 | span.ueditInheritReader { 381 | color: black; 382 | } 383 | /* color for capabilities, inherited by anonymous */ 384 | span.ueditInheritAnonymous { 385 | color: blue; 386 | } 387 | /* format for capabilities, mentioned on the user edit page */ 388 | span.capability { 389 | font-weight: bold; 390 | } 391 | /* format for different user types, mentioned on the user edit page */ 392 | span.usertype { 393 | font-weight: bold; 394 | } 395 | /* leading text for user types, mentioned on the user edit page */ 396 | span.usertype:before { 397 | content:"'"; 398 | } 399 | /* trailing text for user types, mentioned on the user edit page */ 400 | span.usertype:after { 401 | content:"'"; 402 | } 403 | /* selected lines of text within a linenumbered artifact display */ 404 | div.selectedText { 405 | font-weight: bold; 406 | color: blue; 407 | background-color: #d5d5ff; 408 | border: 1px blue solid; 409 | } 410 | /* format for missing privileges note on user setup page */ 411 | p.missingPriv { 412 | color: blue; 413 | } 414 | /* format for leading text in wikirules definitions */ 415 | span.wikiruleHead { 416 | font-weight: bold; 417 | } 418 | /* format for labels on ticket display page */ 419 | td.tktDspLabel { 420 | text-align: right; 421 | } 422 | /* format for values on ticket display page */ 423 | td.tktDspValue { 424 | text-align: left; 425 | vertical-align: top; 426 | background-color: #d0d0d0; 427 | } 428 | /* format for ticket error messages */ 429 | span.tktError { 430 | color: red; 431 | font-weight: bold; 432 | } 433 | /* format for example tables on the report edit page */ 434 | table.rpteditex { 435 | float: right; 436 | margin: 0; 437 | padding: 0; 438 | width: 125px; 439 | text-align: center; 440 | border-collapse: collapse; 441 | border-spacing: 0; 442 | } 443 | /* format for example table cells on the report edit page */ 444 | td.rpteditex { 445 | border-width: thin; 446 | border-color: #000000; 447 | border-style: solid; 448 | } 449 | /* format for user color input on checkin edit page */ 450 | input.checkinUserColor { 451 | /* no special definitions, class defined, to enable color pickers, f.e.: 452 | ** add the color picker found at http:jscolor.com as java script include 453 | ** to the header and configure the java script file with 454 | ** 1. use as bindClass :checkinUserColor 455 | ** 2. change the default hash adding behaviour to ON 456 | ** or change the class defition of element identified by id="clrcust" 457 | ** to a standard jscolor definition with java script in the footer. */ 458 | } 459 | /* format for end of content area, to be used to clear page flow(sidebox on branch,.. */ 460 | div.endContent { 461 | clear: both; 462 | } 463 | /* format for general errors */ 464 | p.generalError { 465 | color: red; 466 | } 467 | /* format for tktsetup errors */ 468 | p.tktsetupError { 469 | color: red; 470 | font-weight: bold; 471 | } 472 | /* format for xfersetup errors */ 473 | p.xfersetupError { 474 | color: red; 475 | font-weight: bold; 476 | } 477 | /* format for th script errors */ 478 | p.thmainError { 479 | color: red; 480 | font-weight: bold; 481 | } 482 | /* format for th script trace messages */ 483 | span.thTrace { 484 | color: red; 485 | } 486 | /* format for report configuration errors */ 487 | p.reportError { 488 | color: red; 489 | font-weight: bold; 490 | } 491 | /* format for report configuration errors */ 492 | blockquote.reportError { 493 | color: red; 494 | font-weight: bold; 495 | } 496 | /* format for artifact lines, no longer shunned */ 497 | p.noMoreShun { 498 | color: blue; 499 | } 500 | /* format for artifact lines beeing shunned */ 501 | p.shunned { 502 | color: blue; 503 | } 504 | /* a broken hyperlink */ 505 | span.brokenlink { 506 | color: red; 507 | } 508 | /* List of files in a timeline */ 509 | ul.filelist { 510 | margin-top: 3px; 511 | line-height: 100%; 512 | } 513 | /* side-by-side diff display */ 514 | div.sbsdiff { 515 | font-family: monospace; 516 | font-size: smaller; 517 | white-space: pre; 518 | } 519 | /* context diff display */ 520 | div.udiff { 521 | font-family: monospace; 522 | white-space: pre; 523 | } 524 | /* changes in a diff */ 525 | span.diffchng { 526 | background-color: #c0c0ff; 527 | } 528 | /* added code in a diff */ 529 | span.diffadd { 530 | background-color: #c0ffc0; 531 | } 532 | /* deleted in a diff */ 533 | span.diffrm { 534 | background-color: #ffc8c8; 535 | } 536 | /* suppressed lines in a diff */ 537 | span.diffhr { 538 | color: #0000ff; 539 | } 540 | /* line numbers in a diff */ 541 | span.diffln { 542 | color: #a0a0a0; 543 | } 544 | /* Moderation Pending message on timeline */ 545 | span.modpending { 546 | color: #b03800; 547 | font-style: italic; 548 | } 549 | -------------------------------------------------------------------------------- /Wub.tcl: -------------------------------------------------------------------------------- 1 | ##***************************************************************************## 2 | ## ## 3 | ## This is a stub and needs to be filled in!!!! ## 4 | ## ## 5 | ##***************************************************************************## 6 | 7 | ############################################################################### 8 | ## ## 9 | ## Copyright (c) 2008, Gerald W. Lester ## 10 | ## All rights reserved. ## 11 | ## ## 12 | ## Redistribution and use in source and binary forms, with or without ## 13 | ## modification, are permitted provided that the following conditions ## 14 | ## are met: ## 15 | ## ## 16 | ## * Redistributions of source code must retain the above copyright ## 17 | ## notice, this list of conditions and the following disclaimer. ## 18 | ## * Redistributions in binary form must reproduce the above ## 19 | ## copyright notice, this list of conditions and the following ## 20 | ## disclaimer in the documentation and/or other materials provided ## 21 | ## with the distribution. ## 22 | ## * Neither the name of the Visiprise Software, Inc nor the names ## 23 | ## of its contributors may be used to endorse or promote products ## 24 | ## derived from this software without specific prior written ## 25 | ## permission. ## 26 | ## ## 27 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## 28 | ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## 29 | ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ## 30 | ## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ## 31 | ## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ## 32 | ## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ## 33 | ## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ## 34 | ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ## 35 | ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ## 36 | ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## 37 | ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## 38 | ## POSSIBILITY OF SUCH DAMAGE. ## 39 | ## ## 40 | ############################################################################### 41 | 42 | package require Tcl 8.4- 43 | # WS::Utils usable here for dict? 44 | if {![llength [info command dict]]} { 45 | package require dict 46 | } 47 | package require uri 48 | package require base64 49 | package require html 50 | 51 | package provide WS::Wub 2.5.0 52 | 53 | namespace eval ::WS::Wub { 54 | 55 | array set portInfo {} 56 | 57 | set portList [list] 58 | set forever {} 59 | } 60 | 61 | 62 | ########################################################################### 63 | # 64 | # Public Procedure Header - as this procedure is modified, please be sure 65 | # that you update this header block. Thanks. 66 | # 67 | #>>BEGIN PUBLIC<< 68 | # 69 | # Procedure Name : ::WS::Wub::AddHandler 70 | # 71 | # Description : Register a handler for a url on a port. 72 | # 73 | # Arguments : 74 | # port -- The port to register the callback on 75 | # url -- The URL to register the callback for 76 | # callback -- The callback prefix, two additionally arguments are lappended 77 | # the callback: (1) the socket (2) the null string 78 | # 79 | # Returns : Nothing 80 | # 81 | # Side-Effects : 82 | # None 83 | # 84 | # Exception Conditions : None 85 | # 86 | # Pre-requisite Conditions : ::WS::Wub::Listen must have been called for the port 87 | # 88 | # Original Author : Gerald W. Lester 89 | # 90 | #>>END PUBLIC<< 91 | # 92 | # Maintenance History - as this file is modified, please be sure that you 93 | # update this segment of the file header block by 94 | # adding a complete entry at the bottom of the list. 95 | # 96 | # Version Date Programmer Comments / Changes / Reasons 97 | # ------- ---------- ---------- ------------------------------------------- 98 | # 1 03/28/2008 G.Lester Initial version 99 | # 100 | # 101 | ########################################################################### 102 | proc ::WS::Wub::AddHandler {port url callback} { 103 | variable portInfo 104 | 105 | dict set portInfo($port,handlers) $url $callback 106 | return; 107 | } 108 | 109 | 110 | ########################################################################### 111 | # 112 | # Public Procedure Header - as this procedure is modified, please be sure 113 | # that you update this header block. Thanks. 114 | # 115 | #>>BEGIN PUBLIC<< 116 | # 117 | # Procedure Name : ::WS::Wub::AddHandlerAllPorts 118 | # 119 | # Description : Register a handler for a url on all "defined" ports. 120 | # 121 | # Arguments : 122 | # url -- List of three elements: 123 | # callback -- The callback prefix, two additionally argumens are lappended 124 | # the callback: (1) the socket (2) the null string 125 | # 126 | # Returns : Nothing 127 | # 128 | # Side-Effects : 129 | # None 130 | # 131 | # Exception Conditions : None 132 | # 133 | # Pre-requisite Conditions : ::WS::Wub::Listen must have been called for the port 134 | # 135 | # Original Author : Gerald W. Lester 136 | # 137 | #>>END PUBLIC<< 138 | # 139 | # Maintenance History - as this file is modified, please be sure that you 140 | # update this segment of the file header block by 141 | # adding a complete entry at the bottom of the list. 142 | # 143 | # Version Date Programmer Comments / Changes / Reasons 144 | # ------- ---------- ---------- ------------------------------------------- 145 | # 1 03/28/2008 G.Lester Initial version 146 | # 147 | # 148 | ########################################################################### 149 | proc ::WS::Wub::AddHandlerAllPorts {url callback} { 150 | variable portList 151 | 152 | foreach port $portList { 153 | AddHandler $port $url $callback 154 | } 155 | 156 | return; 157 | } 158 | 159 | 160 | ########################################################################### 161 | # 162 | # Public Procedure Header - as this procedure is modified, please be sure 163 | # that you update this header block. Thanks. 164 | # 165 | #>>BEGIN PUBLIC<< 166 | # 167 | # Procedure Name : ::WS::Wub::Listen 168 | # 169 | # Description : Instruct the module to listen on a Port, security information. 170 | # 171 | # Arguments : 172 | # port -- Port number to listen on 173 | # certfile -- Name of the certificate file 174 | # keyfile -- Name of the key file 175 | # userpwds -- A list of username and passwords 176 | # realm -- The security realm 177 | # logger -- A logging routines for errors 178 | # 179 | # Returns : Nothing 180 | # 181 | # Side-Effects : 182 | # None 183 | # 184 | # Exception Conditions : None 185 | # 186 | # Pre-requisite Conditions : ::WS::Wub::Listen must have been called for the port 187 | # 188 | # Original Author : Gerald W. Lester 189 | # 190 | #>>END PUBLIC<< 191 | # 192 | # Maintenance History - as this file is modified, please be sure that you 193 | # update this segment of the file header block by 194 | # adding a complete entry at the bottom of the list. 195 | # 196 | # Version Date Programmer Comments / Changes / Reasons 197 | # ------- ---------- ---------- ------------------------------------------- 198 | # 1 03/28/2008 G.Lester Initial version 199 | # 200 | # 201 | ########################################################################### 202 | proc ::WS::Wub::Listen {port {certfile {}} {keyfile {}} {userpwds {}} {realm {}} {logger {::WS::Wub::logger}}} { 203 | variable portInfo 204 | variable portList 205 | 206 | lappend portList $port 207 | foreach key {port certfile keyfile userpwds realm logger} { 208 | set portInfo($port,$key) [set $key] 209 | } 210 | set portInfo($port,$handlers) {} 211 | foreach up $userpwds { 212 | lappend portInfo($port,auths) [base64::encode $up] 213 | } 214 | 215 | if {$certfile ne ""} { 216 | package require tls 217 | 218 | ::tls::init \ 219 | -certfile $certfile \ 220 | -keyfile $keyfile \ 221 | -ssl2 1 \ 222 | -ssl3 1 \ 223 | -tls1 0 \ 224 | -require 0 \ 225 | -request 0 226 | ::tls::socket -server [list ::WS::Wub::accept $port] $port 227 | } else { 228 | socket -server [list ::WS::Wub::accept $port] $port 229 | } 230 | } 231 | 232 | 233 | ########################################################################### 234 | # 235 | # Public Procedure Header - as this procedure is modified, please be sure 236 | # that you update this header block. Thanks. 237 | # 238 | #>>BEGIN PUBLIC<< 239 | # 240 | # Procedure Name : ::WS::Wub::ReturnData 241 | # 242 | # Description : Store the information to be returned. 243 | # 244 | # Arguments : 245 | # socket -- Socket data is for 246 | # type -- Mime type of data 247 | # data -- Data 248 | # code -- Status code 249 | # 250 | # Returns : Nothing 251 | # 252 | # Side-Effects : 253 | # None 254 | # 255 | # Exception Conditions : None 256 | # 257 | # Pre-requisite Conditions : A callback on the socket should be pending 258 | # 259 | # Original Author : Gerald W. Lester 260 | # 261 | #>>END PUBLIC<< 262 | # 263 | # Maintenance History - as this file is modified, please be sure that you 264 | # update this segment of the file header block by 265 | # adding a complete entry at the bottom of the list. 266 | # 267 | # Version Date Programmer Comments / Changes / Reasons 268 | # ------- ---------- ---------- ------------------------------------------- 269 | # 1 03/28/2008 G.Lester Initial version 270 | # 271 | # 272 | ########################################################################### 273 | proc ::WS::Wub::ReturnData {socket type data code} { 274 | upvar #0 ::WS::Wub::Httpd$sock data 275 | 276 | foreach var {type data code} { 277 | dict set $data(reply) $var [set $var] 278 | } 279 | return; 280 | } 281 | 282 | 283 | ########################################################################### 284 | # 285 | # Public Procedure Header - as this procedure is modified, please be sure 286 | # that you update this header block. Thanks. 287 | # 288 | #>>BEGIN PUBLIC<< 289 | # 290 | # Procedure Name : ::WS::Wub::Start 291 | # 292 | # Description : Start listening on all ports (i.e. enter the event loop). 293 | # 294 | # Arguments : None 295 | # 296 | # Returns : Value that event loop was exited with. 297 | # 298 | # Side-Effects : 299 | # None 300 | # 301 | # Exception Conditions : None 302 | # 303 | # Pre-requisite Conditions : 304 | # ::WS::Wub::Listen should have been called for one or more port. 305 | # 306 | # 307 | # Original Author : Gerald W. Lester 308 | # 309 | #>>END PUBLIC<< 310 | # 311 | # Maintenance History - as this file is modified, please be sure that you 312 | # update this segment of the file header block by 313 | # adding a complete entry at the bottom of the list. 314 | # 315 | # Version Date Programmer Comments / Changes / Reasons 316 | # ------- ---------- ---------- ------------------------------------------- 317 | # 1 03/28/2008 G.Lester Initial version 318 | # 319 | # 320 | ########################################################################### 321 | proc ::WS::Wub::Start {} { 322 | vairable forever 323 | 324 | set forever 0 325 | vwait ::WS::Wub::forever 326 | return $forever 327 | } 328 | 329 | 330 | ########################################################################### 331 | # 332 | # Public Procedure Header - as this procedure is modified, please be sure 333 | # that you update this header block. Thanks. 334 | # 335 | #>>BEGIN PUBLIC<< 336 | # 337 | # Procedure Name : ::WS::Wub::Stop 338 | # 339 | # Description : Exit dispatching request. 340 | # 341 | # Arguments : 342 | # value -- Value that ::WS::Embedded::Start should return, 343 | # 344 | # Returns : Nothing 345 | # 346 | # Side-Effects : 347 | # None 348 | # 349 | # Exception Conditions : None 350 | # 351 | # Pre-requisite Conditions : None 352 | # 353 | # Original Author : Gerald W. Lester 354 | # 355 | #>>END PUBLIC<< 356 | # 357 | # Maintenance History - as this file is modified, please be sure that you 358 | # update this segment of the file header block by 359 | # adding a complete entry at the bottom of the list. 360 | # 361 | # Version Date Programmer Comments / Changes / Reasons 362 | # ------- ---------- ---------- ------------------------------------------- 363 | # 1 03/28/2008 G.Lester Initial version 364 | # 365 | # 366 | ########################################################################### 367 | proc ::WS::Wub::Stop {{value 1}} { 368 | vairable forever 369 | 370 | set forever $value 371 | vwait ::WS::Wub::forever 372 | return $forever 373 | } 374 | 375 | 376 | ########################################################################### 377 | # 378 | # Private Procedure Header - as this procedure is modified, please be sure 379 | # that you update this header block. Thanks. 380 | # 381 | #>>BEGIN PRIVATE<< 382 | # 383 | # Procedure Name : ::WS::Wub::logger 384 | # 385 | # Description : Stub for a logger. 386 | # 387 | # Arguments : 388 | # args - not used 389 | # 390 | # Returns : 391 | # Nothing 392 | # 393 | # Side-Effects : None 394 | # 395 | # Exception Conditions : None 396 | # 397 | # Pre-requisite Conditions : None 398 | # 399 | # Original Author : Gerald W. Lester 400 | # 401 | #>>END PRIVATE<< 402 | # 403 | # Maintenance History - as this file is modified, please be sure that you 404 | # update this segment of the file header block by 405 | # adding a complete entry at the bottom of the list. 406 | # 407 | # Version Date Programmer Comments / Changes / Reasons 408 | # ------- ---------- ---------- ------------------------------------------- 409 | # 1 03/28/2008 G.Lester Initial version 410 | # 411 | # 412 | ########################################################################### 413 | proc ::WS::Wub::logger {args} { 414 | } 415 | 416 | 417 | ########################################################################### 418 | # 419 | # Private Procedure Header - as this procedure is modified, please be sure 420 | # that you update this header block. Thanks. 421 | # 422 | #>>BEGIN PRIVATE<< 423 | # 424 | # Procedure Name : ::WS::Wub::respond 425 | # 426 | # Description : Send response back to user. 427 | # 428 | # Arguments : 429 | # sock -- Socket to send reply on 430 | # code -- Code to send 431 | # body -- HTML body to send 432 | # head -- HTML header to send 433 | # 434 | # Returns : 435 | # Nothing 436 | # 437 | # Side-Effects : None 438 | # 439 | # Exception Conditions : None 440 | # 441 | # Pre-requisite Conditions : None 442 | # 443 | # Original Author : Gerald W. Lester 444 | # 445 | #>>END PRIVATE<< 446 | # 447 | # Maintenance History - as this file is modified, please be sure that you 448 | # update this segment of the file header block by 449 | # adding a complete entry at the bottom of the list. 450 | # 451 | # Version Date Programmer Comments / Changes / Reasons 452 | # ------- ---------- ---------- ------------------------------------------- 453 | # 1 03/28/2008 G.Lester Initial version 454 | # 455 | # 456 | ########################################################################### 457 | proc ::WS::Wub::respond {sock code body {head ""}} { 458 | puts -nonewline $sock "HTTP/1.0 $code ???\nContent-Type: text/html; charset=ISO-8859-1\nConnection: close\nContent-length: [string length $body]\n$head\n$body" 459 | } 460 | 461 | 462 | ########################################################################### 463 | # 464 | # Private Procedure Header - as this procedure is modified, please be sure 465 | # that you update this header block. Thanks. 466 | # 467 | #>>BEGIN PRIVATE<< 468 | # 469 | # Procedure Name : ::WS::Wub::checkauth 470 | # 471 | # Description : Check to see if the user is allowed. 472 | # 473 | # Arguments : 474 | # port -- Port number 475 | # sock -- Incoming socket 476 | # ip -- Requester's IP address 477 | # auth -- Authentication information 478 | # 479 | # Returns : 480 | # Nothing 481 | # 482 | # Side-Effects : None 483 | # 484 | # Exception Conditions : None 485 | # 486 | # Pre-requisite Conditions : None 487 | # 488 | # Original Author : Gerald W. Lester 489 | # 490 | #>>END PRIVATE<< 491 | # 492 | # Maintenance History - as this file is modified, please be sure that you 493 | # update this segment of the file header block by 494 | # adding a complete entry at the bottom of the list. 495 | # 496 | # Version Date Programmer Comments / Changes / Reasons 497 | # ------- ---------- ---------- ------------------------------------------- 498 | # 1 03/28/2008 G.Lester Initial version 499 | # 500 | # 501 | ########################################################################### 502 | proc ::WS::Wub::checkauth {port sock ip auth} { 503 | variable portInfo 504 | 505 | if {[llength portInfo($port,auths)] && [lsearch -exact $portInfo($port,auths) $auth]==-1} { 506 | set realm $portInfo($port,realm) 507 | respond $sock 401 Unauthorized "WWW-Authenticate: Basic realm=\"$realm\"\n" 508 | $portInfo($port,logger) "Unauthorized from $ip" 509 | return -code error 510 | } 511 | } 512 | 513 | 514 | ########################################################################### 515 | # 516 | # Private Procedure Header - as this procedure is modified, please be sure 517 | # that you update this header block. Thanks. 518 | # 519 | #>>BEGIN PRIVATE<< 520 | # 521 | # Procedure Name : ::WS::Wub::handler 522 | # 523 | # Description : Handle a request. 524 | # 525 | # Arguments : 526 | # port -- Port number 527 | # sock -- Incoming socket 528 | # ip -- Requester's IP address 529 | # reqstring -- Requester's message 530 | # auth -- Authentication information 531 | # 532 | # Returns : 533 | # Nothing 534 | # 535 | # Side-Effects : None 536 | # 537 | # Exception Conditions : None 538 | # 539 | # Pre-requisite Conditions : None 540 | # 541 | # Original Author : Gerald W. Lester 542 | # 543 | #>>END PRIVATE<< 544 | # 545 | # Maintenance History - as this file is modified, please be sure that you 546 | # update this segment of the file header block by 547 | # adding a complete entry at the bottom of the list. 548 | # 549 | # Version Date Programmer Comments / Changes / Reasons 550 | # ------- ---------- ---------- ------------------------------------------- 551 | # 1 03/28/2008 G.Lester Initial version 552 | # 553 | # 554 | ########################################################################### 555 | proc ::WS::Wub::handler {port sock ip reqstring auth} { 556 | variable portInfo 557 | upvar #0 ::WS::Wub::Httpd$sock req 558 | 559 | if {[catch {checkauth $port $sock $ip $auth}]} { 560 | return; 561 | } 562 | 563 | array set req $reqstring 564 | foreach var {type data code} { 565 | dict set $req(reply) $var [set $var] 566 | } 567 | set path $req(path) 568 | if {[dict exists $portInfo($port,handlers) $path]} { 569 | set cmd [dict get $portInfo($port,handlers) $path] 570 | lappend $cmd sock {} 571 | } else { 572 | respond $port $sock 404 "Error" 573 | } 574 | if {[catch {eval $cmd} msg]} { 575 | respond $port $sock 404 $msg 576 | } else { 577 | set data [dict get $req(reply) data] 578 | set reply "HTTP/1.0 [dict get $req(reply) code] ???\n" 579 | append reply "Content-Type: [dict get $req(reply) type]; charset=UTF-8\n" 580 | append reply "Connection: close\n" 581 | append reply "Content-length: [string length $data]\n" 582 | append reply "\n" 583 | append reply $data 584 | puts -nonewline $sock $reply 585 | } 586 | 587 | return; 588 | } 589 | 590 | 591 | ########################################################################### 592 | # 593 | # Private Procedure Header - as this procedure is modified, please be sure 594 | # that you update this header block. Thanks. 595 | # 596 | #>>BEGIN PRIVATE<< 597 | # 598 | # Procedure Name : ::WS::Wub::accept 599 | # 600 | # Description : Accept an incoming connection. 601 | # 602 | # Arguments : 603 | # port -- Port number 604 | # sock -- Incoming socket 605 | # ip -- Requester's IP address 606 | # clientport -- Requester's port number 607 | # 608 | # Returns : 609 | # Nothing 610 | # 611 | # Side-Effects : None 612 | # 613 | # Exception Conditions : None 614 | # 615 | # Pre-requisite Conditions : None 616 | # 617 | # Original Author : Gerald W. Lester 618 | # 619 | #>>END PRIVATE<< 620 | # 621 | # Maintenance History - as this file is modified, please be sure that you 622 | # update this segment of the file header block by 623 | # adding a complete entry at the bottom of the list. 624 | # 625 | # Version Date Programmer Comments / Changes / Reasons 626 | # ------- ---------- ---------- ------------------------------------------- 627 | # 1 03/28/2008 G.Lester Initial version 628 | # 629 | # 630 | ########################################################################### 631 | proc ::WS::Wub::accept {port sock ip clientport} { 632 | variable portInfo 633 | 634 | if {[catch { 635 | gets $sock line 636 | set auth "" 637 | for {set c 0} {[gets $sock temp]>=0 && $temp ne "\r" && $temp ne ""} {incr c} { 638 | regexp {Authorization: Basic ([^\r\n]+)} $temp -- auth 639 | if {$c == 30} { 640 | $portInfo($port,logger) "Too many lines from $ip" 641 | } 642 | } 643 | if {[eof $sock]} { 644 | $portInfo($port,logger) "Connection closed from $ip" 645 | } 646 | foreach {method url version} $line { break } 647 | switch -exact $method { 648 | GET { 649 | handler $port $sock $ip [uri::split $url] $auth 650 | } 651 | default { 652 | $portInfo($port,logger) "Unsupported method '$method' from $ip" 653 | } 654 | } } msg]} { 655 | $portInfo($port,logger) "Error: $msg" 656 | } 657 | 658 | catch {flush $sock} 659 | catch {close $sock} 660 | return; 661 | } 662 | --------------------------------------------------------------------------------