227 lines
5.7 KiB
Text
Executable file
227 lines
5.7 KiB
Text
Executable file
#!/usr/bin/env newlisp
|
|
#
|
|
# xmlrpc.cgi - CGI script to handle XML-RPC requests
|
|
#
|
|
# This is similar to xmlrpc-server, but stateless as a new
|
|
# newLISP process is invoked everytime this script is executed.
|
|
# For a XML-RPC server maintaining state run xmlrpc-server.
|
|
#
|
|
# v.1.0 - 2005-01-14 Lutz Mueller
|
|
#
|
|
# v.1.1 - 2005-03-20
|
|
# method name for newLISP.evalString was listed wrong
|
|
# v.1.2 - 2010-02-09
|
|
# method name for newLISP.evalString was listed wrong
|
|
# v.1.3 - 2010-10-07
|
|
# replaced obsolete 'error-text' with 'last-error'
|
|
# v.1.4 - 2012-03-16 bugfixes, thanks Kosh
|
|
#
|
|
# supports the following methods:
|
|
#
|
|
# Method Return Parameter
|
|
# ------ ------ ---------
|
|
# system.listMethods string n/a
|
|
# system.methodHelp string string
|
|
# system.methodSignature array string
|
|
# newLISP.evalString base64 base64
|
|
#
|
|
#
|
|
|
|
(set 'version "1.4")
|
|
|
|
# formatting templates for responses
|
|
|
|
(set 'normal-response
|
|
[text]<?xml version="1.0"?>
|
|
<methodResponse>
|
|
<params>
|
|
<param>
|
|
<value>%s</value>
|
|
</param>
|
|
</params>
|
|
</methodResponse>
|
|
[/text])
|
|
|
|
(set 'fault-response
|
|
[text]<?xml version="1.0"?>
|
|
<methodResponse>
|
|
<fault>
|
|
<value>
|
|
<struct>
|
|
<member>
|
|
<name>faultCode</name>
|
|
<value><int>%d</int></value>
|
|
</member>
|
|
<member>
|
|
<name>faultString</name>
|
|
<value><string>%s</string></value>
|
|
</member>
|
|
</struct>
|
|
</value>
|
|
</fault>
|
|
</methodResponse>
|
|
[/text])
|
|
|
|
|
|
# event handler called when newLISP receives a request
|
|
|
|
(define (process-post request)
|
|
(if (not (catch (handle request) 'page))
|
|
(set 'page (format fault-response 0 page)))
|
|
(print
|
|
"Content-Type: text/xml\r\n"
|
|
"Content-Length: " (length page) "\r\n\r\n"
|
|
page))
|
|
|
|
|
|
(define (handle input, XML contentlength methodName params)
|
|
(set 'XML "")
|
|
(xml-type-tags nil nil nil nil)
|
|
(if (not (set 'XML (xml-parse input (+ 1 2 4 8 16))))
|
|
(begin
|
|
(if (not (xml-error))
|
|
(error 3 "No XML or XML is empty")
|
|
(error 4 (append "XML error: "
|
|
(first (xml-error))))))
|
|
|
|
(set 'XML (first XML)))
|
|
|
|
; get methodName and parameter section
|
|
(set 'm (match '(methodCall (methodName *) *) XML))
|
|
(if (not m)
|
|
(error 5 "Invalid XML-RPC format"))
|
|
|
|
(set 'methodName (first (first m)))
|
|
(set 'params (last m))
|
|
|
|
(case methodName
|
|
("newLISP.evalString" (newLISP.evalString params))
|
|
("system.listMethods" (system.listMethods))
|
|
("system.methodHelp" (system.methodHelp params))
|
|
("system.methodSignature" (system.methodSignature params))
|
|
(true (error 6 "Method name not known")))
|
|
)
|
|
|
|
(define (error no msg)
|
|
(throw (format fault-response no
|
|
(append "newLISP XML-RPC v." version " - " msg))))
|
|
|
|
|
|
######################### remote callable methods ##############################
|
|
|
|
(define (system.listMethods)
|
|
[text]<?xml version="1.0"?>
|
|
<methodResponse>
|
|
<params>
|
|
<param><value><array><data>
|
|
<value><string>system.listMethods</string></value>
|
|
<value><string>system.methodHelp</string></value>
|
|
<value><string>system.methodSignature</string></value>
|
|
<value><string>newLISP.evalString</string></value>
|
|
</data></array></value></param>
|
|
</params>
|
|
</methodResponse>
|
|
[/text])
|
|
|
|
|
|
(define (system.methodHelp params, methodName)
|
|
(set 'methodName (params 0 1 1 1 1))
|
|
(case methodName
|
|
("system.listMethods" (format normal-response "Lists all methods implemented."))
|
|
("system.methodHelp" (format normal-response "Documents a method."))
|
|
("system.methodSignature" (format normal-response "Shows the signatures of a method."))
|
|
("newLISP.evalString" (format normal-response "Evaluate a base64 encoded string."))
|
|
(true (error 7 "Method name in system.methodHelp not known")))
|
|
)
|
|
|
|
(define (system.methodSignature params)
|
|
(set 'methodName (params 0 1 1 1 1))
|
|
(case methodName
|
|
("system.listMethods" (format normal-response
|
|
"<array>
|
|
<data>
|
|
<value>
|
|
<array>
|
|
<data>
|
|
<value>array</value>
|
|
</data>
|
|
</array>
|
|
</value>
|
|
</data>
|
|
</array>"))
|
|
|
|
("system.methodHelp" (format normal-response
|
|
"<array>
|
|
<data>
|
|
<value>
|
|
<array>
|
|
<data>
|
|
<value>string</value>
|
|
<value>string</value>
|
|
</data>
|
|
</array>
|
|
</value>
|
|
</data>
|
|
</array>"))
|
|
|
|
("system.methodSignature" (format normal-response
|
|
"<array>
|
|
<data>
|
|
<value>
|
|
<array>
|
|
<data>
|
|
<value>array</value>
|
|
<value>string</value>
|
|
</data>
|
|
</array>
|
|
</value>
|
|
</data>
|
|
</array>"))
|
|
|
|
("newLISP.evalString" (format normal-response
|
|
"<array>
|
|
<data>
|
|
<value>
|
|
<array>
|
|
<data>
|
|
<value>base64</value>
|
|
<value>base64</value>
|
|
</data>
|
|
</array>
|
|
</value>
|
|
</data>
|
|
</array>"))
|
|
|
|
(true (error 7 "Method name in system.methodSignature not known")))
|
|
)
|
|
|
|
(define (newLISP.evalString params, m, result)
|
|
(set 'm (match '((params (param (value (base64 *))))) params))
|
|
(if (not m)
|
|
(error 8 "Invalid format for method newLISP.evalString")
|
|
(set 'result
|
|
(string (eval-string (base64-dec (first (first m))) MAIN (last (last-error)))))
|
|
(format normal-response
|
|
(append "<base64>" (base64-enc result) "</base64>")) )
|
|
)
|
|
|
|
|
|
########################### MAIN ENTRY POINT #######################
|
|
|
|
(set 'input (read-line))
|
|
|
|
(if (not input)
|
|
(print
|
|
"Content-type: text/html\r\n\r\n"
|
|
"<h2>newLISP XML-RPC v." version
|
|
": not a valid XML-RPC request</h2>")
|
|
(begin
|
|
(while (read-line) (write input (current-line)))
|
|
(process-post input))
|
|
)
|
|
|
|
|
|
(exit)
|
|
|
|
|
|
# eof
|