* This is a sample program that runs as a web page. It opens a socket * to the web service at http://www.amazon.com, and allows a user to * search their catalog. The returned data is sent as xml and parsed * using the Janus SOAP functions. To make this work at your site you * would need Janus Web, Janus SOAP, Janus Sockets and an Amazon developer's * token. Besides running on the web, this sample shows how a Janus Socket * is opened and managed, and how http data is received and parsed. * ----------------------------------------------------------------------- * * Here are some Janus rules that build some infrastructure, a port, * the necessary security info, and a web rule, all of which define * a socket application that can be called from a web page. * Typically, these rules would run as part of the online startup. * Define your name server. JANUS NAMESERVER 198.242.244.9 53 * A security group that we'll "allow" to use the socket. JANUS DEFINEUSGROUP SIRIUS ALAN ALEX BARRY DME GARY JEFF TOM WEBUSER * Clear-out and re-define the socket port. JANUS FORCE SOAP JANUS DELETE SOAP JANUS DEFINE SOAP * CLSOCK 5 TIMEOUT 4 REMOTE * * * Security (read the manual about this: you need to "allow" people to use the socket). JANUS CLSOCK SOAP ALLOW USGROUP SIRIUS * Start the port. JANUS START SOAP * A rule to allow access to the web page that calls the socket program. JANUS WEB WEB ON /SOAP/* OPEN ALANPROC CMD 'I *' * If you really can't tell what's going on in your socket program, you * can always turn on a very high level of tracing and get a hex dump of * the entire socket conversion in the journal, by turning on this rule. * JANUS TRACE SOAP 8 * ----------------------------------------------------------------------- * BEGIN %BASE_PAGE IS STRING LEN 3 %CAT IS STRING LEN 50 %DEVELOPERS_TOKEN IS STRING LEN 20 %HOST IS STRING LEN 255 %METHOD IS STRING LEN 4 %MSG IS STRING LEN 255 ARRAY (4) %PAGE IS STRING LEN 3 %KEY IS STRING LEN 255 %T IS STRING LEN 255 %WEIGHT IS STRING LEN 5 %S IS LONGSTRING %CATS IS STRING LEN 255 %CATSL IS STRING LEN 255 %CL IS FIXED DP 0 %CNT IS FIXED DP 0 %RL IS FIXED DP 0 %CONN1 IS FLOAT %COUNT IS FLOAT %D IS FLOAT %DT IS FLOAT %PORT IS FLOAT %PRX IS FLOAT %RC IS FLOAT %TEST IS FLOAT %W IS FLOAT %X IS FLOAT %Y IS FLOAT %Z IS FLOAT %DT = $WEB_DATE + (30 * 24 * 60 * 60) %RC = $WEB_ON %RC = $WEB_TYPE('TEXT/HTML') %RC = $WEB_SUB('@@') %RC = $WEB_EXPIRE($WEB_DATE - 1) %RC = $WEB_RESPONSE('PRAGMA', 'NO-CACHE') * You need to get a developer's token from Amazon. Go to * http://www.amazon.com and look for "Web Services". %DEVELOPERS_TOKEN = 'xxxxxxxxxxxxxx' %HOST = 'xml.amazon.com' %PORT = 80 * valid product line values (per Amazon): %CATS = '/baby/books/classical/dvd/electronics/garden/kitchen' - WITH '/magazines/music/pc-hardware/photo/software/toys/universal' - WITH '/vhs/videogames' %CATSL = '/Baby/Books/Classical Music/DVD/Electronics/Outdoor Living' - WITH '/Kitchen & Housewares/Magazines/Popular Music/Computers' - WITH '/Camera & Photo/Software/Toys & Games/Tools & Hardware' - WITH '/Video/Computer & Video Games' * If form was "posted" capture the input and reset cookie. %METHOD = $UPCASE($WEB_HDR_PARM('METHOD')) IF %METHOD EQ 'POST' THEN %TEST = $WEB_PARM('test') %KEY = $WEB_PARM('key') %PAGE = $WEB_PARM('page') %CAT = $WEB_PARM('cat') %WEIGHT = $WEB_PARM('weight') %RC = $WEB_SET_COOKIE('TEST', %TEST, %DT ) %RC = $WEB_SET_COOKIE('KEY', %KEY, %DT ) %RC = $WEB_SET_COOKIE('PAGE', %PAGE, %DT ) %RC = $WEB_SET_COOKIE('CAT', %CAT, %DT ) %RC = $WEB_SET_COOKIE('WEIGHT', %WEIGHT, %DT ) * Else (form method is "get") see if we can populate form from cookie. ELSE %TEST = $WEB_COOKIE_PARM('TEST') %KEY = $WEB_COOKIE_PARM('KEY') %PAGE = $WEB_COOKIE_PARM('PAGE') %CAT = $WEB_COOKIE_PARM('CAT') %WEIGHT = $WEB_COOKIE_PARM('WEIGHT') END IF CALL SENDFORM * We process as "POST" both on a POST and when * user asked for next page from Amazon. %CNT = 1 IF $WEB_PARM('page') NE '' THEN %PAGE = $WEB_PARM('page') %BASE_PAGE = %PAGE %CNT = ((%PAGE-1)*10) + 1 ELSEIF %METHOD NE 'POST' THEN JUMP TO CLOSE END IF IF NOT $VNUM(%PAGE) OR (%PAGE EQ 0) THEN %PAGE = 1 END IF * Connect %RC = $SOCK_ONRESET('SOCKET_ERROR') CONN: %CONN1 = $SOCK_CONN('SOAP', $UPCASE(%HOST), %PORT) IF %CONN1 LT 0 THEN PRINT '$SOCK_CONN failed to make connection. Reason= ' WITH %CONN1 STOP END IF * Set a line-end character and a "parse" token. %RC = $SOCK_SET(%CONN1, 'LINEND', '0D0A') %RC = $SOCK_SET(%CONN1, 'PRSTOK', '0D0A') * Blanks are not allowed in URLs, so substitute "%20". %KEY = $SUBREP(%KEY,' ','%20',,255) * Send the request: %RC = $SOCK_CAPTURE(%CONN1, 'ON') CALL BUILD_HEADER %RC = $SOCK_CAPTURE(%CONN1, 'OFF') %CL = -1 * Loop over the header lines, parsing the http headers: REPEAT %RC = $SOCK_RECVPRS(%CONN1, %T) IF %RC LE 0 THEN %MSG(1) = 'Can''t Access Service' JUMP TO ERRX END IF * Blank line indicates "end-of-header". IF %T EQ '' THEN LOOP END ELSEIF $SUBSTR(%T, 1, 16) EQ - 'Content-Length: ' THEN %CL = $SUBSTR(%T, 16) END IF END REPEAT * Pull the remaining info (the XML) into a longstring. %RL = $SOCK_RECV(%CONN1, %S) * Length of received string should be same as content length. IF %RL LT %CL THEN %MSG(1) = 'XML Content Error:' %MSG(2) = 'Packet Length (' WITH %RL WITH ') doesn''t match ' - WITH 'content length in header (' WITH %CL WITH ').' JUMP TO ERRX END IF SOCK_END: * Initialize an XML doc. %D = $XML_DOC %RC = $XML_SET(%D,'NAMESPACE','IGNORE') * Now deserialize the received string into the doc. * NB: We skip this in test mode because sometimes the deserialization * fails when the XML is faulty. If we hit the $XML_STR2DOC function * we won't be able to see the faulty XML (though the error message * from the failed function call may be the best diagnostic we're * going to get anyway). IF NOT %TEST THEN %S = $XML_STR2DOC(%D, %S, 'DTD_IGNORE') END IF * Close the socket. %RC = $SOCK_CLOSE(%CONN1) * If we're testing we just print the raw XML and exit. * Why print the %S longstring in 1K chunks? Because if the * longstring is longer than LOBUFF, the print will be truncated. IF %TEST THEN PRINT '