static xmlrpc_mem_block * process_rpc_call (xmlrpc_env *env, const char *data, gsize size, RCDRPCMethodData *method_data) { xmlrpc_mem_block *output; rc_debug (RC_DEBUG_LEVEL_DEBUG, "Handling RPC connection"); if (current_method_data) rc_debug (RC_DEBUG_LEVEL_DEBUG, "Reentrancy in an RPC call"); current_method_data = method_data; /* Set up the access control check function */ xmlrpc_registry_set_preinvoke_method ( env, registry, access_control_check, method_data->identity); output = xmlrpc_registry_process_call ( env, registry, NULL, (char *) data, size); current_method_data = NULL; rc_debug (RC_DEBUG_LEVEL_DEBUG, "Call processed"); return output; } /* process_rpc_call */
int xmlrpcsrv_process(char *data, size_t size, char **response, size_t *reslen) { xmlrpc_env env; xmlrpc_env_init(&env); xmlrpc_mem_block *output = NULL; #ifdef HAVE_XMLRPC_REGISTRY_PROCESS_CALL2 xmlrpc_registry_process_call2(&env, xmlrpcsrv_registry, data, size, NULL, &output); #else output = xmlrpc_registry_process_call(&env, xmlrpcsrv_registry, "localhost", data, size); #endif if (!output) return POM_ERR; *reslen = xmlrpc_mem_block_size(output); *response = malloc(*reslen); if (!*response) { pomlog(POMLOG_ERR "Not enough memory to allocate %u bytes for response", *reslen); xmlrpc_mem_block_free(output); xmlrpc_env_clean(&env); return POM_ERR; } memcpy(*response, xmlrpc_mem_block_contents(output), *reslen); xmlrpc_mem_block_free(output); xmlrpc_env_clean(&env); return POM_OK; }
/************************************** * ProcessRequest * Procesa una peticion *************************************/ int XmlHandler::ProcessRequest(TRequestInfo *req,TSession * const ses) { xmlrpc_env env; int inputLen; char *method; xmlrpc_value *params = NULL; timeval tv; Log(">ProcessRequest [uri:%s]\n",req->uri); //Init timer getUpdDifTime(&tv); //Creamos un enviroment xmlrpc_env_init(&env); //Si no es post if (req->method != m_post) //Mandamos error return XmlRpcServer::SendError(ses, 405, "Only POST allowed"); //Obtenemos el content type const char * content_type = RequestHeaderValue(ses, (char*)"content-type"); //Si no es el bueno if (content_type == NULL || strcmp(content_type, "text/xml") != 0) return XmlRpcServer::SendError(ses, 400, "Wrong content-type"); //Obtenemos el content length const char * content_length = RequestHeaderValue(ses, (char*)"content-length"); //Si no hay if (content_length == NULL) return XmlRpcServer::SendError(ses,411,"No content-length"); //Obtenemos el entero inputLen = atoi(content_length); //Tiene que ser mayor que cero if ((inputLen < 0) || (inputLen > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID))) return XmlRpcServer::SendError(ses,400,"Size limit"); //Creamos un buffer para el body char * buffer = (char *) malloc(inputLen); if (!XmlRpcServer::GetBody(ses,buffer,inputLen)) { //LIberamos el buffer free(buffer); //Y salimos sin devolver nada Log("Operation timedout\n"); return 1; } //Get method name xmlrpc_parse_call(&env,buffer,inputLen,(const char**)&method,¶ms); Log("-ProcessRequest [method:%s]\n",method); //Free name and params free(method); xmlrpc_DECREF(params); //Generamos la respuesta xmlrpc_mem_block *output = xmlrpc_registry_process_call( &env, registry, NULL, buffer, inputLen ); //Si todo ha ido bien if (!env.fault_occurred) { //POnemos el content type ResponseContentType(ses, (char*)"text/xml; charset=\"utf-8\""); //Y mandamos la respuesta XmlRpcServer::SendResponse(ses,200,XMLRPC_MEMBLOCK_CONTENTS(char, output), XMLRPC_MEMBLOCK_SIZE(char, output)); } else