Index: ClientSide.tcl ================================================================== --- ClientSide.tcl +++ ClientSide.tcl @@ -39,11 +39,11 @@ ## POSSIBILITY OF SUCH DAMAGE. ## ## ## ############################################################################### package require Tcl 8.4 -package require WS::Utils 2.3.7 ; # dict, lassign +package require WS::Utils 2.4 ; # dict, lassign package require tdom 0.8 package require http 2 package require log package require uri @@ -678,11 +678,11 @@ # #>>BEGIN PUBLIC<< # # Procedure Name : ::WS::Client::AddOutputHeader # -# Description : Import and additional namespace into the service +# Description : Import any additional namespace into the service # # Arguments : # serviceName - Service name to of the oepration # operation - name of operation to add an output header to # headerType - the type name to add as a header @@ -713,15 +713,15 @@ ########################################################################### proc ::WS::Client::AddOutputHeader {serviceName operation headerType} { variable serviceArr set serviceInfo $serviceArr($serviceName) - set soapReplyHeader [dict get $serviceInfo operation $operationName soapReplyHeader] + set soapReplyHeader [dict get $serviceInfo operation $operation soapReplyHeader] lappend soapReplyHeader $headerType - dict set serviceInfo operation $operationName soapReplyHeader $soapReplyHeader + dict set serviceInfo operation $operation soapReplyHeader $soapReplyHeader set serviceArr($serviceName) $serviceInfo - return ; + return } ########################################################################### @@ -1026,13 +1026,16 @@ if {$first > 0} { set wsdlXML [string range $wsdlXML $first end] } ::log::log debug "Parsing WSDL {$wsdlXML}" + # save parsed document node to tmpdoc dom parse $wsdlXML tmpdoc + # save transformed document handle in variable wsdlDoc $tmpdoc xslt $::WS::Utils::xsltSchemaDom wsdlDoc $tmpdoc delete + # save top node in variable wsdlNode $wsdlDoc documentElement wsdlNode set nsCount 1 set targetNs [$wsdlNode getAttribute targetNamespace] set ::WS::Utils::targetNs $targetNs dict set nsDict url $targetNs tns$nsCount @@ -1281,10 +1284,15 @@ return \ -code error \ -errorcode [list WS CLIENT UNKOPER [list $serviceName $operationName]] \ "Unknown operation '$operationName' for service '$serviceName'" } + + ## + ## build query + ## + set url [dict get $serviceInfo location] SaveAndSetOptions $serviceName if {[catch {set query [buildCallquery $serviceName $operationName $url $argList]} err]} { RestoreSavedOptions $serviceName return -code error -errorcode $::errorCode -errorinfo $::errorInfo $err @@ -1295,10 +1303,15 @@ set headers [concat $headers [dict get $serviceInfo headers]] } if {[dict exists $serviceInfo operation $operationName action]} { lappend headers SOAPAction [format {"%s"} [dict get $serviceInfo operation $operationName action]] } + + ## + ## do http call + ## + if {[llength $headers]} { ::log::log info [list ::http::geturl $url -query $query -type [dict get $serviceInfo contentType] -headers $headers] set token [::http::geturl $url -query $query -type [dict get $serviceInfo contentType] -headers $headers] } else { ::log::log info [::http::geturl $url -query $query -type [dict get $serviceInfo contentType]] @@ -1420,10 +1433,13 @@ set headers [concat $headers [dict get $serviceInfo headers]] } if {[dict exists $serviceInfo operation $operationName action]} { lappend headers SOAPAction [format {"%s"} [dict get $serviceInfo operation $operationName action]] } + ## + ## Do the http request + ## if {[llength $headers]} { ::log::log info [list ::http::geturl $url -query $query -type [dict get $serviceInfo contentType] -headers $headers] set token [::http::geturl $url -query $query -type [dict get $serviceInfo contentType] -headers $headers] } else { ::log::log info [list ::http::geturl $url -query $query -type [dict get $serviceInfo contentType] ] @@ -1974,11 +1990,13 @@ set first [string first {<} $inXML] if {$first > 0} { set inXML [string range $inXML $first end] } + # parse xml and save handle in variable doc dom parse $inXML doc + # save top node handle in variable top $doc documentElement top set xns { ENV http://schemas.xmlsoap.org/soap/envelope/ xsi "http://www.w3.org/2001/XMLSchema-instance" xs "http://www.w3.org/2001/XMLSchema" @@ -2000,12 +2018,12 @@ if {[llength $rootNode] > 1} { foreach tmp $rootNode { #puts "\t Got {[$tmp localName]} looking for {$expectedMsgTypeBase}" if {[$tmp localName] eq $expectedMsgTypeBase || [$tmp nodeName] eq $expectedMsgTypeBase || - [$tmp localName] eq Fault || - [$tmp nodeName] eq Fault} { + [$tmp localName] eq {Fault} || + [$tmp nodeName] eq {Fault}} { set rootNode $tmp break } } } @@ -2265,10 +2283,11 @@ set xns [dict get [::WS::Utils::GetServiceTypeDef Client $serviceName $inputHeaderType] xns] if {[info exists tnsArray($xns)]} { set xns $tnsArray($xns) } if {$firstHeader} { + # side effect: save new node handle in variable header $env appendChild [$doc createElement "SOAP-ENV:Header" header] set firstHeader 0 } if {[dict exists $serviceInfo skipHeaderLevel] && [dict get $serviceInfo skipHeaderLevel]} { set headerData $header @@ -2285,10 +2304,11 @@ } } ::WS::Utils::convertDictToType Client $serviceName $doc $headerData $argList $inputHeaderType } + # side effect: save new element handle in variable bod $env appendChild [$doc createElement "SOAP-ENV:Body" bod] #puts "set xns \[dict get \[::WS::Utils::GetServiceTypeDef Client $serviceName $msgType\] xns\]" #puts "\t [::WS::Utils::GetServiceTypeDef Client $serviceName $msgType]" set xns [dict get [::WS::Utils::GetServiceTypeDef Client $serviceName $msgType] xns] if {[info exists tnsArray($xns)]} { @@ -2397,10 +2417,11 @@ $env appendChild [$doc createElement "SOAP-ENV:Body" bod] set baseName [dict get $serviceInfo operation $operationName name] set callXns [dict get $serviceInfo operation $operationName xns] + # side effect: node handle is saved in variable reply if {![string is space $callXns]} { $bod appendChild [$doc createElement $callXns:$baseName reply] } else { $bod appendChild [$doc createElement $baseName reply] } @@ -2775,11 +2796,11 @@ if {!$options(allowOperOverloading)} { return -code error \ -errorcode [list WS CLIENT NOOVERLOAD $operName] } ## - ## See if the existing operation needs to be cloned" + ## See if the existing operation needs to be cloned ## set origType [lindex [split [dict get $serviceInfo operation $operName inputs] {:}] end] set newName ${operName}_${origType} if {![dict exists $serviceInfo operation $newName]} { ## @@ -2868,11 +2889,11 @@ lappend soapReplyHeaderList $type } dict set serviceInfo operation $operName soapReplyHeader $soapReplyHeaderList ## - ## Validate that the input and output uses + ## Validate that the input and output uses are the same ## set inUse $use set outUse $use catch {set inUse [[$oper selectNodes w:input/d:body] getAttribute use]} catch {set outUse [[$oper selectNodes w:output/d:body] getAttribute use]} @@ -3200,10 +3221,15 @@ return \ -code error \ -errorcode [list WS CLIENT UNKOPER [list $serviceName $objectName $operationName]] \ "Unknown operation '$operationName' for object '$objectName' of service '$serviceName'" } + + ## + ## build call query + ## + if {$location ne {}} { set url $location } else { set url [dict get $serviceInfo object $objectName location] } @@ -3215,10 +3241,15 @@ RestoreSavedOptions $serviceName } if {[dict exists $serviceInfo headers]} { set headers [concat $headers [dict get $serviceInfo headers]] } + + ## + ## do http call + ## + if {[llength $headers]} { ::log::log info [list ::http::geturl $url -query $query -type [dict get $serviceInfo contentType] -headers $headers] set token [::http::geturl $url -query $query -type [dict get $serviceInfo contentType] -headers $headers] } else { ::log::log [list ::http::geturl $url -query $query -type [dict get $serviceInfo contentType]] @@ -3330,17 +3361,26 @@ if {$location ne {}} { set url $location } else { set url [dict get $serviceInfo object $objectName location] } + + ## + ## build call query + ## + SaveAndSetOptions $serviceName if {[catch {set query [buildRestCallquery $serviceName $objectName $operationName $url $argList]} err]} { RestoreSavedOptions $serviceName return -code error -errorcode $::errorCode -errorinfo $::errorInfo $err - } else { - RestoreSavedOptions $serviceName } + RestoreSavedOptions $serviceName + + ## + ## Do http call + ## + if {[dict exists $serviceInfo headers]} { set headers [concat $headers [dict get $serviceInfo headers]] } if {[llength $headers]} { ::log::log info [list ::http::geturl $url -query $query -type [dict get $serviceInfo contentType] -headers $headers] @@ -3656,11 +3696,13 @@ set outTransform [dict get $serviceInfo outTransform] if {$outTransform ne {}} { set inXML [$outTransform $serviceName $operationName REPLY $inXML] } set expectedMsgType [dict get $serviceInfo object $objectName operation $operationName outputs] + # save parsed xml handle in variable doc dom parse $inXML doc + # save top node handle in variable top $doc documentElement top set xns {} foreach tmp [dict get $serviceInfo targetNamespace] { lappend xns $tmp } Index: Utilities.tcl ================================================================== --- Utilities.tcl +++ Utilities.tcl @@ -4744,11 +4744,11 @@ # # Arguments : # url - target document url # args - additional argument list to http::geturl call # -# Returns : nothing +# Returns : http package token of received data # # Side-Effects : Save final url in redirectArray to forward info to # procedure "processImport". # # Exception Conditions : None @@ -4880,18 +4880,18 @@ set args [lrange $args 2 end] } set token [eval ::WS::Utils::geturl_followRedirects $args] ::http::wait $token - if {[string equal [::http::status $token] ok]} { + if {[::http::status $token] eq {ok}} { if {[::http::size $token] == 0} { ::log::log debug "\tHTTP error: no data" ::http::cleanup $token return -errorcode [list WS CLIENT NODATA [lindex $args 0]]\ -code error "HTTP failure socket closed" } - if {![string equal $codeVar ""]} { + if {$codeVar ne ""} { upvar 1 $codeVar ncode } set ncode [::http::ncode $token] set body [::http::data $token] ::http::cleanup $token