(index ("xml-rpc-server" 0) ("xml-rpc-methodcall" 1029) ("xml-rpc-response->values" 1566) ("make-xml-rpc-request-handler" 1952) ("start-simple-xml-rpc-server" 2945) ("xml-rpc-call->xml-rpc-response" 3302) ("call-xml-rpc-proc" 4515) ("xml-rpc-unparsers" 5639) ("value->xml-rpc-fragment" 6911) ("nonempty-symbol-keyed-alist?" 7170) ("list->xml-rpc-array" 7974) ("vector->xml-rpc-array" 7974) ("number->xml-rpc-int" 7974) ("number->xml-rpc-double" 7974) ("boolean->xml-rpc-boolean" 7974) ("u8vector->xml-rpc-base64" 7974) ("blob->xml-rpc-base64" 7974) ("alist->xml-rpc-struct" 7974) ("hash-table->xml-rpc-struct" 7974) ("->xml-rpc-string" 9056) ("vector->xml-rpc-iso8601" 9378) ("xml-rpc-parsers" 10172) ("xml-rpc-fragment->value" 11618) ("xml-rpc-int->number" 11991) ("xml-rpc-double->number" 11991) ("xml-rpc-boolean->number" 11991) ("xml-rpc-string->string" 11991) ("xml-rpc-array->vector" 11991) ("xml-rpc-array->list" 11991) ("xml-rpc-struct->alist" 11991) ("xml-rpc-struct->hash-table" 11991) ("xml-rpc-base64->string" 11991) ("xml-rpc-base64->u8vector" 11991) ("xml-rpc-base64->blob" 11991) ("xml-rpc-datetime->vector" 11991))
(def (sig (procedure "(xml-rpc-server uri)" (id xml-rpc-server))) (p "Returns a procedure that, when called with the name of a remote XML-RPC method, will return a procedure that passes its arguments to the XML-RPC server which is given in " (tt "uri") " (which can be an URI object or a string representing an URI).") (p "To determine how XML-RPC types are mapped to Scheme types and vice-versa, see " (int-link "#Low-level" "below") ".  It's important that you read this, because there is some ambiguity in how lists are mapped (either to arrays or to structs).") (p "Here is an example that fetches the current time of day from xml-rpc.org:") (highlight scheme "(require-extension xml-rpc-client)\n\n(define time-server\n  (xml-rpc-server \"http://xml-rpc.org/RPC2\") )\n  \n(define get-current-time\n  (time-server \"currentTime.getCurrentTime\") )\n  \n(print (time->string (get-current-time)))") (p "For lower-level access to the client (implementing custom handlers, for example), you can use the following procedures:"))
(def (sig (procedure "(xml-rpc-methodcall method-name args)" (id xml-rpc-methodcall))) (p "Constructs an SXML representation of a method call to the procedure " (tt "method-name") " with an arguments list of " (tt "args") ".") (highlight scheme "(use xml-rpc-client)\n\n(xml-rpc-methodcall 'scheme.makeList '(1 2 3 \"testing\"))\n =>\n(methodCall\n  (methodName \"scheme.makeList\")\n  (params\n    (param (value (i4 \"1\")))\n    (param (value (i4 \"2\")))\n    (param (value (i4 \"3\")))\n    (param (value (string \"testing\")))))"))
(def (sig (procedure "(xml-rpc-response->values response-sxml)" (id xml-rpc-response->values))) (p "This procedure accepts as " (tt "response-sxml") " the SXML representation of a server's response, and either returns the values returned by the procedure call encoded in the response, or throws an exception of type " (tt "exn xml-rpc") " in case the response contains invalid data."))
(def (sig (procedure "(make-xml-rpc-request-handler procedures)" (id make-xml-rpc-request-handler))) (p "This creates a procedure which accepts two arguments; an " (int-link "intarweb") " request object and a response object.  It will read an XML-RPC request from the request-port and respond to the request with the response object, writing to its port.") (p "The procedure that is requested to be called is looked up in the " (tt "procedures") " argument, which is an alist of procedure name (symbols) to procedure (lambda) mappings. The procedures are called with exactly the arguments that are sent by the client, encoded in the call (" (tt "call-sxml") "). They will be converted to regular Scheme values before the procedure is invoked.") (p "To determine how XML-RPC types are mapped to Scheme types and vice-versa, see " (int-link "#Low-level" "below") ".  It's important that you read this, because there is some ambiguity in how lists are mapped (either to arrays or to structs)."))
(def (sig (procedure "(start-simple-xml-rpc-server procedures [port])" (id start-simple-xml-rpc-server))) (p "Create a standalone XML-RPC server on " (tt "port") " (defaults to 8080), which accepts an XML-RPC request on any URL.") (p "You can also use slightly more low-level procedures to implement your own server to be exactly like you want it to be:"))
(def (sig (procedure "(xml-rpc-call->xml-rpc-response call-sxml procedures)" (id xml-rpc-call->xml-rpc-response))) (p "This procedure converts an XML-RPC procedure call described by " (tt "call-sxml") " into an SXML representation of the result.  The procedure is looked up in " (tt "procedures") ", invoked, and its return values are converted into the appropriate SXML structure describing a " (tt "methodResponse") ".  If an error occurs inside the procedure, the procedure does not exist, or the XML is invalid, a " (tt "methodResponse") " encoding the " (tt "fault") " is constructed instead.") (highlight scheme "(use xml-rpc-server)\n\n(xml-rpc-call->xml-rpc-response\n  `(*TOP*\n     (*PI* xml \"version=\\\"1.0\\\"\")\n     (methodCall  ; (xml-rpc-methodcall 'scheme.makeList '(1 2 3))\n       (methodName \"scheme.makeList\")\n         (params\n           (param (value (int \"1\")))\n           (param (value (int \"2\")))\n           (param (value (int \"3\"))))))\n  `((scheme.makeList . ,list)))\n =>\n(methodResponse\n  (params\n    (param (value\n             (array\n\t       (data\n\t         (value (i4 \"1\"))\n                 (value (i4 \"2\"))\n                 (value (i4 \"3\"))))))))"))
(def (sig (procedure "(call-xml-rpc-proc call-sxml procedures)" (id call-xml-rpc-proc))) (p "This procedure accepts as " (tt "call-sxml") " the SXML representation of a procedure call from a client and calls it, returning its values.") (p "This is exactly like " (tt "xml-rpc-call->xml-rpc-response") ", except it does not construct an SXML result tree. Instead, the return values are those returned by the procedure being called.  In case the procedure could not be found or if the call contains an invalid XML structure, an exception of type " (tt "(exn xml-rpc)") " is thrown.  The " (tt "xml-rpc") " part of the condition contains a " (tt "code") " property which contains the fault code. This is " (tt "1") " in case the procedure could not be found and " (tt "2") " in case the XML is bad.") (highlight scheme "(use xml-rpc-server)\n\n(call-xml-rpc-proc\n  `(*TOP*\n     (*PI* xml \"version=\\\"1.0\\\"\")\n     (methodCall\n      (methodName \"Math.add\")\n      (params\n       (param (value (int \"1\")))\n       (param (value (int \"2\")))\n       (param (value (int \"3\"))))))\n   `((Math.add . ,+)))\n =>\n6"))
(def (sig (parameter "(xml-rpc-unparsers [alist])" (id xml-rpc-unparsers))) (p "This parameter controls how Scheme values are encoded into XML-RPC values. The keys of this alist are predicate procedures, the values are conversion procedures.  If the predicate procedure returns true for its argument, it's a datatype that will be converted to SXML by the matching conversion procedure.") (p "Defaults to:") (highlight scheme "`((,vector? . ,vector->xml-rpc-array)\n  (,(conjoin number? exact?) . ,number->xml-rpc-int)\n  (,number? . ,number->xml-rpc-double)\n  (,boolean? . ,boolean->xml-rpc-boolean)\n  (,string? . ,->xml-rpc-string)\n  (,symbol? . ,->xml-rpc-string)\n  (,u8vector? . ,u8vector->xml-rpc-base64)\n  (,blob? . ,blob->xml-rpc-base64)\n  (,hash-table? . ,hash-table->xml-rpc-struct)\n  ;; see below for an explantation of this predicate\n  (,nonempty-symbol-keyed-alist? . ,alist->xml-rpc-struct)\n  (,list? . ,list->xml-rpc-array))") (p "Order matters in this alist; the converter corresponding to the first predicate returning a true value is used.") (p "The SXML returned by these conversion procedures is the element " (i "inside") " the " (tt "value") " element.") (highlight scheme "(use xml-rpc-lolevel)\n\n(number->xml-rpc-int 1)\n =>\n(i4 \"1\")"))
(def (sig (procedure "(value->xml-rpc-fragment value)" (id value->xml-rpc-fragment))) (p "This procedure converts any Scheme value to SXML for its XML-RPC representation.  It looks up the conversion procedure in the " (tt "xml-rpc-unparsers") " parameter."))
(def (sig (procedure "(nonempty-symbol-keyed-alist? obj)" (id nonempty-symbol-keyed-alist?))) (p "Returns " (tt "#t") " when " (tt "obj") " is a " (i "nonempty") " list of pairs, each of which has a symbol as " (tt "car") ".") (p "The idea behind this predicates is that it helps to do \"The Right Thing\" when you call an XML-RPC procedure. You can pass in regular lists or alists, and it will try to make the right decision whether to convert your lists to structs or arrays.") (p "The predicate returns true for nonempty lists only because it's much more likely that you will have empty regular lists than empty alists. However, it's important to be aware of this because you might end up with an empty alist. For absolute safety, remove this predicate from the parameter and use only hash-tables."))
(def (sig (procedure "(list->xml-rpc-array list)" (id list->xml-rpc-array)) (procedure "(vector->xml-rpc-array vector)" (id vector->xml-rpc-array)) (procedure "(number->xml-rpc-int number)" (id number->xml-rpc-int)) (procedure "(number->xml-rpc-double number)" (id number->xml-rpc-double)) (procedure "(boolean->xml-rpc-boolean boolean)" (id boolean->xml-rpc-boolean)) (procedure "(u8vector->xml-rpc-base64 u8vector)" (id u8vector->xml-rpc-base64)) (procedure "(blob->xml-rpc-base64 blob)" (id blob->xml-rpc-base64)) (procedure "(alist->xml-rpc-struct alist)" (id alist->xml-rpc-struct)) (procedure "(hash-table->xml-rpc-struct hash-table)" (id hash-table->xml-rpc-struct))) (p "These procedures pretty much do the obvious thing: they encode a Scheme object of the given type to an SXML representation for use in the XML-RPC request.  Again, the return values look like " (tt "(i4 \"1\")") " and " (tt "(string \"foo\")") ", " (i "not") " like " (tt "(value (string \"foo\"))") ". Inside arrays and structs, the " (tt "value") " is automatically wrapped around the right values."))
(def (sig (procedure "(->xml-rpc-string obj)" (id ->xml-rpc-string))) (p "This procedure converts the " (tt "obj") " to string with " (tt "->string") " and then encodes it in SXML as an XML-RPC string value.  This is useful for passing symbols, regular strings or numbers to procedures expecting string representation."))
(def (sig (procedure "(vector->xml-rpc-iso8601 time-vector)" (id vector->xml-rpc-iso8601))) (p "This procedure encodes a \"time vector\" (10-element vector, as returned by eg " (int-link "/man/4/Unit posix#seconds-local-time" "seconds->local-time") ") to an iso8601 string representing the same date.  Currently this procedure is not in the parameter list by default, because it's impossible to differentiate between a regular vector that just happens to be 10 elements long and a \"time-vector\". The same problem exists for integers and the \"seconds since the epoch\" representation of time.") (p "Using " (int-link "srfi-19") " is a solution to this problem, as it provides a distinct datatype for date/time objects. But you would have to make your own conversion routines in this case."))
(def (sig (parameter "(xml-rpc-parsers [alist])" (id xml-rpc-parsers))) (p "This parameter controls how XML-RPC values are decoded back into Scheme values. The keys of this alist are symbols, the values are conversion procedures.  If the name of a predicate procedure returns true for its argument, it's a datatype that will be converted to SXML by the matching conversion procedure.") (p "Defaults to:") (highlight scheme "`((i4 . ,xml-rpc-int->number)\n  (int . ,xml-rpc-int->number)\n  (double . ,xml-rpc-double->number)\n  (boolean . ,xml-rpc-boolean->number)\n  (string . ,xml-rpc-string->string)\n  (base64 . ,xml-rpc-base64->u8vector)\n  (dateTime.iso8601 . ,xml-rpc-datetime->vector)\n  (array . ,xml-rpc-array->vector)\n  (struct . ,xml-rpc-struct->hash-table))") (p "The SXML arguments to these conversion procedures is the element " (i "inside") " the " (tt "value") " element. In other words, the element name (or " (tt "car") ")of its SXML argument is equal to its key in this alist.") (p (i "Important note") ": Due to unspecified details of POSIX " (tt "strptime") ", you should " (i "never") " rely on proper values in the day-of-year or day-of-week slots for datetime values returned by xml-rpc.  This is because XML-RPC internally uses regular ISO8601 format where these fields are not present.  Some C libraries derive this information from the other fields (which is possible and can be done correctly), but others do not."))
(def (sig (procedure "(xml-rpc-fragment->value sxml-fragment)" (id xml-rpc-fragment->value))) (p "This procedure converts an SXML representation of an XML-RPC value to its Scheme representation.  It looks up the conversion procedure in the " (tt "xml-rpc-parsers") " parameter.") (highlight scheme "(use xml-rpc-lolevel)\n\n(xml-rpc-fragment->value '(i4 \"1\"))\n =>\n1"))
(def (sig (procedure "(xml-rpc-int->number sxml-fragment)" (id xml-rpc-int->number)) (procedure "(xml-rpc-double->number sxml-fragment)" (id xml-rpc-double->number)) (procedure "(xml-rpc-boolean->number sxml-fragment)" (id xml-rpc-boolean->number)) (procedure "(xml-rpc-string->string sxml-fragment)" (id xml-rpc-string->string)) (procedure "(xml-rpc-array->vector sxml-fragment)" (id xml-rpc-array->vector)) (procedure "(xml-rpc-array->list sxml-fragment)" (id xml-rpc-array->list)) (procedure "(xml-rpc-struct->alist sxml-fragment)" (id xml-rpc-struct->alist)) (procedure "(xml-rpc-struct->hash-table sxml-fragment)" (id xml-rpc-struct->hash-table)) (procedure "(xml-rpc-base64->string sxml-fragment)" (id xml-rpc-base64->string)) (procedure "(xml-rpc-base64->u8vector sxml-fragment)" (id xml-rpc-base64->u8vector)) (procedure "(xml-rpc-base64->blob sxml-fragment)" (id xml-rpc-base64->blob)) (procedure "(xml-rpc-datetime->vector sxml-fragment)" (id xml-rpc-datetime->vector))) (p "Convert the given " (tt "sxml-fragment") " to the corresponding Scheme value."))
