XML Service Samples Rest
From Disney Common 2015 lab …
The following examples are https://
, demonstrating secure REST XMLSERVICE.
The modern languages featured below run on IBM i (new LPP OPS), but also run remote from laptop, cloud, etc.
Example languages demonstrates actual XML send to/from XMLSERVICE (no toolkits).
With this information, and, Google XML parsing in language, you can build your own https://
REST toolkits, in any language.
- XMLSERVICE REST Apache configuration (
https://
) - XMLSERVICE REST HTML/XML
- XMLSERVICE REST bash w/curl - bash xmlservice.sh
- XMLSERVICE REST php - php xmlservice.php
- XMLSERVICE REST python - python xmlservice.py
- XMLSERVICE REST node.js - node xmlservice.js
- XMLSERVICE REST ruby - ruby xmlservice.rb
- XMLSERVICE REST java - java xmlservice
- Note: Examples are copied from Common 2015 lab. IF Common “frankeni” machine happens to be running, and someone not break the master examples (hint), you can use this secure link to run examples live https://common1.frankeni.com:47700/ (click on command line picture of language to run).
XMLSERVICE REST Apache configuration (https://
)
The Common 2015 lab features simple PASE CGI xmlservice calls. This is not the fastest method, but it demonstrates both command line and PASE CGI as one-and-the-same. Most of these languages provide built-in web servers, usually simple proxy/reverse-proxy to Apache. However, most languages can also be configured to run with Apache as CGI and FastCGI.
- /QOpenSys/xmlservice/bash-cgi
#!/QOpenSys/opt/freeware/bin/bash export PASSWORD=(see instructor) mydir=$(dirname $PATH_TRANSLATED) cd $mydir myscript=$(basename $PATH_TRANSLATED) if [[ $myscript == *".py"* ]] then result=$(/QOpenSys/opt/freeware/bin/python $myscript) elif [[ $myscript == *".php"* ]] then result=$(env) elif [[ $myscript == *".rb"* ]] then result=$(/QOpenSys/usr/bin/ruby $myscript) elif [[ $myscript == *".js"* ]] then result=$(/usr/bin/node $myscript) elif [[ $myscript == *".sh"* ]] then result=$(exec $myscript) elif [[ $myscript == *".java"* ]] then myscript=$(basename $PATH_TRANSLATED | awk '{ gsub(/.java/,""); print }') result=$(/QOpenSys/usr/bin/java $myscript) else result="<html><body>unsupported type ($myscript)</body></html>" fi if [[ $result == *"<html>"* ]] then printf "Content-Type: text/html\n\n" else printf "Content-Type: text/xml\n\n" fi echo $result #echo '<pre>' #env #echo '</pre>'
- /www/xmlservice/conf/fastcgi.conf (for PHP only)
; Static PHP servers for default user Server type="application/x-httpd-php" CommandLine="/usr/local/zendsvr6/bin/php-cgi.bin" StartProcesses="1" SetEnv="LIBPATH=/usr/local/zendsvr6/lib" SetEnv="PHPRC=/home/xml/etc" SetEnv="PHP_FCGI_CHILDREN=10" SetEnv="PHP_FCGI_MAX_REQUESTS=0" ConnectionTimeout="30" RequestTimeout="60" SetEnv="CCSID=1208" SetEnv="LANG=C" SetEnv="INSTALLATION_UID=100313092601" SetEnv="LDR_CNTRL=MAXDATA=0x40000000" SetEnv="ZEND_TMPDIR=/usr/local/zendsvr6/tmp" SetEnv="TZ=<EST>5<EDT>,M3.2.0,M11.1.0" SetEnv="PASSWORD=NICE2XML" ; Where to place socket files IpcDir /www/xmlservice/logs
- /www/xmlservice/conf/httpd.conf
# Apache Default server configuration LoadModule ibm_ssl_module /QSYS.LIB/QHTTPSVR.LIB/QZSRVSSL.SRVPGM LoadModule proxy_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM LoadModule proxy_http_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM LoadModule proxy_connect_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM LoadModule proxy_ftp_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM LoadModule proxy_balancer_module /QSYS.LIB/QHTTPSVR.LIB/QZSRCORE.SRVPGM LoadModule zend_enabler_module /QSYS.LIB/QHTTPSVR.LIB/QZFAST.SRVPGM ProxyPreserveHost On # General setup directives HotBackup Off TimeOut 30000 KeepAlive Off AddLanguage en .en DefaultFsCCSID 37 CGIJobCCSID 37 # Listen *:58700 Listen *:47700 # keep logs 7 days LogMaint logs/access_log 7 0 LogMaint logs/error_log 7 0 LogMaint logs/error_zfcgi 7 0 DocumentRoot /www/xmlservice/htdocs NameVirtualHost *:47700 <VirtualHost *:47700> # SSLAppName QIBM_HTTP_SERVER_STD77 SSLAppName QIBM_HTTP_SERVER_XMLSERVICE SSLCacheEnable SSLEngine On SSLClientAuth None SetEnv HTTPS_PORT 47700 </VirtualHost> <Directory /> order allow,deny deny from all Options -Indexes -ExecCGI -includes AllowOverride All </Directory> # Allow requests for files in document root <Directory /www/xmlservice/htdocs> order allow,deny allow from all </Directory> <Directory /www/xmlservice/htdocs/zip> Options +Indexes order allow,deny allow from all </Directory> ScriptAlias /cgi-bin/ /QSYS.LIB/XMLSERVICE.LIB/ <Directory /QSYS.LIB/XMLSERVICE.LIB/> order allow,deny allow from all SetHandler cgi-script Options +ExecCGI </Directory> # pase CGI # cd /QOpenSys # ln -sf /home/xml xml # cd /www/xmlservice/htdocs # ln -sf /home/xml xml ScriptAlias /pase-bin/ /QOpenSys/xmlservice/ AddType application/x-httpd-python .py Action application/x-httpd-python /pase-bin/bash-cgi # AddType application/x-httpd-php .php # Action application/x-httpd-php /pase-bin/bash-cgi AddType application/x-httpd-ruby .rb Action application/x-httpd-ruby /pase-bin/bash-cgi AddType application/x-httpd-node .js Action application/x-httpd-node /pase-bin/bash-cgi AddType application/x-httpd-java .java Action application/x-httpd-java /pase-bin/bash-cgi AddType application/x-httpd-sh .sh Action application/x-httpd-sh /pase-bin/bash-cgi <Directory /QOpenSys/xmlservice> Options +ExecCGI order allow,deny allow from all </Directory> # zend fastcgi AddType application/x-httpd-php .php AddHandler fastcgi-script .php
XMLSERVICE REST HTML/XML
<html> <body> <h1>Secure call XMLSERVICE please</h1> <form id="myForm" name="myForm" action="https://common1.frankeni.com:47700/cgi-bin/xmlcgi.pgm" method="post"> <input type="hidden" name="db2" value="*LOCAL"> <br>User: <input type="input" name="uid" value=""> (see instructor) <br>Password: <input type="password" name="pwd" value=""> <input type="hidden" name="ipc" value="*na"> <input type="hidden" name="ctl" value="*here"> <br>XML Input: <br><textarea readonly name="xmlin" rows="20" cols="100"><?xml version='1.0'?> <xmlservice> <cmd>CHGLIBL LIBL(XMLSERVICE) CURLIB(XMLSERVICE)</cmd> <pgm name='ZZCALL'> <parm><data type='1A'>a</data></parm> <parm><data type='1A'>b</data></parm> <parm><data type='7p4'>11.1111</data></parm> <parm><data type='12p2'>222.22</data></parm> <parm> <ds> <data type='1A'>x</data> <data type='1A'>y</data> <data type='7p4'>66.6666</data> <data type='12p2'>77777.77</data> </ds> </parm> </pgm> <sql> <query>select * from QIWS.QCUSTCDT where LSTNAM='Jones'</query> <fetch block='all'/> </sql> </xmlservice> </textarea> <input type="hidden" name="xmlout" value="512000"> <br><input type="submit" name=submit" value="submit" /> </form> </body> </html>
XMLSERVICE REST bash w/curl
ssh xml@common1.frankeni.com > bash xmlservice.sh
#!/bin/bash curl -k \ --data-urlencode "db2=*LOCAL" \ --data-urlencode "uid=XML" \ --data-urlencode "pwd=$PASSWORD" \ --data-urlencode "ipc=*na" \ --data-urlencode "ctl=*here" \ --data-urlencode "xmlin=\ <?xml version='1.0'?> <xmlservice> <cmd>CHGLIBL LIBL(XMLSERVICE) CURLIB(XMLSERVICE)</cmd> <sh>system dsplibl</sh> <pgm name='ZZCALL'> <parm><data type='1A'>a</data></parm> <parm><data type='1A'>b</data></parm> <parm><data type='7p4'>11.1111</data></parm> <parm><data type='12p2'>222.22</data></parm> <parm> <ds> <data type='1A'>x</data> <data type='1A'>y</data> <data type='7p4'>66.6666</data> <data type='12p2'>77777.77</data> </ds> </parm> </pgm> <sql> <query>select * from QIWS.QCUSTCDT where LSTNAM='Jones'</query> <fetch block='all'/> </sql> </xmlservice>" \ --data-urlencode "xmlout=512000" \ https://common1.frankeni.com:47700/cgi-bin/xmlcgi.pgm
XMLSERVICE REST php
ssh xml@common1.frankeni.com > php xmlservice.php
<?php // $url = "http://common1.frankeni.com:58700/cgi-bin/xmlcgi.pgm"; $url = "https://common1.frankeni.com:47700/cgi-bin/xmlcgi.pgm"; $ixml = "<?xml version='1.0'?>\n"; $ixml .= "<xmlservice>"; $ixml .= "<cmd>CHGLIBL LIBL(XMLSERVICE) CURLIB(XMLSERVICE)</cmd>"; $ixml .= "<sh>system dsplibl</sh>"; $ixml .= " <pgm name='ZZCALL'>"; $ixml .= " <parm><data type='1A'>a</data></parm>"; $ixml .= " <parm><data type='1A'>b</data></parm>"; $ixml .= " <parm><data type='7p4'>11.1111</data></parm>"; $ixml .= " <parm><data type='12p2'>222.22</data></parm>"; $ixml .= " <parm>"; $ixml .= " <ds>"; $ixml .= " <data type='1A'>x</data>"; $ixml .= " <data type='1A'>y</data>"; $ixml .= " <data type='7p4'>66.6666</data>"; $ixml .= " <data type='12p2'>77777.77</data>"; $ixml .= " </ds>"; $ixml .= " </parm>"; $ixml .= "</pgm>"; $ixml .= "<sql>"; $ixml .= "<query>select * from QIWS.QCUSTCDT where LSTNAM='Jones'</query>"; $ixml .= "<fetch block='all'/>"; $ixml .= "</sql>"; $ixml .= "</xmlservice>"; $postdata = http_build_query( array( 'db2'=>'*LOCAL', 'uid'=>'XML', 'pwd'=>getenv('PASSWORD'), 'ipc'=>'*na', 'ctl'=>'*here', 'xmlin'=>$ixml, 'xmlout'=>512000 ) ); $opts=array('http'=> array( 'method'=>'POST', 'header'=>'Content-type: application/x-www-form-urlencoded', 'content'=>$postdata ), ); if (strpos($url,"ttps") > 0) { $opts['ssl'] = array( "verify_peer"=>false, "verify_peer_name"=>false); } $context = stream_context_create($opts); $xmlout = file_get_contents($url, false, $context); // output print "$xmlout\n"; // print phpinfo(); ?>
XMLSERVICE REST python
ssh xml@common1.frankeni.com > python xmlservice.py
# python import os import urllib import xml.dom.minidom xmlout = "" try: # url = 'http://common1.frankeni.com:58700/cgi-bin/xmlcgi.pgm' url = 'https://common1.frankeni.com:47700/cgi-bin/xmlcgi.pgm' ixml = "<?xml version='1.0'?>\n" ixml += "<xmlservice>" ixml += "<cmd>CHGLIBL LIBL(XMLSERVICE) CURLIB(XMLSERVICE)</cmd>" ixml += "<sh>system dsplibl</sh>" ixml += "<pgm name='ZZCALL'>" ixml += " <parm><data type='1A'>a</data></parm>" ixml += " <parm><data type='1A'>b</data></parm>" ixml += " <parm><data type='7p4'>11.1111</data></parm>" ixml += " <parm><data type='12p2'>222.22</data></parm>" ixml += " <parm>" ixml += " <ds>" ixml += " <data type='1A'>x</data>" ixml += " <data type='1A'>y</data>" ixml += " <data type='7p4'>66.6666</data>" ixml += " <data type='12p2'>77777.77</data>" ixml += " </ds>" ixml += " </parm>" ixml += "</pgm>" ixml += "<sql>" ixml += "<query>select * from QIWS.QCUSTCDT where LSTNAM='Jones'</query>" ixml += "<fetch block='all'/>" ixml += "</sql>" ixml += "</xmlservice>" params = urllib.urlencode({ 'db2': '*LOCAL', 'uid': 'XML', 'pwd': os.environ['PASSWORD'], 'ipc': '*na', 'ctl': '*here', 'xmlin': ixml, 'xmlout': '512000' }) usock = urllib.urlopen(url, params) xmldoc = xml.dom.minidom.parse(usock) usock.close() xmlout = xmldoc.toxml() except Exception, info: xmlout = "Error '%s' " % (info[0]) # output print xmlout
XMLSERVICE REST node.js
ssh xml@common1.frankeni.com > node xmlservice.js
// node.js // output (callback) function cb(str) { console.log(str); } // var uri = url.parse("http://common1.frankeni.com:58700/cgi-bin/xmlcgi.pgm"); var url = require('url'); var uri = url.parse("https://common1.frankeni.com:47700/cgi-bin/xmlcgi.pgm"); if (uri.protocol == 'https:') { var http = require("https"); } else { var http = require('http'); } var ixml = "<?xml version='1.0'?>\n" + "<xmlservice>" + "<cmd>CHGLIBL LIBL(XMLSERVICE) CURLIB(XMLSERVICE)</cmd>" + "<sh>system dsplibl</sh>" + " <pgm name='ZZCALL'>" + " <parm><data type='1A'>a</data></parm>" + " <parm><data type='1A'>b</data></parm>" + " <parm><data type='7p4'>11.1111</data></parm>" + " <parm><data type='12p2'>222.22</data></parm>" + " <parm>" + " <ds>" + " <data type='1A'>x</data>" + " <data type='1A'>y</data>" + " <data type='7p4'>66.6666</data>" + " <data type='12p2'>77777.77</data>" + " </ds>" + " </parm>" + "</pgm>" + "<sql>" + "<query>select * from QIWS.QCUSTCDT where LSTNAM='Jones'</query>" + "<fetch block='all'/>" + "</sql>" + "</xmlservice>"; var xml_enc = encodeURI("db2=" + '*LOCAL' + "&uid=" + 'XML' + "&pwd=" + process.env.PASSWORD + "&ipc=" + '*na' + "&ctl=" + '*here' + "&xmlin=" + ixml + "&xmlout=" + '512000'); var arr = uri.host.split(":"); var options = { host: arr[0], port: arr[1], path: uri.path + '/?' + xml_enc }; if (uri.protocol == 'https:') { options['rejectUnauthorized'] = false; options['requestCert'] = true; options['agent'] = false; } // console.log(options); var httpCallback = function(response) { var str = ''; //another chunk of data has been received, so append it to `str` response.on('data', function (chunk) { str += chunk; }); //the whole response has been received, so return response.on('end', function () { cb(str); }); } // make the call var req = http.request(options, httpCallback).end();
XMLSERVICE REST ruby
ssh xml@common1.frankeni.com > ruby xmlservice.rb
# ruby require 'net/https' require 'uri' # @url = 'http://common1.frankeni.com:58700/cgi-bin/xmlcgi.pgm' @url = 'https://common1.frankeni.com:47700/cgi-bin/xmlcgi.pgm' @ixml = "<?xml version='1.0'?>\n" @ixml << "<xmlservice>" @ixml << "<cmd>CHGLIBL LIBL(XMLSERVICE) CURLIB(XMLSERVICE)</cmd>" @ixml << "<sh>system dsplibl</sh>" @ixml << " <pgm name='ZZCALL'>" @ixml << " <parm><data type='1A'>a</data></parm>" @ixml << " <parm><data type='1A'>b</data></parm>" @ixml << " <parm><data type='7p4'>11.1111</data></parm>" @ixml << " <parm><data type='12p2'>222.22</data></parm>" @ixml << " <parm>" @ixml << " <ds>" @ixml << " <data type='1A'>x</data>" @ixml << " <data type='1A'>y</data>" @ixml << " <data type='7p4'>66.6666</data>" @ixml << " <data type='12p2'>77777.77</data>" @ixml << " </ds>" @ixml << " </parm>" @ixml << "</pgm>" @ixml << "<sql>" @ixml << "<query>select * from QIWS.QCUSTCDT where LSTNAM='Jones'</query>" @ixml << "<fetch block='all'/>" @ixml << "</sql>" @ixml << "</xmlservice>" post_args = { :db2 => '*LOCAL', :uid => 'XML', :pwd => ENV['PASSWORD'], :ipc => '*na', :ctl => '*here', :xmlin => URI::encode(@ixml), :xmlout => '512000' } uri = URI(@url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true if uri.scheme == 'https' http.verify_mode = OpenSSL::SSL::VERIFY_NONE res = http.post(uri, URI.encode_www_form(post_args)) # output @xmlout = res.body puts @xmlout
XMLSERVICE REST java
ssh xml@common1.frankeni.com > javac xmlservice.java > java xmlservice
// javac xmlservice.java // java xmlservice import java.io.*; import java.net.*; import java.security.SecureRandom; import java.security.cert.X509Certificate; import javax.net.ssl.*; public class xmlservice { public static String go () throws UnsupportedEncodingException, UnsupportedEncodingException, IOException { // URL url = new URL("http://common1.frankeni.com:58700/cgi-bin/xmlcgi.pgm"); URL url = new URL("https://common1.frankeni.com:47700/cgi-bin/xmlcgi.pgm"); String ixml = "<?xml version='1.0'?>\n" + "<xmlservice>" + "<cmd>CHGLIBL LIBL(XMLSERVICE) CURLIB(XMLSERVICE)</cmd>" + "<sh>system dsplibl</sh>" + " <pgm name='ZZCALL'>" + " <parm><data type='1A'>a</data></parm>" + " <parm><data type='1A'>b</data></parm>" + " <parm><data type='7p4'>11.1111</data></parm>" + " <parm><data type='12p2'>222.22</data></parm>" + " <parm>" + " <ds>" + " <data type='1A'>x</data>" + " <data type='1A'>y</data>" + " <data type='7p4'>66.6666</data>" + " <data type='12p2'>77777.77</data>" + " </ds>" + " </parm>" + "</pgm>" + "<sql>" + "<query>select * from QIWS.QCUSTCDT where LSTNAM='Jones'</query>" + "<fetch block='all'/>" + "</sql>" + "</xmlservice>"; String query = new String( java.net.URLEncoder.encode( "db2=" + "*LOCAL" + "&uid=" + "XML" + "&pwd=" + java.lang.System.getenv("PASSWORD") + "&ipc=" + "*na" + "&ctl=" + "*here" + "&xmlin=" + ixml + "&xmlout=" + "512000" , "ISO-8859-1")); byte[] queryBytes = query.getBytes("UTF-8"); String length = String.valueOf((url + query).getBytes("UTF-8").length); // HttpURLConnection conn = (HttpURLConnection) url.openConnection(); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); try { SSLSocketFactory sslSocketFactory = createSslSocketFactory(); conn.setSSLSocketFactory(sslSocketFactory); // certificate common name needed to be lp0364d (match tcp name) // conn.setHostnameVerifier(new HostnameVerifier() { public boolean verify(String _s1, SSLSession _s2) { return true;} }); } catch (Exception e) { System.out.println(e.getMessage()); } conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Length", length); conn.setDoOutput(true); OutputStream os = conn.getOutputStream(); os.write(queryBytes); os.flush(); conn.connect(); BufferedReader strm = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; String doc = ""; while ((inputLine = strm.readLine()) != null) { doc = doc + inputLine; } return new String(doc); } private static SSLSocketFactory createSslSocketFactory() throws Exception { TrustManager[] byPassTrustManagers = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } public void checkClientTrusted(X509Certificate[] chain, String authType) {} public void checkServerTrusted(X509Certificate[] chain, String authType) {} } }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, byPassTrustManagers, new SecureRandom()); return sslContext.getSocketFactory(); } public static void main (String args[]) { // output String xmlout = ""; try { xmlout += go(); } catch (Exception e) { xmlout += e.getMessage(); } System.out.println(xmlout); } }