Tcl Requires Chilkat v11.0.0+
Tcl
Xero API through an SOCKS Proxy
This example demonstrates connecting through a SOCKS proxy w/ 2-legged OAuth for a Xero private application.Chilkat Tcl Downloads
load ./chilkat.dll
set success 0
# This sample code would typically be placed in a subroutine or function
# where the rest object is passed by reference.
# It does the OAuth1 setup and makes the initial connection.
set rest [new_CkRest]
# Connect to the Xero server through an HTTP proxy, and then tell the REST object
# to use the socket connection.
set socket [new_CkSocket]
# Set the SOCKS proxy domain or IP address, port, and SOCKS version number (4 or 5)
CkSocket_put_SocksHostname $socket "192.168.1.100"
CkSocket_put_SocksPort $socket 1080
CkSocket_put_SocksVersion $socket 5
# Other properties exist for specifying a SOCKS proxy login and password,
# but these are not used in this example.
# Connect through the SOCKS proxy..
set bTls 1
set port 443
set maxWaitMs 5000
set success [CkSocket_Connect $socket "api.xero.com" $port $bTls $maxWaitMs]
if {$success != 1} then {
puts "Connect Failure Error Code: [CkSocket_get_ConnectFailReason $socket]"
puts [CkSocket_lastErrorText $socket]
delete_CkRest $rest
delete_CkSocket $socket
exit
}
# Use the SOCKS proxied TLS connection:
set success [CkRest_UseConnection $rest $socket 1]
if {$success == 0} then {
puts [CkRest_lastErrorText $rest]
delete_CkRest $rest
delete_CkSocket $socket
exit
}
# OK, we're connected.
# The UseConnection method has an internal reference to the underlying/internal socket.
# The application can does not need to keep its socket object in existence.
# -----------------------------------------------------------------
# Now setup the OAuth1 authenticator..
set consumerKey "XERO_PRIVATE_APP_KEY"
set consumerSecret "XERO_PRIVATE_APP_SECRET"
# Let's get our private key from our PFX (password protected), or the PEM (unprotected).
# You can decide which to use. Either is OK, although I would recommend keeping your
# private keys in a PFX and not in an unprotected PEM.
set pfx [new_CkPfx]
set success [CkPfx_LoadPfxFile $pfx "qa_data/certs/xero_private_app/public_privatekey.pfx" "PFX_PASSWORD"]
if {$success == 0} then {
puts [CkPfx_lastErrorText $pfx]
delete_CkRest $rest
delete_CkSocket $socket
delete_CkPfx $pfx
exit
}
set privKeyFromPfx [new_CkPrivateKey]
set success [CkPfx_PrivateKeyAt $pfx 0 $privKeyFromPfx]
if {$success == 0} then {
puts [CkPfx_lastErrorText $pfx]
delete_CkRest $rest
delete_CkSocket $socket
delete_CkPfx $pfx
delete_CkPrivateKey $privKeyFromPfx
exit
}
# Or we can load from a PEM..
set privKeyFromPem [new_CkPrivateKey]
set success [CkPrivateKey_LoadPemFile $privKeyFromPem "qa_data/certs/xero_private_app/privatekey.pem"]
if {$success == 0} then {
puts [CkPrivateKey_lastErrorText $privKeyFromPem]
delete_CkRest $rest
delete_CkSocket $socket
delete_CkPfx $pfx
delete_CkPrivateKey $privKeyFromPfx
delete_CkPrivateKey $privKeyFromPem
exit
}
# Note: There are many other means for loading a private key, including
# from other formats and directly from memory (i.e. not file-based).
set oauth1 [new_CkOAuth1]
CkOAuth1_put_ConsumerKey $oauth1 $consumerKey
CkOAuth1_put_ConsumerSecret $oauth1 $consumerSecret
CkOAuth1_put_Token $oauth1 $consumerKey
CkOAuth1_put_TokenSecret $oauth1 $consumerSecret
CkOAuth1_put_SignatureMethod $oauth1 "RSA-SHA1"
CkOAuth1_SetRsaKey $oauth1 $privKeyFromPfx
# Install the OAuth1 authenticator.
CkRest_SetAuthOAuth1 $rest $oauth1 0
puts "OK, the Xero OAuth1 is initialized and the REST object is ready to make REST API calls.."
# -----------------------------------------------------------------
# Make a call to verify that OAuth1 through an HTTP proxy works..
# Get the full list of contacts.
set sbXml [new_CkStringBuilder]
set success [CkRest_FullRequestNoBodySb $rest "GET" "/api.xro/2.0/Contacts" $sbXml]
if {$success == 0} then {
puts [CkRest_lastErrorText $rest]
delete_CkRest $rest
delete_CkSocket $socket
delete_CkPfx $pfx
delete_CkPrivateKey $privKeyFromPfx
delete_CkPrivateKey $privKeyFromPem
delete_CkOAuth1 $oauth1
delete_CkStringBuilder $sbXml
exit
}
# A 200 response is expected for actual success.
if {[CkRest_get_ResponseStatusCode $rest] != 200} then {
puts [CkStringBuilder_getAsString $sbXml]
delete_CkRest $rest
delete_CkSocket $socket
delete_CkPfx $pfx
delete_CkPrivateKey $privKeyFromPfx
delete_CkPrivateKey $privKeyFromPem
delete_CkOAuth1 $oauth1
delete_CkStringBuilder $sbXml
exit
}
# Iterate over the contacts..
set bAutoTrim 0
set xml [new_CkXml]
CkXml_LoadSb $xml $sbXml $bAutoTrim
CkXml_SaveXml $xml "qa_cache/xero_contacts.xml"
# How many records exist?
set recordCount [CkXml_NumChildrenAt $xml "Contacts"]
puts "numRecords = $recordCount"
set i 0
while {$i < $recordCount} {
CkXml_put_I $xml $i
puts "ContactID: [CkXml_getChildContent $xml {Contacts|Contact[i]|ContactID}]"
set i [expr $i + 1]
}
delete_CkRest $rest
delete_CkSocket $socket
delete_CkPfx $pfx
delete_CkPrivateKey $privKeyFromPfx
delete_CkPrivateKey $privKeyFromPem
delete_CkOAuth1 $oauth1
delete_CkStringBuilder $sbXml
delete_CkXml $xml