|
XML * ACTION_soap_do (WFTK_ADAPTOR * ad, va_list args)
{
XML * action = (XML *) 0;
XML * datasheet;
XML * soap_body;
XML * soap_env;
XML * soap_request;
XML * soap_parm;
XML * mark;
char * value;
char * soap_str;
XML * http_action;
XML * http_content;
WFTK_ADAPTOR * http_ad;
XML * soap_return;
XML * result_spec;
if (args) action = va_arg (args, XML *);
if (!action) {
xml_set (ad->parms, "error", "No action given.");
return (XML *) 0;
}
datasheet = va_arg (args, XML *);
if (!*xml_attrval (action, "server")) {
xml_set (ad->parms, "error", "No server specified in action.");
return NULL;
}
http_ad = wftk_get_adaptor (ad->session, ACTION, "http");
if (!http_ad) {
xml_set (ad->parms, "error", "Unable to initialize libcurl");
return NULL;
}
/* All right, everything's hunky-dory; down to business. */
/* Build SOAP request. */
soap_env = xml_create ("SOAP-ENV:Envelope");
xml_set (soap_env, "SOAP-ENV:encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/");
xml_set (soap_env, "xmlns:xsd", "http://www.w3.org/1999/XMLSchema");
xml_set (soap_env, "xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
xml_set (soap_env, "xmlns:xsi", "http://www.w3.org/1999/XMLSchema-instance");
xml_set (soap_env, "xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/");
soap_body = xml_create ("SOAP-ENV:Body");
xml_append_pretty (soap_env, soap_body);
soap_request = xml_create (xml_attrval (action, "function"));
xml_append_pretty (soap_body, soap_request);
xml_set (soap_request, "SOAP-ENC:root", "1");
mark = xml_firstelem (action);
while (mark) {
if (xml_is (mark, "parm")) {
soap_parm = xml_create (xml_attrval (mark, "name"));
xml_set (soap_parm, "xsi:type", *xml_attrval (mark, "xsi:type") ? xml_attrval (mark, "xsi:type") : "xsd:string");
if (*xml_attrval (mark, "field")) {
value = xmlobj_get (datasheet, NULL, xml_attrval (mark, "field"));
} else {
value = xmlobj_get_direct (mark);
}
xml_append (soap_parm, xml_createtext_nodup (value));
xml_append_pretty (soap_request, soap_parm);
}
mark = xml_nextelem (mark);
}
soap_str = xml_string (soap_env);
xml_free (soap_env);
/* Build HTTP request. */
http_action = xml_create ("action");
xml_set (http_action, "url", xml_attrval (action, "server"));
xml_set (http_action, "method", "post");
http_content = xml_createtext ("\n");
xml_textcat (http_content, soap_str);
xml_textcat (http_content, "\n");
mark = xml_create ("content");
xml_append (mark, http_content);
xml_append_pretty (http_action, mark);
free (soap_str);
/* Perform request. */
wftk_call_adaptor (http_ad, "do", http_action, datasheet);
if (!strcmp (xml_attrval (http_action, "http-retcode"), "500")) {
xml_set (ad->parms, "error", "Remote server experienced server error (code: 500)");
}
result_spec = xml_loc (action, ".result");
if (result_spec) {
/* Interpret results. */
soap_str = xml_stringcontenthtml (xml_loc (http_action, ".result"));
soap_return = xml_parse (soap_str);
free (soap_str);
xml_free (http_action);
soap_body = xml_firstelem (soap_return); /* TODO: do we care about multiple bodies? At the moment, no.*/
soap_body = xml_firstelem (soap_body); /* TODO: how about multiple responses in one body? Same answer at present. */
if (*xml_attrval (result_spec, "field")) {
mark = xml_firstelem (soap_body); /* First approximation: take the first value in the response and run with it. */
value = xml_stringcontent (mark);
xmlobj_set_nodup (datasheet, NULL, xml_attrval (result_spec, "field"), value);
}
xml_append_pretty (result_spec, xml_copy (soap_body));
xml_free (soap_return);
}
}
|