diff options
Diffstat (limited to 'Utilities/cmxmlrpc/xmlrpc_client.c')
-rw-r--r-- | Utilities/cmxmlrpc/xmlrpc_client.c | 977 |
1 files changed, 0 insertions, 977 deletions
diff --git a/Utilities/cmxmlrpc/xmlrpc_client.c b/Utilities/cmxmlrpc/xmlrpc_client.c deleted file mode 100644 index a5ad65c..0000000 --- a/Utilities/cmxmlrpc/xmlrpc_client.c +++ /dev/null @@ -1,977 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#undef PACKAGE -#undef VERSION - -#include <stddef.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> -#include <errno.h> - -#include "bool.h" -#include "mallocvar.h" -#include "xmlrpc.h" -#include "xmlrpc_int.h" -#include "xmlrpc_client.h" -#include "xmlrpc_client_int.h" -/* transport_config.h defines XMLRPC_DEFAULT_TRANSPORT, - MUST_BUILD_WININET_CLIENT, MUST_BUILD_CURL_CLIENT, - MUST_BUILD_LIBWWW_CLIENT -*/ -#include "transport_config.h" - -#if MUST_BUILD_WININET_CLIENT -#include "xmlrpc_wininet_transport.h" -#endif -#if MUST_BUILD_CURL_CLIENT -#include "xmlrpc_curl_transport.h" -#endif -#if MUST_BUILD_LIBWWW_CLIENT -#include "xmlrpc_libwww_transport.h" -#endif - -struct xmlrpc_client { -/*---------------------------------------------------------------------------- - This represents a client object. ------------------------------------------------------------------------------*/ - struct clientTransport * transportP; -}; - - - -typedef struct call_info -{ - /* These fields are used when performing asynchronous calls. - ** The _asynch_data_holder contains server_url, method_name and - ** param_array, so it's the only thing we need to free. */ - xmlrpc_value *_asynch_data_holder; - char *server_url; - char *method_name; - xmlrpc_value *param_array; - xmlrpc_response_handler callback; - void *user_data; - - /* The serialized XML data passed to this call. We keep this around - ** for use by our source_anchor field. */ - xmlrpc_mem_block *serialized_xml; -} call_info; - -static bool clientInitialized = FALSE; - -/*========================================================================= -** Initialization and Shutdown -**========================================================================= -*/ - -static struct clientTransportOps clientTransportOps; - -static struct xmlrpc_client client; - /* Some day, we need to make this dynamically allocated, so there can - be more than one client per program and just generally to provide - a cleaner interface. - */ - -extern void -xmlrpc_client_init(int const flags, - const char * const appname, - const char * const appversion) { - - struct xmlrpc_clientparms clientparms; - - /* As our interface does not allow for failure, we just fail silently ! */ - - xmlrpc_env env; - xmlrpc_env_init(&env); - - clientparms.transport = XMLRPC_DEFAULT_TRANSPORT; - - xmlrpc_client_init2(&env, flags, - appname, appversion, - &clientparms, XMLRPC_CPSIZE(transport)); - - xmlrpc_env_clean(&env); -} - - - -const char * -xmlrpc_client_get_default_transport(xmlrpc_env * const env ATTR_UNUSED) { - - return XMLRPC_DEFAULT_TRANSPORT; -} - - - -static void -setupTransport(xmlrpc_env * const envP, - const char * const transportName) { - - if (FALSE) { - } -#if MUST_BUILD_WININET_CLIENT - else if (strcmp(transportName, "wininet") == 0) - clientTransportOps = xmlrpc_wininet_transport_ops; -#endif -#if MUST_BUILD_CURL_CLIENT - else if (strcmp(transportName, "curl") == 0) - clientTransportOps = xmlrpc_curl_transport_ops; - else if (strcmp(transportName, "libcurl") == 0) - clientTransportOps = xmlrpc_curl_transport_ops; -#endif -#if MUST_BUILD_LIBWWW_CLIENT - else if (strcmp(transportName, "libwww") == 0) - clientTransportOps = xmlrpc_libwww_transport_ops; -#endif - else - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Unrecognized XML transport name '%s'", transportName); -} - - - -void -xmlrpc_client_init2(xmlrpc_env * const envP, - int const flags, - const char * const appname, - const char * const appversion, - struct xmlrpc_clientparms * const clientparmsP, - unsigned int const parm_size) { - - if (clientInitialized) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Xmlrpc-c client instance has already been initialized " - "(need to call xmlrpc_client_cleanup() before you can " - "reinitialize)."); - else { - const char * transportName; - - if (parm_size < XMLRPC_CPSIZE(transport) || - clientparmsP->transport == NULL) { - /* He didn't specify a transport. Use the default */ - transportName = xmlrpc_client_get_default_transport(envP); - } else - transportName = clientparmsP->transport; - - if (!envP->fault_occurred) { - setupTransport(envP, transportName); - if (!envP->fault_occurred) { - clientTransportOps.create(envP, flags, appname, appversion, - &client.transportP); - if (!envP->fault_occurred) - clientInitialized = TRUE; - } - } - } -} - - - -void -xmlrpc_client_cleanup() { - - XMLRPC_ASSERT(clientInitialized); - - clientTransportOps.destroy(client.transportP); - - clientInitialized = FALSE; -} - - - -static void -call_info_free(call_info * const callInfoP) { - - /* Assume the worst.. That only parts of the call_info are valid. */ - - XMLRPC_ASSERT_PTR_OK(callInfoP); - - /* If this has been allocated, we're responsible for destroying it. */ - if (callInfoP->_asynch_data_holder) - xmlrpc_DECREF(callInfoP->_asynch_data_holder); - - /* Now we can blow away the XML data. */ - if (callInfoP->serialized_xml) - xmlrpc_mem_block_free(callInfoP->serialized_xml); - - free(callInfoP); -} - - - -static void -call_info_new(xmlrpc_env * const envP, - xmlrpc_server_info * const server, - const char * const method_name, - xmlrpc_value * const argP, - call_info ** const callInfoPP) { -/*---------------------------------------------------------------------------- - Create a call_info object. A call_info object represents an XML-RPC - call. ------------------------------------------------------------------------------*/ - call_info * callInfoP; - - XMLRPC_ASSERT_PTR_OK(argP); - XMLRPC_ASSERT_PTR_OK(callInfoPP); - - if (method_name == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "method name argument is NULL pointer"); - else if (server == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "server info argument is NULL pointer"); - else { - MALLOCVAR(callInfoP); - if (callInfoP == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for xmlrpc_call_info"); - else { - xmlrpc_mem_block * callXmlP; - - /* Clear contents. */ - memset(callInfoP, 0, sizeof(*callInfoP)); - - /* Make the XML for our call */ - callXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - xmlrpc_serialize_call(envP, callXmlP, method_name, argP); - if (!envP->fault_occurred) { - xmlrpc_traceXml("XML-RPC CALL", - XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP), - (unsigned int)XMLRPC_MEMBLOCK_SIZE(char, callXmlP)); - - callInfoP->serialized_xml = callXmlP; - - *callInfoPP = callInfoP; - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, callXmlP); - } - if (envP->fault_occurred) - free(callInfoP); - } - } -} - - - -static void -clientCallServerParams(xmlrpc_env * const envP, - struct clientTransport * const transportP, - xmlrpc_server_info * const serverP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const resultPP) { - - call_info * callInfoP; - - if (!clientInitialized) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Xmlrpc-c client instance has not been initialized " - "(need to call xmlrpc_client_init2())."); - else { - call_info_new(envP, serverP, methodName, paramArrayP, &callInfoP); - if (!envP->fault_occurred) { - xmlrpc_mem_block * respXmlP; - - clientTransportOps.call(envP, transportP, serverP, - callInfoP->serialized_xml, callInfoP, - &respXmlP); - if (!envP->fault_occurred) { - xmlrpc_traceXml("XML-RPC RESPONSE", - XMLRPC_MEMBLOCK_CONTENTS(char, respXmlP), - (unsigned int)XMLRPC_MEMBLOCK_SIZE(char, respXmlP)); - - *resultPP = xmlrpc_parse_response( - envP, - XMLRPC_MEMBLOCK_CONTENTS(char, respXmlP), - XMLRPC_MEMBLOCK_SIZE(char, respXmlP)); - XMLRPC_MEMBLOCK_FREE(char, respXmlP); - } - call_info_free(callInfoP); - } - } -} - - - -xmlrpc_value * -xmlrpc_client_call_params(xmlrpc_env * const envP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_value * const paramArrayP) { - - xmlrpc_value *retval; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverUrl); - - if (!clientInitialized) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Xmlrpc-c client instance has not been initialized " - "(need to call xmlrpc_client_init2())."); - else { - xmlrpc_server_info * serverP; - - /* Build a server info object and make our call. */ - serverP = xmlrpc_server_info_new(envP, serverUrl); - if (!envP->fault_occurred) { - clientCallServerParams(envP, client.transportP, serverP, - methodName, paramArrayP, - &retval); - - xmlrpc_server_info_free(serverP); - } - } - - if (!envP->fault_occurred) - XMLRPC_ASSERT_VALUE_OK(retval); - - return retval; -} - - - -static xmlrpc_value * -xmlrpc_client_call_va(xmlrpc_env * const envP, - const char * const server_url, - const char * const method_name, - const char * const format, - va_list args) { - - xmlrpc_value * argP; - xmlrpc_value * retval = 0; - xmlrpc_env argenv; - const char * suffix; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(format); - - /* Build our argument value. */ - xmlrpc_env_init(&argenv); - xmlrpc_build_value_va(&argenv, format, args, &argP, &suffix); - if (argenv.fault_occurred) { - xmlrpc_env_set_fault_formatted( - envP, argenv.fault_code, "Invalid RPC arguments. " - "The format argument must indicate a single array, and the " - "following arguments must correspond to that format argument. " - "The failure is: %s", - argenv.fault_string); - xmlrpc_env_clean(&argenv); - } else { - XMLRPC_ASSERT_VALUE_OK(argP); - - if (*suffix != '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one arument.", - suffix); - else { - /* Perform the actual XML-RPC call. */ - retval = xmlrpc_client_call_params( - envP, server_url, method_name, argP); - if (!envP->fault_occurred) - XMLRPC_ASSERT_VALUE_OK(retval); - } - xmlrpc_DECREF(argP); - } - return retval; -} - - - -xmlrpc_value * -xmlrpc_client_call(xmlrpc_env * const envP, - const char * const server_url, - const char * const method_name, - const char * const format, - ...) { - - xmlrpc_value * result; - va_list args; - - va_start(args, format); - result = xmlrpc_client_call_va(envP, server_url, - method_name, format, args); - va_end(args); - - return result; -} - - - -xmlrpc_value * -xmlrpc_client_call_server(xmlrpc_env * const envP, - xmlrpc_server_info * const serverP, - const char * const methodName, - const char * const format, - ...) { - - va_list args; - xmlrpc_value * paramArrayP; - xmlrpc_value * retval; - const char * suffix; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(format); - - /* Build our argument */ - va_start(args, format); - xmlrpc_build_value_va(envP, format, args, ¶mArrayP, &suffix); - va_end(args); - - if (!envP->fault_occurred) { - if (*suffix != '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one arument.", - suffix); - else - clientCallServerParams(envP, client.transportP, serverP, - methodName, paramArrayP, - &retval); - - xmlrpc_DECREF(paramArrayP); - } - return retval; -} - - -void -xmlrpc_client_event_loop_finish_asynch(void) { - XMLRPC_ASSERT(clientInitialized); - clientTransportOps.finish_asynch(client.transportP, timeout_no, 0); -} - - - -void -xmlrpc_client_event_loop_finish_asynch_timeout(timeout_t const timeout) { - XMLRPC_ASSERT(clientInitialized); - clientTransportOps.finish_asynch(client.transportP, timeout_yes, timeout); -} - - - -static void -call_info_set_asynch_data(xmlrpc_env * const env, - call_info * const info, - const char * const server_url, - const char * const method_name, - xmlrpc_value * const argP, - xmlrpc_response_handler callback, - void * const user_data) { - - xmlrpc_value *holder; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(info); - XMLRPC_ASSERT(info->_asynch_data_holder == NULL); - XMLRPC_ASSERT_PTR_OK(server_url); - XMLRPC_ASSERT_PTR_OK(method_name); - XMLRPC_ASSERT_VALUE_OK(argP); - - /* Install our callback and user_data. - ** (We're not responsible for destroying the user_data.) */ - info->callback = callback; - info->user_data = user_data; - - /* Build an XML-RPC data structure to hold our other data. This makes - ** copies of server_url and method_name, and increments the reference - ** to the argument *argP. */ - holder = xmlrpc_build_value(env, "(ssV)", - server_url, method_name, argP); - XMLRPC_FAIL_IF_FAULT(env); - - /* Parse the newly-allocated structure into our public member variables. - ** This doesn't make any new references, so we can dispose of the whole - ** thing by DECREF'ing the one master reference. Nifty, huh? */ - xmlrpc_parse_value(env, holder, "(ssV)", - &info->server_url, - &info->method_name, - &info->param_array); - XMLRPC_FAIL_IF_FAULT(env); - - /* Hand over ownership of the holder to the call_info struct. */ - info->_asynch_data_holder = holder; - holder = NULL; - - cleanup: - if (env->fault_occurred) { - if (holder) - xmlrpc_DECREF(holder); - } -} - -/*========================================================================= -** xmlrpc_server_info -**========================================================================= -*/ - -xmlrpc_server_info * -xmlrpc_server_info_new (xmlrpc_env * const env, - const char * const server_url) { - - xmlrpc_server_info *server; - char *url_copy; - - /* Error-handling preconditions. */ - url_copy = NULL; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(server_url); - - /* Allocate our memory blocks. */ - server = (xmlrpc_server_info*) malloc(sizeof(xmlrpc_server_info)); - XMLRPC_FAIL_IF_NULL(server, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for xmlrpc_server_info"); - memset(server, 0, sizeof(xmlrpc_server_info)); - url_copy = (char*) malloc(strlen(server_url) + 1); - XMLRPC_FAIL_IF_NULL(url_copy, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for server URL"); - - /* Build our object. */ - strcpy(url_copy, server_url); - server->_server_url = url_copy; - server->_http_basic_auth = NULL; - - cleanup: - if (env->fault_occurred) { - if (url_copy) - free(url_copy); - if (server) - free(server); - return NULL; - } - return server; -} - -xmlrpc_server_info * xmlrpc_server_info_copy(xmlrpc_env *env, - xmlrpc_server_info *aserver) -{ - xmlrpc_server_info *server; - char *url_copy, *auth_copy; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(aserver); - - /* Error-handling preconditions. */ - url_copy = NULL; - auth_copy = NULL; - - /* Allocate our memory blocks. */ - server = (xmlrpc_server_info*) malloc(sizeof(xmlrpc_server_info)); - XMLRPC_FAIL_IF_NULL(server, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for xmlrpc_server_info"); - url_copy = (char*) malloc(strlen(aserver->_server_url) + 1); - XMLRPC_FAIL_IF_NULL(url_copy, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for server URL"); - auth_copy = (char*) malloc(strlen(aserver->_http_basic_auth) + 1); - XMLRPC_FAIL_IF_NULL(auth_copy, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for authentication info"); - - /* Build our object. */ - strcpy(url_copy, aserver->_server_url); - server->_server_url = url_copy; - strcpy(auth_copy, aserver->_http_basic_auth); - server->_http_basic_auth = auth_copy; - - cleanup: - if (env->fault_occurred) { - if (url_copy) - free(url_copy); - if (auth_copy) - free(auth_copy); - if (server) - free(server); - return NULL; - } - return server; - -} - -void xmlrpc_server_info_free (xmlrpc_server_info *server) -{ - XMLRPC_ASSERT_PTR_OK(server); - XMLRPC_ASSERT(server->_server_url != XMLRPC_BAD_POINTER); - - if (server->_http_basic_auth) - free(server->_http_basic_auth); - free(server->_server_url); - server->_server_url = XMLRPC_BAD_POINTER; - free(server); -} - -/*========================================================================= -** xmlrpc_client_call_asynch -**========================================================================= -*/ - -void -xmlrpc_client_call_asynch(const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler callback, - void * const userData, - const char * const format, - ...) { - - xmlrpc_env env; - va_list args; - xmlrpc_value * paramArrayP; - const char * suffix; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT_PTR_OK(serverUrl); - XMLRPC_ASSERT_PTR_OK(format); - - /* Build our argument array. */ - va_start(args, format); - xmlrpc_build_value_va(&env, format, args, ¶mArrayP, &suffix); - va_end(args); - if (env.fault_occurred) { - /* Unfortunately, we have no way to return an error and the - regular callback for a failed RPC is designed to have the - parameter array passed to it. This was probably an oversight - of the original asynch design, but now we have to be as - backward compatible as possible, so we do this: - */ - (*callback)(serverUrl, methodName, NULL, userData, &env, NULL); - } else { - if (*suffix != '\0') - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one arument.", - suffix); - else { - xmlrpc_server_info * serverP; - serverP = xmlrpc_server_info_new(&env, serverUrl); - if (!env.fault_occurred) { - xmlrpc_client_call_server_asynch_params( - serverP, methodName, callback, userData, - paramArrayP); - } - xmlrpc_server_info_free(serverP); - } - if (env.fault_occurred) - (*callback)(serverUrl, methodName, paramArrayP, userData, - &env, NULL); - xmlrpc_DECREF(paramArrayP); - } - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_call_asynch_params(const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler callback, - void * const userData, - xmlrpc_value * const paramArrayP) { - - xmlrpc_env env; - xmlrpc_server_info *serverP; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT_PTR_OK(serverUrl); - - serverP = xmlrpc_server_info_new(&env, serverUrl); - if (!env.fault_occurred) { - xmlrpc_client_call_server_asynch_params( - serverP, methodName, callback, userData, paramArrayP); - - xmlrpc_server_info_free(serverP); - } - - if (env.fault_occurred) - /* We have no way to return failure; we report the failure - as it happened after we successfully started the RPC. - */ - (*callback)(serverUrl, methodName, paramArrayP, userData, - &env, NULL); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_call_server_asynch(xmlrpc_server_info * const serverP, - const char * const methodName, - xmlrpc_response_handler callback, - void * const userData, - const char * const format, - ...) { - - xmlrpc_env env; - va_list args; - xmlrpc_value * paramArrayP; - const char * suffix; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT_PTR_OK(format); - - /* Build our parameter array. */ - va_start(args, format); - xmlrpc_build_value_va(&env, format, args, ¶mArrayP, &suffix); - va_end(args); - if (env.fault_occurred) { - /* Unfortunately, we have no way to return an error and the - regular callback for a failed RPC is designed to have the - parameter array passed to it. This was probably an oversight - of the original asynch design, but now we have to be as - backward compatible as possible, so we do this: - */ - (*callback)(serverP->_server_url, methodName, NULL, userData, - &env, NULL); - } else { - if (*suffix != '\0') - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one arument.", - suffix); - else { - xmlrpc_client_call_server_asynch_params( - serverP, methodName, callback, userData, paramArrayP); - } - xmlrpc_DECREF(paramArrayP); - } - - if (env.fault_occurred) - (*callback)(serverP->_server_url, methodName, paramArrayP, userData, - &env, NULL); - - xmlrpc_env_clean(&env); -} - - - -static void -asynchComplete(call_info * const callInfoP, - xmlrpc_mem_block * const responseXmlP, - xmlrpc_env const transportEnv) { -/*---------------------------------------------------------------------------- - Complete an asynchronous XML-RPC call request. - - This includes calling the user's RPC completion routine. - - 'transportEnv' describes the an error that the transport - encountered in processing the call. If the transport successfully - sent the call to the server and processed the response but the - server failed the call, 'transportEnv' indicates no error, and the - response in *callInfoP might very well indicate that the server - failed the request. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * responseP = 0; - - xmlrpc_env_init(&env); - - if (transportEnv.fault_occurred) - xmlrpc_env_set_fault_formatted( - &env, transportEnv.fault_code, - "Client transport failed to execute the RPC. %s", - transportEnv.fault_string); - - if (!env.fault_occurred) - responseP = xmlrpc_parse_response( - &env, - XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlP), - XMLRPC_MEMBLOCK_SIZE(char, responseXmlP)); - - /* Call the user's callback function with the result */ - (*callInfoP->callback)(callInfoP->server_url, - callInfoP->method_name, - callInfoP->param_array, - callInfoP->user_data, &env, responseP); - - if (!env.fault_occurred) - xmlrpc_DECREF(responseP); - - call_info_free(callInfoP); - - xmlrpc_env_clean(&env); -} - - - -static void -sendRequest(xmlrpc_env * const envP, - struct clientTransport * const transportP, - xmlrpc_server_info * const serverP, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - xmlrpc_value * const argP) { - - call_info * callInfoP; - - call_info_new(envP, serverP, methodName, argP, &callInfoP); - if (!envP->fault_occurred) { - call_info_set_asynch_data(envP, callInfoP, - serverP->_server_url, methodName, - argP, responseHandler, userData); - if (!envP->fault_occurred) - clientTransportOps.send_request( - envP, transportP, serverP, callInfoP->serialized_xml, - &asynchComplete, callInfoP); - - if (envP->fault_occurred) - call_info_free(callInfoP); - else { - /* asynchComplete() will free *callInfoP */ - } - } - if (envP->fault_occurred) { - /* Transport did not start the call. Report the call complete - (with error) now. - */ - (*responseHandler)(serverP->_server_url, methodName, argP, userData, - envP, NULL); - } else { - /* The transport will call *responseHandler() when it has completed - the call - */ - } -} - - - -void -xmlrpc_client_call_server_asynch_params( - xmlrpc_server_info * const serverP, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - xmlrpc_value * const argP) { - xmlrpc_env env; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(methodName); - XMLRPC_ASSERT_PTR_OK(responseHandler); - XMLRPC_ASSERT_VALUE_OK(argP); - - if (!clientInitialized) - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_INTERNAL_ERROR, - "Xmlrpc-c client instance has not been initialized " - "(need to call xmlrpc_client_init2())."); - else - sendRequest(&env, client.transportP, serverP, - methodName, responseHandler, userData, - argP); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_server_info_set_basic_auth(xmlrpc_env * const envP, - xmlrpc_server_info * const serverP, - const char * const username, - const char * const password) { - - size_t username_len, password_len, raw_token_len; - char *raw_token; - xmlrpc_mem_block *token; - char *token_data, *auth_type, *auth_header; - size_t token_len, auth_type_len, auth_header_len; - - /* Error-handling preconditions. */ - token = NULL; - auth_header = NULL; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(username); - XMLRPC_ASSERT_PTR_OK(password); - - /* Calculate some lengths. */ - username_len = strlen(username); - password_len = strlen(password); - raw_token_len = username_len + password_len + 1; - - /* Build a raw token of the form 'username:password'. */ - raw_token = (char*) malloc(raw_token_len + 1); - XMLRPC_FAIL_IF_NULL(raw_token, envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for auth token"); - strcpy(raw_token, username); - raw_token[username_len] = ':'; - strcpy(&raw_token[username_len + 1], password); - - /* Encode our raw token using Base64. */ - token = xmlrpc_base64_encode_without_newlines(envP, - (unsigned char*) raw_token, - raw_token_len); - XMLRPC_FAIL_IF_FAULT(envP); - token_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, token); - token_len = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, token); - - /* Build our actual header value. (I hate string processing in C.) */ - auth_type = "Basic "; - auth_type_len = strlen(auth_type); - auth_header_len = auth_type_len + token_len; - auth_header = (char*) malloc(auth_header_len + 1); - XMLRPC_FAIL_IF_NULL(auth_header, envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for auth header"); - memcpy(auth_header, auth_type, auth_type_len); - memcpy(&auth_header[auth_type_len], token_data, token_len); - auth_header[auth_header_len] = '\0'; - - /* Clean up any pre-existing authentication information, and install - ** the new value. */ - if (serverP->_http_basic_auth) - free(serverP->_http_basic_auth); - serverP->_http_basic_auth = auth_header; - - cleanup: - if (raw_token) - free(raw_token); - if (token) - xmlrpc_mem_block_free(token); - if (envP->fault_occurred) { - if (auth_header) - free(auth_header); - } -} - |