Exemple #1
0
/**
 * Convenience routine: format tree to memory buffer.
 *
 * @param root		tree to dump
 * @param buf		buffer where formatting is done
 * @param len		buffer length
 * @param options	formatting options
 *
 * @return length of generated string, -1 on failure.
 */
size_t
xfmt_tree_to_buffer(const xnode_t *root, void *buf, size_t len, uint32 options)
{
    ostream_t *os;
    pdata_t *pd;
    pmsg_t *mb;
    bool ok;
    size_t written = (size_t) -1;

    g_assert(root != NULL);
    g_assert(buf != NULL);
    g_assert(size_is_non_negative(len));

    pd = pdata_allocb_ext(buf, len, pdata_free_nop, NULL);
    mb = pmsg_alloc(PMSG_P_DATA, pd, 0, 0);
    os = ostream_open_pmsg(mb);

    ok = xfmt_tree(root, os, options);
    ok = ostream_close(os) && ok;

    if (ok)
        written = pmsg_size(mb);

    pmsg_free(mb);

    g_assert((size_t) -1 == written || written <= len);

    return written;
}
Exemple #2
0
/**
 * Convenience routine: dump tree with prologue to specified file, skipping
 * pure white space nodes.
 *
 * @param root		tree to dump
 * @param f			file where we should dump the tree
 *
 * @return TRUE on success.
 */
bool
xfmt_tree_prologue_dump(const xnode_t *root, FILE *f)
{
    ostream_t *os;

    if (!log_file_printable(f))
        return FALSE;

    os = ostream_open_file(f);
    xfmt_tree(root, os, XFMT_O_SKIP_BLANKS | XFMT_O_PROLOGUE);
    return 0 == ostream_close(os);
}
Exemple #3
0
/**
 * Convenience routine: dump tree specified file.
 *
 * See xfmt_tree_extended() for a description of the available options.
 *
 * @param root			tree to dump
 * @param f				file where we should dump the tree
 * @param options		formatting options, as documented above
 * @param pvec			a vector of prefixes to be used for namespaces
 * @param pvcnt			amount of entries in vector
 * @param default_ns	default namespace to install at root element
 *
 * @return TRUE on success.
 */
bool
xfmt_tree_dump_extended(const xnode_t *root, FILE *f,
                        uint32 options, const struct xfmt_prefix *pvec, size_t pvcnt,
                        const char *default_ns)
{
    ostream_t *os;

    if (!log_file_printable(f))
        return FALSE;

    os = ostream_open_file(f);
    xfmt_tree_extended(root, os, options, pvec, pvcnt, default_ns);
    return 0 == ostream_close(os);
}
Exemple #4
0
/**
 * 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;
}