mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-23 13:05:27 +00:00
remove unused xmlrpc-related files
* src/xmlrpc.h: Remove file. * src/xmlrpc.c: Likewise. * tests/test_xmlrpc.sh: Likewise. * tests/xmlrpctest.c: Likewise. * tests/xmlrpcserver.py: Likewise. * tests/Makefile.am (EXTRA_DIST): Remove xmlserver.py. (noinst_PROGRAMS): Remove xmlrpctest, along with associated variables. * po/POTFILES.in: Remove src/xmlrpc.c. * tests/.cvsignore: Remove xmlrpctest.
This commit is contained in:
parent
2e59a005fd
commit
506629e619
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
Fri Dec 12 12:19:56 +0100 2008 Jim Meyering <meyering@redhat.com>
|
||||||
|
|
||||||
|
remove unused xmlrpc-related files
|
||||||
|
* src/xmlrpc.h: Remove file.
|
||||||
|
* src/xmlrpc.c: Likewise.
|
||||||
|
* tests/test_xmlrpc.sh: Likewise.
|
||||||
|
* tests/xmlrpctest.c: Likewise.
|
||||||
|
* tests/xmlrpcserver.py: Likewise.
|
||||||
|
* tests/Makefile.am (EXTRA_DIST): Remove xmlserver.py.
|
||||||
|
(noinst_PROGRAMS): Remove xmlrpctest, along with associated variables.
|
||||||
|
* po/POTFILES.in: Remove src/xmlrpc.c.
|
||||||
|
* tests/.cvsignore: Remove xmlrpctest.
|
||||||
|
|
||||||
Fri Dec 12 11:37:16 CET 2008 Daniel Veillard <veillard@redhat.com>
|
Fri Dec 12 11:37:16 CET 2008 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* src/qemu_conf.c src/uml_conf.c: fix a couple of places where
|
* src/qemu_conf.c src/uml_conf.c: fix a couple of places where
|
||||||
|
@ -40,5 +40,4 @@ src/xen_internal.c
|
|||||||
src/xend_internal.c
|
src/xend_internal.c
|
||||||
src/xm_internal.c
|
src/xm_internal.c
|
||||||
src/xml.c
|
src/xml.c
|
||||||
src/xmlrpc.c
|
|
||||||
src/xs_internal.c
|
src/xs_internal.c
|
||||||
|
688
src/xmlrpc.c
688
src/xmlrpc.c
@ -1,688 +0,0 @@
|
|||||||
/*
|
|
||||||
* xmlrpc.c: XML-RPC protocol handler for libvir library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 IBM, Corp.
|
|
||||||
*
|
|
||||||
* See COPYING.LIB for the License of this software
|
|
||||||
*
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "xmlrpc.h"
|
|
||||||
#include "virterror_internal.h"
|
|
||||||
#include "memory.h"
|
|
||||||
|
|
||||||
#include <libxml/nanohttp.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/* TODO
|
|
||||||
1) Lots of error checking
|
|
||||||
2) xmlRpcValueToSexpr
|
|
||||||
*/
|
|
||||||
|
|
||||||
static xmlNodePtr xmlFirstElement(xmlNodePtr node);
|
|
||||||
static xmlNodePtr xmlNextElement(xmlNodePtr node);
|
|
||||||
|
|
||||||
struct _xmlRpcContext
|
|
||||||
{
|
|
||||||
char *uri;
|
|
||||||
int faultCode;
|
|
||||||
char *faultMessage;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void xmlRpcError(virErrorNumber error, const char *info, int value)
|
|
||||||
{
|
|
||||||
const char *errmsg;
|
|
||||||
|
|
||||||
if (error == VIR_ERR_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
errmsg = virErrorMsg(error, info);
|
|
||||||
virRaiseError(NULL, NULL, NULL, VIR_FROM_RPC, error, VIR_ERR_ERROR,
|
|
||||||
errmsg, info, NULL, value, 0, errmsg, info, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueNew(xmlRpcValueType type)
|
|
||||||
{
|
|
||||||
xmlRpcValuePtr ret = NULL;
|
|
||||||
if (VIR_ALLOC(ret) < 0)
|
|
||||||
xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate value"), sizeof(*ret));
|
|
||||||
else
|
|
||||||
ret->kind = type;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *xmlGetText(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
for (node = node->children; node; node = node->next)
|
|
||||||
if (node->type == XML_TEXT_NODE) {
|
|
||||||
char *x = strdup((const char *)node->content);
|
|
||||||
if (!x)
|
|
||||||
xmlRpcError(VIR_ERR_NO_MEMORY, _("copying node content"),
|
|
||||||
strlen((const char *)node->content));
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlNodePtr xmlFirstElement(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
for (node = node->children; node; node = node->next)
|
|
||||||
if (node->type == XML_ELEMENT_NODE)
|
|
||||||
break;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlNodePtr xmlNextElement(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
for (node = node->next; node; node = node->next)
|
|
||||||
if (node->type == XML_ELEMENT_NODE)
|
|
||||||
break;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalDateTime(xmlNodePtr node ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
/* we don't need this */
|
|
||||||
TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalString(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_STRING);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
ret->value.string = xmlGetText(node);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalBase64(xmlNodePtr node ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
/* we don't need this */
|
|
||||||
TODO
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalInteger(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_INTEGER);
|
|
||||||
char *value = xmlGetText(node);
|
|
||||||
|
|
||||||
if (ret && value)
|
|
||||||
ret->value.integer = atoi(value);
|
|
||||||
VIR_FREE(value);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalBoolean(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_BOOLEAN);
|
|
||||||
char *value = xmlGetText(node);
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
return NULL;
|
|
||||||
if (value && atoi(value))
|
|
||||||
ret->value.boolean = true;
|
|
||||||
else
|
|
||||||
ret->value.boolean = false;
|
|
||||||
VIR_FREE(value);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalDouble(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_DOUBLE);
|
|
||||||
char *value = xmlGetText(node);
|
|
||||||
|
|
||||||
if (ret && value)
|
|
||||||
ret->value.real = atof(value);
|
|
||||||
VIR_FREE(value);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalArray(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_ARRAY);
|
|
||||||
xmlNodePtr cur;
|
|
||||||
int n_elements = 0;
|
|
||||||
xmlRpcValuePtr *elems;
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur))
|
|
||||||
n_elements += 1;
|
|
||||||
|
|
||||||
if (VIR_ALLOC_N(elems, n_elements) < 0) {
|
|
||||||
xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate value array"),
|
|
||||||
n_elements * sizeof(*elems));
|
|
||||||
VIR_FREE(ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
n_elements = 0;
|
|
||||||
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
|
|
||||||
elems[n_elements] = xmlRpcValueUnmarshal(cur);
|
|
||||||
n_elements += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->value.array.elements = elems;
|
|
||||||
ret->value.array.n_elements = n_elements;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValueDictElementPtr xmlRpcValueUnmarshalDictElement(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
xmlRpcValueDictElementPtr ret;
|
|
||||||
xmlNodePtr cur;
|
|
||||||
|
|
||||||
if (VIR_ALLOC(ret) < 0) {
|
|
||||||
xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate dict"), sizeof(*ret));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memset(ret, 0, sizeof(*ret));
|
|
||||||
|
|
||||||
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
|
|
||||||
if (xmlStrEqual(cur->name, BAD_CAST "name")) {
|
|
||||||
ret->name = xmlGetText(cur);
|
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "value")) {
|
|
||||||
ret->value = xmlRpcValueUnmarshal(cur);
|
|
||||||
} else {
|
|
||||||
xmlRpcError(VIR_ERR_XML_ERROR, _("unexpected dict node"), 0);
|
|
||||||
VIR_FREE(ret->name);
|
|
||||||
if (ret->value)
|
|
||||||
xmlRpcValueFree(ret->value);
|
|
||||||
VIR_FREE(ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->next = NULL;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalDict(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
xmlRpcValueDictElementPtr root = NULL, *elem = &root;
|
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_STRUCT);
|
|
||||||
xmlNodePtr cur;
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret->value.dict.root = root;
|
|
||||||
|
|
||||||
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
|
|
||||||
*elem = xmlRpcValueUnmarshalDictElement(cur);
|
|
||||||
if (*elem==NULL) {
|
|
||||||
xmlRpcValueFree(ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
elem = &(*elem)->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlRpcValuePtr xmlRpcValueUnmarshal(xmlNodePtr node)
|
|
||||||
{
|
|
||||||
xmlNodePtr n;
|
|
||||||
xmlRpcValuePtr ret = NULL;
|
|
||||||
|
|
||||||
if (xmlStrEqual(node->name, BAD_CAST "value")) {
|
|
||||||
n = xmlFirstElement(node);
|
|
||||||
if (n == NULL) {
|
|
||||||
ret = xmlRpcValueUnmarshalString(node);
|
|
||||||
} else {
|
|
||||||
ret = xmlRpcValueUnmarshal(n);
|
|
||||||
}
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "dateTime.iso8601")) {
|
|
||||||
ret = xmlRpcValueUnmarshalDateTime(node);
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "string")) {
|
|
||||||
ret = xmlRpcValueUnmarshalString(node);
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "base64")) {
|
|
||||||
ret = xmlRpcValueUnmarshalBase64(node);
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "i4") ||
|
|
||||||
xmlStrEqual(node->name, BAD_CAST "int")) {
|
|
||||||
ret = xmlRpcValueUnmarshalInteger(node);
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "boolean")) {
|
|
||||||
ret = xmlRpcValueUnmarshalBoolean(node);
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "double")) {
|
|
||||||
ret = xmlRpcValueUnmarshalDouble(node);
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "array")) {
|
|
||||||
ret = xmlRpcValueUnmarshal(xmlFirstElement(node));
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "data")) {
|
|
||||||
ret = xmlRpcValueUnmarshalArray(node);
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "struct")) {
|
|
||||||
ret = xmlRpcValueUnmarshalDict(node);
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "nil")) {
|
|
||||||
ret = xmlRpcValueNew(XML_RPC_NIL);
|
|
||||||
} else {
|
|
||||||
xmlRpcError(VIR_ERR_XML_ERROR, _("unexpected value node"), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xmlRpcValueFree(xmlRpcValuePtr value)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
xmlRpcValueDictElementPtr cur, next;
|
|
||||||
|
|
||||||
if (value == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (value->kind) {
|
|
||||||
case XML_RPC_ARRAY:
|
|
||||||
for (i = 0; i < value->value.array.n_elements; i++)
|
|
||||||
xmlRpcValueFree(value->value.array.elements[i]);
|
|
||||||
VIR_FREE(value->value.array.elements);
|
|
||||||
break;
|
|
||||||
case XML_RPC_STRUCT:
|
|
||||||
next = value->value.dict.root;
|
|
||||||
while (next) {
|
|
||||||
cur = next;
|
|
||||||
next = next->next;
|
|
||||||
VIR_FREE(cur->name);
|
|
||||||
xmlRpcValueFree(cur->value);
|
|
||||||
VIR_FREE(cur);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case XML_RPC_STRING:
|
|
||||||
VIR_FREE(value->value.string);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
VIR_FREE(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void xmlRpcValueMarshal(xmlRpcValuePtr value, virBufferPtr buf, int indent)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
xmlRpcValueDictElement *elem;
|
|
||||||
|
|
||||||
virBufferVSprintf(buf, "%*s<value>", indent, "");
|
|
||||||
switch (value->kind) {
|
|
||||||
case XML_RPC_ARRAY:
|
|
||||||
virBufferStrcat(buf, "<array><data>\n", NULL);
|
|
||||||
for (i = 0; i < value->value.array.n_elements; i++)
|
|
||||||
xmlRpcValueMarshal(value->value.array.elements[i], buf, indent+2);
|
|
||||||
virBufferVSprintf(buf, "%*s</data></array>", indent, "");
|
|
||||||
break;
|
|
||||||
case XML_RPC_STRUCT:
|
|
||||||
virBufferStrcat(buf, "<struct>\n", NULL);
|
|
||||||
indent += 2;
|
|
||||||
for (elem = value->value.dict.root; elem; elem = elem->next) {
|
|
||||||
virBufferVSprintf(buf, "%*s<member>\n", indent, "");
|
|
||||||
virBufferVSprintf(buf, "%*s<name>%s</name>\n",
|
|
||||||
indent + 2, "", elem->name);
|
|
||||||
xmlRpcValueMarshal(elem->value, buf, indent + 2);
|
|
||||||
virBufferVSprintf(buf, "%*s</member>\n", indent, "");
|
|
||||||
}
|
|
||||||
indent -= 2;
|
|
||||||
virBufferVSprintf(buf, "%*s</struct>", indent, "");
|
|
||||||
break;
|
|
||||||
case XML_RPC_INTEGER:
|
|
||||||
virBufferVSprintf(buf, "<int>%d</int>", value->value.integer);
|
|
||||||
break;
|
|
||||||
case XML_RPC_DOUBLE:
|
|
||||||
virBufferVSprintf(buf, "<double>%f</double>", value->value.real);
|
|
||||||
break;
|
|
||||||
case XML_RPC_BOOLEAN:
|
|
||||||
if (value->value.boolean)
|
|
||||||
i = 1;
|
|
||||||
else
|
|
||||||
i = 0;
|
|
||||||
virBufferVSprintf(buf, "<boolean>%d</boolean>", i);
|
|
||||||
break;
|
|
||||||
case XML_RPC_DATE_TIME:
|
|
||||||
/* FIXME */
|
|
||||||
TODO
|
|
||||||
break;
|
|
||||||
case XML_RPC_BASE64:
|
|
||||||
/* FIXME */
|
|
||||||
TODO
|
|
||||||
break;
|
|
||||||
case XML_RPC_STRING:
|
|
||||||
virBufferStrcat(buf,
|
|
||||||
"<string>", value->value.string, "</string>", NULL);
|
|
||||||
break;
|
|
||||||
case XML_RPC_NIL:
|
|
||||||
virBufferStrcat(buf, "<nil> </nil>", NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
virBufferStrcat(buf, "</value>\n", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void xmlRpcMarshalRequest(const char *request,
|
|
||||||
virBufferPtr buf,
|
|
||||||
int argc, xmlRpcValuePtr *argv)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
virBufferStrcat(buf,
|
|
||||||
"<?xml version=\"1.0\"?>\n"
|
|
||||||
"<methodCall>\n"
|
|
||||||
" <methodName>", request, "</methodName>\n"
|
|
||||||
" <params>\n", NULL);
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
virBufferStrcat(buf,
|
|
||||||
" <param>\n", NULL);
|
|
||||||
xmlRpcValueMarshal(argv[i], buf, 6);
|
|
||||||
virBufferStrcat(buf,
|
|
||||||
" </param>\n", NULL);
|
|
||||||
}
|
|
||||||
virBufferStrcat(buf,
|
|
||||||
" </params>\n"
|
|
||||||
"</methodCall>\n", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlRpcValuePtr xmlRpcUnmarshalResponse(xmlNodePtr node, bool *is_fault)
|
|
||||||
{
|
|
||||||
if (!node)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!xmlStrEqual(node->name, BAD_CAST "methodResponse"))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
node = xmlFirstElement(node);
|
|
||||||
if (xmlStrEqual(node->name, BAD_CAST "params")) {
|
|
||||||
node = xmlFirstElement(node);
|
|
||||||
|
|
||||||
if (!xmlStrEqual(node->name, BAD_CAST "param"))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
*is_fault = false;
|
|
||||||
return xmlRpcValueUnmarshal(xmlFirstElement(node));
|
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "fault")) {
|
|
||||||
*is_fault = true;
|
|
||||||
return xmlRpcValueUnmarshal(xmlFirstElement(node));
|
|
||||||
} else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *xmlRpcCallRaw(const char *url, const char *request)
|
|
||||||
{
|
|
||||||
void *cxt;
|
|
||||||
char *contentType = (char *) "text/xml";
|
|
||||||
int len, ret, serrno;
|
|
||||||
char *response = NULL;
|
|
||||||
|
|
||||||
cxt = xmlNanoHTTPMethod(url,
|
|
||||||
"POST",
|
|
||||||
request,
|
|
||||||
&contentType,
|
|
||||||
NULL,
|
|
||||||
strlen(request));
|
|
||||||
|
|
||||||
if (cxt == NULL) {
|
|
||||||
xmlRpcError(VIR_ERR_POST_FAILED, _("send request"), 0);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contentType && STRNEQ(contentType, "text/xml")) {
|
|
||||||
errno = EINVAL;
|
|
||||||
xmlRpcError(VIR_ERR_POST_FAILED, _("unexpected mime type"), 0);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = xmlNanoHTTPContentLength(cxt);
|
|
||||||
if (VIR_ALLOC_N(response, len + 1) < 0) {
|
|
||||||
xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate response"), len);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
ret = xmlNanoHTTPRead(cxt, response, len);
|
|
||||||
if (ret != len) {
|
|
||||||
errno = EINVAL;
|
|
||||||
VIR_FREE(response);
|
|
||||||
xmlRpcError(VIR_ERR_POST_FAILED, _("read response"), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
response[len] = 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
serrno = errno;
|
|
||||||
if (cxt) {
|
|
||||||
xmlNanoHTTPClose(cxt);
|
|
||||||
VIR_FREE(contentType);
|
|
||||||
}
|
|
||||||
errno = serrno;
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char **xmlRpcStringArray(xmlRpcValuePtr value)
|
|
||||||
{
|
|
||||||
char **ret, *ptr;
|
|
||||||
int i;
|
|
||||||
size_t size = 0;
|
|
||||||
|
|
||||||
if (value->kind != XML_RPC_ARRAY)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
size = sizeof(char *) * (value->value.array.n_elements + 1);
|
|
||||||
|
|
||||||
for (i = 0; i < value->value.array.n_elements; i++)
|
|
||||||
if (value->value.array.elements[i]->kind == XML_RPC_STRING)
|
|
||||||
size += strlen(value->value.array.elements[i]->value.string) + 1;
|
|
||||||
|
|
||||||
if (VIR_ALLOC_N(ptr, size) < 0) {
|
|
||||||
xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate string array"), size);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ret = (char **)ptr;
|
|
||||||
ptr += sizeof(char *) * (value->value.array.n_elements + 1);
|
|
||||||
|
|
||||||
for (i = 0; i < value->value.array.n_elements; i++) {
|
|
||||||
if (value->value.array.elements[i]->kind == XML_RPC_STRING) {
|
|
||||||
char *s = value->value.array.elements[i]->value.string;
|
|
||||||
strcpy(ptr, s);
|
|
||||||
ret[i] = ptr;
|
|
||||||
ptr += strlen(s) + 1;
|
|
||||||
} else
|
|
||||||
ret[i] = (char *) "";
|
|
||||||
}
|
|
||||||
|
|
||||||
ret[i] = NULL;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlRpcValuePtr *
|
|
||||||
xmlRpcArgvNew(const char *fmt, va_list ap, int *argc)
|
|
||||||
{
|
|
||||||
xmlRpcValuePtr *argv;
|
|
||||||
const char *ptr;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
*argc = strlen(fmt);
|
|
||||||
if (VIR_ALLOC_N(argv, *argc) < 0) {
|
|
||||||
xmlRpcError(VIR_ERR_NO_MEMORY, _("read response"), sizeof(*argv) * *argc);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
for (ptr = fmt; *ptr; ptr++) {
|
|
||||||
switch (*ptr) {
|
|
||||||
case 'i':
|
|
||||||
if ((argv[i] = xmlRpcValueNew(XML_RPC_INTEGER)))
|
|
||||||
argv[i]->value.integer = va_arg(ap, int32_t);
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
if ((argv[i] = xmlRpcValueNew(XML_RPC_DOUBLE)))
|
|
||||||
argv[i]->value.real = va_arg(ap, double);
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
if ((argv[i] = xmlRpcValueNew(XML_RPC_BOOLEAN)))
|
|
||||||
argv[i]->value.boolean = va_arg(ap, int);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
if ((argv[i] = xmlRpcValueNew(XML_RPC_STRING)))
|
|
||||||
argv[i]->value.string = strdup(va_arg(ap, const char *));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
argv[i] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (argv[i]==NULL) {
|
|
||||||
xmlRpcArgvFree(i, argv);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return argv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
xmlRpcArgvFree(int argc, xmlRpcValuePtr *argv)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (!argv)
|
|
||||||
return;
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
xmlRpcValueFree(argv[i]);
|
|
||||||
|
|
||||||
VIR_FREE(argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
int xmlRpcCall(xmlRpcContextPtr context, const char *method,
|
|
||||||
const char *retfmt, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int argc;
|
|
||||||
xmlRpcValuePtr *argv;
|
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
||||||
char *ret;
|
|
||||||
xmlDocPtr xml;
|
|
||||||
xmlNodePtr node;
|
|
||||||
bool fault;
|
|
||||||
xmlRpcValuePtr value;
|
|
||||||
void *retval = NULL;
|
|
||||||
char *content;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
|
|
||||||
if (retfmt && *retfmt)
|
|
||||||
retval = va_arg(ap, void *);
|
|
||||||
|
|
||||||
if (!(argv = xmlRpcArgvNew(fmt, ap, &argc)))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
xmlRpcMarshalRequest(method, &buf, argc, argv);
|
|
||||||
|
|
||||||
xmlRpcArgvFree(argc, argv);
|
|
||||||
|
|
||||||
if (virBufferError(&buf))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
content = virBufferContentAndReset(&buf);
|
|
||||||
ret = xmlRpcCallRaw(context->uri, content);
|
|
||||||
VIR_FREE(content);
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
xml = xmlReadDoc((const xmlChar *)ret, "response.xml", NULL,
|
|
||||||
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
||||||
XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
|
|
||||||
VIR_FREE(ret);
|
|
||||||
|
|
||||||
if (xml == NULL) {
|
|
||||||
errno = EINVAL;
|
|
||||||
xmlRpcError(VIR_ERR_XML_ERROR, _("parse server response failed"), 0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
node = xmlDocGetRootElement(xml);
|
|
||||||
|
|
||||||
value = xmlRpcUnmarshalResponse(node, &fault);
|
|
||||||
|
|
||||||
if (!fault) {
|
|
||||||
switch (*retfmt) {
|
|
||||||
case 'i':
|
|
||||||
if (value->kind == XML_RPC_INTEGER)
|
|
||||||
*(int32_t *)retval = value->value.integer;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
if (value->kind == XML_RPC_BOOLEAN)
|
|
||||||
*(bool *)retval = value->value.boolean;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
if (value->kind == XML_RPC_DOUBLE)
|
|
||||||
*(double *)retval = value->value.real;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
if (value->kind == XML_RPC_STRING)
|
|
||||||
*(char **)retval = strdup(value->value.string);
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
*(char ***)retval = xmlRpcStringArray(value);
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
*(xmlRpcValuePtr *)retval = value;
|
|
||||||
value = NULL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("not supported yet\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlFreeDoc(xml);
|
|
||||||
|
|
||||||
if (fault) {
|
|
||||||
/* FIXME we need generic dict routines */
|
|
||||||
/* FIXME we need faultMessage propagate to libvirt error API */
|
|
||||||
context->faultCode = value->value.dict.root->value->value.integer;
|
|
||||||
context->faultMessage = strdup(value->value.dict.root->next->value->value.string);
|
|
||||||
xmlRpcValueFree(value);
|
|
||||||
errno = EFAULT;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlRpcValueFree(value);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlRpcContextPtr xmlRpcContextNew(const char *uri)
|
|
||||||
{
|
|
||||||
xmlRpcContextPtr ret;
|
|
||||||
|
|
||||||
if (VIR_ALLOC(ret) < 0) {
|
|
||||||
xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate new context"), sizeof(*ret));
|
|
||||||
} else {
|
|
||||||
ret->uri = strdup(uri);
|
|
||||||
ret->faultMessage = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xmlRpcContextFree(xmlRpcContextPtr context)
|
|
||||||
{
|
|
||||||
if (context) {
|
|
||||||
VIR_FREE(context->uri);
|
|
||||||
VIR_FREE(context->faultMessage);
|
|
||||||
VIR_FREE(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int xmlRpcContextFaultCode(xmlRpcContextPtr context)
|
|
||||||
{
|
|
||||||
return context->faultCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *xmlRpcContextFaultMessage(xmlRpcContextPtr context)
|
|
||||||
{
|
|
||||||
return context->faultMessage;
|
|
||||||
}
|
|
115
src/xmlrpc.h
115
src/xmlrpc.h
@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* xmlrpc.c: XML-RPC protocol handler for libvir library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 IBM, Corp.
|
|
||||||
*
|
|
||||||
* See COPYING.LIB for the License of this software
|
|
||||||
*
|
|
||||||
* Anthony Liguori <aliguori@us.ibm.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _VIR_XML_RPC_H_
|
|
||||||
#define _VIR_XML_RPC_H_
|
|
||||||
|
|
||||||
#include <libxml/parser.h>
|
|
||||||
#include <libxml/tree.h>
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#include "buf.h"
|
|
||||||
|
|
||||||
typedef enum _xmlRpcValueType xmlRpcValueType;
|
|
||||||
|
|
||||||
typedef struct _xmlRpcValueArray xmlRpcValueArray;
|
|
||||||
typedef struct _xmlRpcValueDictElement xmlRpcValueDictElement;
|
|
||||||
typedef struct _xmlRpcValueDict xmlRpcValueDict;
|
|
||||||
typedef struct _xmlRpcValueBase64 xmlRpcValueBase64;
|
|
||||||
typedef struct _xmlRpcValue xmlRpcValue;
|
|
||||||
typedef struct _xmlRpcContext xmlRpcContext;
|
|
||||||
|
|
||||||
typedef xmlRpcValueArray *xmlRpcValueArrayPtr;
|
|
||||||
typedef xmlRpcValueDictElement *xmlRpcValueDictElementPtr;
|
|
||||||
typedef xmlRpcValueDict *xmlRpcValueDictPtr;
|
|
||||||
typedef xmlRpcValueBase64 *xmlRpcValueBase64Ptr;
|
|
||||||
typedef xmlRpcValue *xmlRpcValuePtr;
|
|
||||||
typedef xmlRpcContext *xmlRpcContextPtr;
|
|
||||||
|
|
||||||
enum _xmlRpcValueType {
|
|
||||||
XML_RPC_ARRAY,
|
|
||||||
XML_RPC_STRUCT,
|
|
||||||
XML_RPC_INTEGER,
|
|
||||||
XML_RPC_DOUBLE,
|
|
||||||
XML_RPC_BOOLEAN,
|
|
||||||
XML_RPC_DATE_TIME,
|
|
||||||
XML_RPC_BASE64,
|
|
||||||
XML_RPC_STRING,
|
|
||||||
XML_RPC_NIL,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _xmlRpcValueArray {
|
|
||||||
int n_elements;
|
|
||||||
xmlRpcValuePtr *elements;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _xmlRpcValueDictElement {
|
|
||||||
char *name;
|
|
||||||
xmlRpcValuePtr value;
|
|
||||||
xmlRpcValueDictElementPtr next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _xmlRpcValueDict {
|
|
||||||
xmlRpcValueDictElementPtr root;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _xmlRpcValueBase64 {
|
|
||||||
void *data;
|
|
||||||
size_t n_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _xmlRpcValue {
|
|
||||||
xmlRpcValueType kind;
|
|
||||||
|
|
||||||
union {
|
|
||||||
char *string;
|
|
||||||
xmlRpcValueArray array;
|
|
||||||
xmlRpcValueDict dict;
|
|
||||||
int32_t integer;
|
|
||||||
double real;
|
|
||||||
bool boolean;
|
|
||||||
time_t dateTime;
|
|
||||||
xmlRpcValueBase64 base64;
|
|
||||||
} value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _xmlRpcContext;
|
|
||||||
|
|
||||||
xmlRpcValuePtr *xmlRpcArgvNew(const char *fmt, va_list ap, int *argc);
|
|
||||||
void xmlRpcArgvFree(int argc, xmlRpcValuePtr *argv);
|
|
||||||
|
|
||||||
void xmlRpcMarshalRequest(const char *request,
|
|
||||||
virBufferPtr buf,
|
|
||||||
int argc, xmlRpcValuePtr *argv);
|
|
||||||
|
|
||||||
xmlRpcValuePtr xmlRpcUnmarshalResponse(xmlNodePtr node, bool *is_fault);
|
|
||||||
|
|
||||||
void xmlRpcValueMarshal(xmlRpcValuePtr value, virBufferPtr buf, int indent);
|
|
||||||
|
|
||||||
xmlRpcValuePtr xmlRpcValueUnmarshal(xmlNodePtr node);
|
|
||||||
|
|
||||||
void xmlRpcValueFree(xmlRpcValuePtr value);
|
|
||||||
|
|
||||||
int xmlRpcCall(xmlRpcContextPtr context, const char *method,
|
|
||||||
const char *retval, const char *fmt, ...);
|
|
||||||
|
|
||||||
xmlRpcContextPtr xmlRpcContextNew(const char *uri);
|
|
||||||
|
|
||||||
void xmlRpcContextFree(xmlRpcContextPtr context);
|
|
||||||
|
|
||||||
int xmlRpcContextFaultCode(xmlRpcContextPtr context);
|
|
||||||
|
|
||||||
const char *xmlRpcContextFaultMessage(xmlRpcContextPtr context);
|
|
||||||
|
|
||||||
#endif
|
|
@ -2,7 +2,6 @@ Makefile
|
|||||||
Makefile.in
|
Makefile.in
|
||||||
.deps
|
.deps
|
||||||
.libs
|
.libs
|
||||||
xmlrpctest
|
|
||||||
sexpr2xmltest
|
sexpr2xmltest
|
||||||
xml2sexprtest
|
xml2sexprtest
|
||||||
virshtest
|
virshtest
|
||||||
|
@ -38,13 +38,12 @@ LDADDS = \
|
|||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
oomtrace.pl \
|
oomtrace.pl \
|
||||||
test-lib.sh \
|
test-lib.sh \
|
||||||
xmlrpcserver.py \
|
|
||||||
qemuxml2argvdata \
|
qemuxml2argvdata \
|
||||||
nodeinfodata \
|
nodeinfodata \
|
||||||
domainschematest \
|
domainschematest \
|
||||||
domainschemadata
|
domainschemadata
|
||||||
|
|
||||||
noinst_PROGRAMS = xmlrpctest virshtest conftest \
|
noinst_PROGRAMS = virshtest conftest \
|
||||||
nodeinfotest statstest qparamtest
|
nodeinfotest statstest qparamtest
|
||||||
|
|
||||||
if WITH_XEN
|
if WITH_XEN
|
||||||
@ -111,15 +110,6 @@ TESTS_ENVIRONMENT = \
|
|||||||
valgrind:
|
valgrind:
|
||||||
$(MAKE) check VG="valgrind --quiet --leak-check=full --suppressions=$(srcdir)/.valgrind.supp"
|
$(MAKE) check VG="valgrind --quiet --leak-check=full --suppressions=$(srcdir)/.valgrind.supp"
|
||||||
|
|
||||||
# Note: xmlrpc.[c|h] is not in libvirt yet
|
|
||||||
xmlrpctest_SOURCES = \
|
|
||||||
xmlrpctest.c \
|
|
||||||
testutils.c testutils.h \
|
|
||||||
@top_srcdir@/src/xmlrpc.c \
|
|
||||||
@top_srcdir@/src/xmlrpc.h
|
|
||||||
|
|
||||||
xmlrpctest_LDADD = $(LDADDS)
|
|
||||||
|
|
||||||
if WITH_XEN
|
if WITH_XEN
|
||||||
xml2sexprtest_SOURCES = \
|
xml2sexprtest_SOURCES = \
|
||||||
xml2sexprtest.c testutilsxen.c testutilsxen.h \
|
xml2sexprtest.c testutilsxen.c testutilsxen.h \
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
./xmlrpcserver.py >/dev/null 2>&1 &
|
|
||||||
sleep 1
|
|
||||||
./xmlrpctest
|
|
||||||
pkill -f xmlrpcserver.py >/dev/null 2>&1 &
|
|
@ -1,49 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
#
|
|
||||||
# xmlrpcserver.py: simple server for XML-RPC tests
|
|
||||||
#
|
|
||||||
# Copyright (C) 2005 Red Hat, Inc.
|
|
||||||
#
|
|
||||||
# See COPYING.LIB for the License of this software
|
|
||||||
#
|
|
||||||
# Karel Zak <kzak@redhat.com>
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# simple client:
|
|
||||||
#
|
|
||||||
# >>> import xmlrpclib
|
|
||||||
# >>> s=xmlrpclib.Server('http://localhost:8000')
|
|
||||||
# >>> s.plus(10,10)
|
|
||||||
# 20
|
|
||||||
#
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from SimpleXMLRPCServer import SimpleXMLRPCServer
|
|
||||||
|
|
||||||
SERVER_PORT = 8000
|
|
||||||
|
|
||||||
|
|
||||||
class VirtRPCServer(SimpleXMLRPCServer):
|
|
||||||
def _dispatch(self, method, params):
|
|
||||||
try:
|
|
||||||
func = getattr(self, 'test_' + method)
|
|
||||||
except AttributeError:
|
|
||||||
raise Exception('method "%s" is not supported' % method)
|
|
||||||
else:
|
|
||||||
return func(*params)
|
|
||||||
|
|
||||||
def test_plus(self, x, y):
|
|
||||||
return x + y
|
|
||||||
|
|
||||||
|
|
||||||
server = VirtRPCServer(("localhost", SERVER_PORT))
|
|
||||||
server.serve_forever()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# vim: set tabstop=4:
|
|
||||||
# vim: set shiftwidth=4:
|
|
||||||
# vim: set expandtab:
|
|
@ -1,269 +0,0 @@
|
|||||||
/*
|
|
||||||
* xmlrpctest.c: simple client for XML-RPC tests
|
|
||||||
*
|
|
||||||
* Copyright (C) 2005, 2008 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* See COPYING.LIB for the License of this software
|
|
||||||
*
|
|
||||||
* Karel Zak <kzak@redhat.com>
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <libxml/parser.h>
|
|
||||||
#include <libxml/tree.h>
|
|
||||||
#include <libxml/xpath.h>
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
#include "buf.h"
|
|
||||||
#include "xmlrpc.h"
|
|
||||||
|
|
||||||
#include "testutils.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define NLOOPS 100 /* default number of loops per test */
|
|
||||||
|
|
||||||
static char *progname;
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
testMethodPlusINT(const void *data)
|
|
||||||
{
|
|
||||||
int retval = 0;
|
|
||||||
xmlRpcContextPtr cxt = (xmlRpcContextPtr) data;
|
|
||||||
|
|
||||||
if (xmlRpcCall(cxt, "plus", "i", "ii",
|
|
||||||
(const char *) &retval, 10, 10) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return retval==(10+10) ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
testMethodPlusDOUBLE(const void *data)
|
|
||||||
{
|
|
||||||
double retval = 0;
|
|
||||||
xmlRpcContextPtr cxt = (xmlRpcContextPtr) data;
|
|
||||||
|
|
||||||
if (xmlRpcCall(cxt, "plus", "f", "ff",
|
|
||||||
(const char *) &retval, 10.1234, 10.1234) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return retval==(10.1234+10.1234) ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
marshalRequest(virBufferPtr buf, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
int argc;
|
|
||||||
xmlRpcValuePtr *argv;
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
argv = xmlRpcArgvNew(fmt, ap, &argc);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
xmlRpcMarshalRequest("test", buf, argc, argv);
|
|
||||||
|
|
||||||
xmlRpcArgvFree(argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
checkRequestValue(const char *xmlstr, const char *xpath, int type, void *expected)
|
|
||||||
{
|
|
||||||
xmlDocPtr xml = NULL;
|
|
||||||
xmlXPathContextPtr ctxt = NULL;
|
|
||||||
xmlXPathObjectPtr obj = NULL;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
xml = xmlReadDoc((const xmlChar *) xmlstr, "xmlrpctest.xml", NULL,
|
|
||||||
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
||||||
XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
|
|
||||||
if (!xml)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!(ctxt = xmlXPathNewContext(xml)))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (!(obj = xmlXPathEval(BAD_CAST xpath, ctxt)))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
switch(type) {
|
|
||||||
case XML_RPC_INTEGER:
|
|
||||||
if ((obj->type != XPATH_NUMBER) ||
|
|
||||||
((int) obj->floatval != *((int *)expected)))
|
|
||||||
goto error;
|
|
||||||
break;
|
|
||||||
case XML_RPC_DOUBLE:
|
|
||||||
if ((obj->type != XPATH_NUMBER) ||
|
|
||||||
((double) obj->floatval != *((double *)expected)))
|
|
||||||
goto error;
|
|
||||||
break;
|
|
||||||
case XML_RPC_STRING:
|
|
||||||
if ((obj->type != XPATH_STRING) ||
|
|
||||||
(STRNEQ((const char *)obj->stringval, (const char *)expected)))
|
|
||||||
goto error;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
xmlXPathFreeContext(ctxt);
|
|
||||||
if (xml)
|
|
||||||
xmlFreeDoc(xml);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
testMarshalRequestINT(const void *data)
|
|
||||||
{
|
|
||||||
int num = INT_MAX;
|
|
||||||
int ret = 0;
|
|
||||||
int check = data ? *((int *)data) : 0;
|
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
||||||
marshalRequest(&buf, "i", num);
|
|
||||||
char *content;
|
|
||||||
|
|
||||||
if (virBufferError(&buf))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
content = virBufferContentAndReset(&buf);
|
|
||||||
|
|
||||||
if (check)
|
|
||||||
ret = checkRequestValue(content,
|
|
||||||
"number(/methodCall/params/param[1]/value/int)",
|
|
||||||
XML_RPC_INTEGER, (void *) &num);
|
|
||||||
|
|
||||||
free(content);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
testMarshalRequestSTRING(const void *data ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
const char *str = "This library will be really sexy.";
|
|
||||||
int ret = 0;
|
|
||||||
int check = data ? *((int *)data) : 0;
|
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
||||||
char *content;
|
|
||||||
|
|
||||||
marshalRequest(&buf, "s", str);
|
|
||||||
|
|
||||||
if (virBufferError(&buf))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
content = virBufferContentAndReset(&buf);
|
|
||||||
if (check)
|
|
||||||
ret = checkRequestValue(content,
|
|
||||||
"string(/methodCall/params/param[1]/value/string)",
|
|
||||||
XML_RPC_STRING, (void *) str);
|
|
||||||
|
|
||||||
free(content);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
testMarshalRequestDOUBLE(const void *data)
|
|
||||||
{
|
|
||||||
double num = 123456789.123;
|
|
||||||
int ret = 0;
|
|
||||||
int check = data ? *((int *)data) : 0;
|
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
||||||
char *content;
|
|
||||||
|
|
||||||
marshalRequest(&buf, "f", num);
|
|
||||||
|
|
||||||
if (virBufferError(&buf))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
content = virBufferContentAndReset(&buf);
|
|
||||||
if (check)
|
|
||||||
ret = checkRequestValue(content,
|
|
||||||
"number(/methodCall/params/param[1]/value/double)",
|
|
||||||
XML_RPC_DOUBLE, (void *) &num);
|
|
||||||
|
|
||||||
free(content);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
xmlRpcContextPtr cxt = NULL;
|
|
||||||
int check = 1;
|
|
||||||
int ret = 0;
|
|
||||||
const char *url = "http://localhost:8000";
|
|
||||||
|
|
||||||
progname = argv[0];
|
|
||||||
|
|
||||||
if (argc > 2)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage: %s [url]\n", progname);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if (argc == 2)
|
|
||||||
url = argv[1];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* client-server tests
|
|
||||||
*/
|
|
||||||
if (!(cxt = xmlRpcContextNew(url)))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s: failed create new RPC context\n", progname);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virtTestRun("XML-RPC methodCall INT+INT",
|
|
||||||
NLOOPS, testMethodPlusINT, (const void *) cxt) != 0)
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
if (virtTestRun("XML-RPC methodCall DOUBLE+DOUBLE",
|
|
||||||
NLOOPS, testMethodPlusDOUBLE, (const void *) cxt) != 0)
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
xmlRpcContextFree(cxt);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* regression / performance tests
|
|
||||||
*/
|
|
||||||
if (virtTestRun("XML-RPC request marshalling: INT (check)",
|
|
||||||
1, testMarshalRequestINT, (const void *) &check) != 0)
|
|
||||||
ret = -1;
|
|
||||||
if (virtTestRun("XML-RPC request marshalling: INT",
|
|
||||||
NLOOPS, testMarshalRequestINT, NULL) != 0)
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
if (virtTestRun("XML-RPC request marshalling: DOUBLE (check)",
|
|
||||||
1, testMarshalRequestDOUBLE, (const void *) &check) != 0)
|
|
||||||
ret = -1;
|
|
||||||
if (virtTestRun("XML-RPC request marshalling: DOUBLE",
|
|
||||||
NLOOPS, testMarshalRequestDOUBLE, NULL) != 0)
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
if (virtTestRun("XML-RPC request marshalling: STRING (check)",
|
|
||||||
1, testMarshalRequestSTRING, (void *) &check) != 0)
|
|
||||||
ret = -1;
|
|
||||||
if (virtTestRun("XML-RPC request marshalling: STRING",
|
|
||||||
NLOOPS, testMarshalRequestSTRING, NULL) != 0)
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* vim: set tabstop=4:
|
|
||||||
* vim: set shiftwidth=4:
|
|
||||||
* vim: set expandtab:
|
|
||||||
*/
|
|
Loading…
x
Reference in New Issue
Block a user