/** * Create a new comment node, inserted under parent node as the last child. * * @param parent the parent node (NULL creates a standalone node * @param text the comment text, copied ("--" will be emitted as "- -") */ xnode_t * xnode_new_comment(xnode_t *parent, const char *text) { xnode_t *xn; g_assert(text != NULL); xn = xnode_new(XNODE_T_COMMENT); xn->u.c.text = h_strdup(text); if (parent != NULL) xnode_add_child(parent, xn); return xn; }
/** * Create a new text node, inserted under parent node as the last child.. * * When created as verbatim, any '&' character is left as-is, otherwise they * are escaped. All '<' and '>' are escaped regardless. * * @param parent the parent node (NULL creates a standalone node * @param text the text * @param verbatim whether text is to be emitted verbatim or escaped */ xnode_t * xnode_new_text(xnode_t *parent, const char *text, bool verbatim) { xnode_t *xn; g_assert(text != NULL); xn = xnode_new(XNODE_T_TEXT); xn->u.t.text = h_strdup(text); xn->u.t.asis = booleanize(verbatim); if (parent != NULL) xnode_add_child(parent, xn); return xn; }
/** * Create a new element tag node, inserted under parent node as the last child. * * @param parent the parent node (NULL creates a standalone node) * @param ns the namespace URI (NULL if none) * @param name the element's name (copied) */ xnode_t * xnode_new_element(xnode_t *parent, const char *ns, const char *name) { xnode_t *xn; g_assert(name != NULL); xn = xnode_new(XNODE_T_ELEMENT); xn->u.e.name = atom_str_get(name); xn->u.e.ns_uri = NULL == ns ? NULL : atom_str_get(ns); if (parent != NULL) xnode_add_child(parent, xn); return xn; }
/** * Initiate a SOAP remote procedure call. * * Call will be launched asynchronously, not immediately upon return so that * callbacks are never called on the same stack frame and to allow further * options to be set on the handle before the call begins. * * Initially the request is sent as a regular POST. It is possible to force * the usage of the HTTP Extension Framework by using the SOAP_RPC_O_MAN_FORCE * option, in which case an M-POST will be sent with the proper SOAP Man: * header. Finally, automatic retry of the request can be requested via the * SOAP_RPC_O_MAN_RETRY option: it will start with POST and switch to M-POST * on 405 or 510 errors. * * @param url the HTTP URL to contact for the RPC * @param action the SOAP action to perform * @param maxlen maximum length of data we accept to receive * @param options user-supplied options * @param xn SOAP RPC data payload (XML tree root, will be freed) * @param soap_ns requested SOAP namespace prefix, NULL to use default * @param reply_cb callback to invoke when we get a reply * @param error_cb callback to invoke on error * @param arg additional user-defined callback parameter * * @return a SOAP RPC handle, NULL if the request cannot be initiated (XML * payload too large). In any case, the XML tree is freed. */ soap_rpc_t * soap_rpc(const char *url, const char *action, size_t maxlen, guint32 options, xnode_t *xn, const char *soap_ns, soap_reply_cb_t reply_cb, soap_error_cb_t error_cb, void *arg) { soap_rpc_t *sr; xnode_t *root, *body; pmsg_t *mb; ostream_t *os; gboolean failed = FALSE; g_assert(url != NULL); g_assert(action != NULL); /* * Create the SOAP XML request. */ root = xnode_new_element(NULL, SOAP_NAMESPACE, SOAP_X_ENVELOPE); xnode_add_namespace(root, soap_ns ? soap_ns : "SOAP", SOAP_NAMESPACE); xnode_prop_ns_set(root, SOAP_NAMESPACE, SOAP_X_ENC_STYLE, SOAP_ENCODING); body = xnode_new_element(root, SOAP_NAMESPACE, SOAP_X_BODY); xnode_add_child(body, xn); /* * Serialize the XML tree to a PDU message buffer. */ mb = pmsg_new(PMSG_P_DATA, NULL, SOAP_MAX_PAYLOAD); os = ostream_open_pmsg(mb); xfmt_tree(root, os, XFMT_O_NO_INDENT); if (!ostream_close(os)) { failed = TRUE; g_warning("SOAP unable to serialize payload within %d bytes", SOAP_MAX_PAYLOAD); if (GNET_PROPERTY(soap_debug) > 1) xfmt_tree_dump(root, stderr); } /* * Free the XML tree, including the supplied user nodes. */ xnode_tree_free(root); if (failed) { pmsg_free(mb); return NULL; } /* * Serialization of the XML payload was successful, prepare the * asynchronous SOAP request. */ sr = soap_rpc_alloc(); sr->url = atom_str_get(url); sr->action = atom_str_get(action); sr->maxlen = maxlen; sr->content_len = maxlen; /* Until we see a Content-Length */ sr->options = options; sr->mb = mb; sr->reply_cb = reply_cb; sr->error_cb = error_cb; sr->arg = arg; /* * Make sure the error callback is not called synchronously, and give * them time to supply other options after creating the request before * it starts. */ sr->delay_ev = cq_main_insert(1, soap_rpc_launch, sr); return sr; }