/* with the exception of the registration calls, most everything in main * only needs to be written once per server. */ int main(int argc, char **argv) { XMLRPC_SERVER server; XMLRPC_REQUEST request=0; XMLRPC_REQUEST response; /* create a new server object */ server = XMLRPC_ServerCreate(); /* Register public methods with the server */ XMLRPC_ServerRegisterMethod(server, "hello", hello_callback); /* Now, let's get the client's request from stdin.... */ { char filebuf[4096]; // not that intelligent. sue me. int len = fread(filebuf, sizeof(char), sizeof(filebuf)-1, stdin); if(len) { filebuf[len] = 0; // parse the xml into a request structure request = XMLRPC_REQUEST_FromXML((const char*)filebuf, len, NULL); } } if(!request) { fprintf(stderr, "bogus xmlrpc request\n"); return 1; } /* create a response struct */ response = XMLRPC_RequestNew(); XMLRPC_RequestSetRequestType(response, xmlrpc_request_response); /* call server method with client request and assign the response to our response struct */ XMLRPC_RequestSetData(response, XMLRPC_ServerCallMethod(server, request, NULL)); /* be courteous. reply in same vocabulary/manner as the request. */ XMLRPC_RequestSetOutputOptions(response, XMLRPC_RequestGetOutputOptions(request) ); /* serialize server response as XML */ if(1) { char *outBuf = XMLRPC_REQUEST_ToXML(response, 0); if(outBuf) { printf(outBuf); free(outBuf); } } // cleanup. null safe. XMLRPC_RequestFree(request, 1); XMLRPC_RequestFree(response, 1); XMLRPC_ServerDestroy(server); return 0; }
int uhRPCHandler(UrlHandlerParam* param) { XMLRPC_REQUEST request=NULL; XMLRPC_REQUEST response=NULL; STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS in_opts; char *encoding = 0; int output = 0; char *outBuf = NULL; in_opts.xml_elem_opts.encoding = utf8_get_encoding_id_from_string(encoding); if (param->hs->request.payloadSize > 0) { request = XMLRPC_REQUEST_FromXML(param->hs->request.pucPayload, param->hs->request.payloadSize, &in_opts); /* create a response struct */ response = XMLRPC_RequestNew(); XMLRPC_RequestSetRequestType(response, xmlrpc_request_response); /* call server method with client request and assign the response to our response struct */ XMLRPC_RequestSetData(response, XMLRPC_ServerCallMethod(xml_rpm_server_obj, request, NULL)); if(output == 0 || output == 2) { /* serialize server response as XML */ outBuf = XMLRPC_REQUEST_ToXML(response, 0); } if (outBuf) { //Copy the response into the output buffer strcpy(param->pucBuffer,outBuf); param->dataBytes = strlen(outBuf); param->fileType=HTTPFILETYPE_XML; //Clean up the request and response objects, along with the //buffer which was created by the XML-RPC engine. if(request) XMLRPC_RequestFree(request, 1); if(response) XMLRPC_RequestFree(response, 1); if (outBuf) free(outBuf); return (FLAG_DATA_RAW); } } //Clean up the request and response objects, along with the //buffer which was created by the XML-RPC engine. if(request) XMLRPC_RequestFree(request, 1); if(response) XMLRPC_RequestFree(response, 1); if (outBuf) free(outBuf); return (FLAG_DATA_RAW); }
void XMLRPCResponder::completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { if (mCode == CURLE_OK && !is_internal_http_error(status)) { mBufferSize = buffer->count(channels.in()); if (200 <= status && status < 400) { char* ptr = NULL; char* buf = NULL; LLMutexLock lock(buffer->getMutex()); LLBufferArray::const_segment_iterator_t const end = buffer->endSegment(); for (LLBufferArray::const_segment_iterator_t iter = buffer->beginSegment(); iter != end; ++iter) { LLSegment const& segment = *iter; if (segment.isOnChannel(channels.in())) { S32 const segment_size = segment.size(); if (!buf) { if (segment_size == mBufferSize) { // It's contiguous, no need for copying. mResponse = XMLRPC_REQUEST_FromXML((char const*)segment.data(), mBufferSize, NULL); break; } ptr = buf = new char [mBufferSize]; } llassert(ptr + segment_size <= buf + mBufferSize); memcpy(ptr, segment.data(), segment_size); ptr += segment_size; } } if (buf) { mResponse = XMLRPC_REQUEST_FromXML(buf, mBufferSize, NULL); delete [] buf; } } } }
XMLRPC_REQUEST XmlRpcConnection::Send(const char* data) { HttpUtilities::HttpRequest request; request.SetUrl(strUrl_); request.SetRequestData("text/xml", data); request.SetMethod(HttpUtilities::HttpRequest::Post); request.Perform(); const std::vector<u8> response_data = request.GetResponseData(); if (!request.GetSuccess()) throw XmlRpcException(std::string("XmlRpcEpi exception in XmlRpcConnection::Send() " + request.GetReason())); if (response_data.size() == 0) throw XmlRpcException(std::string("XmlRpcEpi exception in XmlRpcConnection::Send() response data size was zero: ")); // Convert the XML string to a XMLRPC reply structure. return XMLRPC_REQUEST_FromXML((const char*)&response_data[0], (int)(response_data.size()), 0); }
bool XMLRPC::setBuffer(dBuffer & _buffer) { XMLRPC_REQUEST temp_request; t_uint buffSize = _buffer.size(); char *s=new char[buffSize+1]; _buffer.getBytes(reinterpret_cast<t_byteP>(s), buffSize); s[buffSize] = 0; /* in xml_element.c:695 fprintf(stderr...) is used on error conditions.. Might wan't to remove that */ #if BTG_EXTERNALIZATION_DEBUG BTG_NOTICE(logWrapper(), "Deserializing command from " << s << " of size " << buffSize); #endif // BTG_EXTERNALIZATION_DEBUG temp_request = XMLRPC_REQUEST_FromXML(s, buffSize, NULL); delete[] s; if(!temp_request) { return false; } if (XMLRPC_RequestGetError(temp_request)) { XMLRPC_RequestFree(temp_request, 1); return false; } /* Parsed OK, free the current request */ XMLRPC_RequestFree(xmlrpc_request, 1); xmlrpc_request = temp_request; doRewind = true; return true; }
LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump) { LLFastTimer t(FTM_PROCESS_XMLRPC2LLSD_REQUEST); PUMP_DEBUG; if(!eos) return STATUS_BREAK; if(!buffer) return STATUS_ERROR; PUMP_DEBUG; // *FIX: This technique for reading data is far from optimal. We // need to have some kind of istream interface into the xml // parser... S32 bytes = buffer->countAfter(channels.in(), NULL); if(!bytes) return STATUS_ERROR; char* buf = new char[bytes + 1]; buf[bytes] = '\0'; buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes); //lldebugs << "xmlrpc request: " << buf << llendl; // Check the value in the buffer. XMLRPC_REQUEST_FromXML will report a error code 4 if // values that are less than 0x20 are passed to it, except // 0x09: Horizontal tab; 0x0a: New Line; 0x0d: Carriage U8* cur_pBuf = (U8*)buf; U8 cur_char; for (S32 i=0; i<bytes; i++) { cur_char = *cur_pBuf; if ( cur_char < 0x20 && 0x09 != cur_char && 0x0a != cur_char && 0x0d != cur_char ) { *cur_pBuf = '?'; } ++cur_pBuf; } PUMP_DEBUG; XMLRPC_REQUEST request = XMLRPC_REQUEST_FromXML( buf, bytes, NULL); if(!request) { llwarns << "XML -> SD Request process parse error." << llendl; delete[] buf; return STATUS_ERROR; } PUMP_DEBUG; LLBufferStream stream(channels, buffer.get()); stream.precision(DEFAULT_PRECISION); const char* name = XMLRPC_RequestGetMethodName(request); stream << LLSDRPC_REQUEST_HEADER_1 << (name ? name : "") << LLSDRPC_REQUEST_HEADER_2; XMLRPC_VALUE param = XMLRPC_RequestGetData(request); if(param) { PUMP_DEBUG; S32 size = XMLRPC_VectorSize(param); if(size > 1) { // if there are multiple parameters, stuff the values into // an array so that the next step in the chain can read them. stream << "["; } XMLRPC_VALUE current = XMLRPC_VectorRewind(param); bool needs_comma = false; while(current) { if(needs_comma) { stream << ","; } needs_comma = true; stream_out(stream, current); current = XMLRPC_VectorNext(param); } if(size > 1) { // close the array stream << "]"; } } stream << LLSDRPC_REQUEST_FOOTER << std::flush; XMLRPC_RequestFree(request, 1); delete[] buf; PUMP_DEBUG; return STATUS_DONE; }
LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump) { LLFastTimer t(FTM_PROCESS_XMLRPC2LLSD_RESPONSE); PUMP_DEBUG; if(!eos) return STATUS_BREAK; if(!buffer) return STATUS_ERROR; PUMP_DEBUG; // *FIX: This technique for reading data is far from optimal. We // need to have some kind of istream interface into the xml // parser... S32 bytes = buffer->countAfter(channels.in(), NULL); if(!bytes) return STATUS_ERROR; char* buf = new char[bytes + 1]; buf[bytes] = '\0'; buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes); //lldebugs << "xmlrpc response: " << buf << llendl; PUMP_DEBUG; XMLRPC_REQUEST response = XMLRPC_REQUEST_FromXML( buf, bytes, NULL); if(!response) { llwarns << "XML -> SD Response unable to parse xml." << llendl; delete[] buf; return STATUS_ERROR; } PUMP_DEBUG; LLBufferStream stream(channels, buffer.get()); stream.precision(DEFAULT_PRECISION); if(XMLRPC_ResponseIsFault(response)) { PUMP_DEBUG; stream << LLSDRPC_FAULT_HADER_1 << XMLRPC_GetResponseFaultCode(response) << LLSDRPC_FAULT_HADER_2; const char* fault_str = XMLRPC_GetResponseFaultString(response); std::string fault_string; if(fault_str) { fault_string.assign(fault_str); } stream << "'" << LLSDNotationFormatter::escapeString(fault_string) << "'" <<LLSDRPC_FAULT_FOOTER << std::flush; } else { PUMP_DEBUG; stream << LLSDRPC_RESPONSE_HEADER; XMLRPC_VALUE param = XMLRPC_RequestGetData(response); if(param) { stream_out(stream, param); } stream << LLSDRPC_RESPONSE_FOOTER << std::flush; } PUMP_DEBUG; XMLRPC_RequestFree(response, 1); delete[] buf; PUMP_DEBUG; return STATUS_DONE; }
void LLXMLRPCTransaction::Impl::curlEasyRequestCallback(bool success) { llassert(mStatus == LLXMLRPCTransaction::StatusStarted || mStatus == LLXMLRPCTransaction::StatusDownloading); AICurlEasyRequestStateMachine* state_machine = mCurlEasyRequestStateMachinePtr; // We're done with the statemachine, one way or another. // Set mCurlEasyRequestStateMachinePtr to NULL so we won't call mCurlEasyRequestStateMachinePtr->running() in the destructor. // Note that the state machine auto-cleaning: it will be deleted by the main-thread after this function returns. mCurlEasyRequestStateMachinePtr = NULL; if (!success) { // AICurlEasyRequestStateMachine did abort. // This currently only happens when libcurl didn't finish before the timer expired. std::ostringstream msg; F32 timeout_value = gSavedSettings.getF32("CurlRequestTimeOut"); msg << "Connection to " << mURI << " timed out (" << timeout_value << " s)!"; if (timeout_value < 40) { msg << "\nTry increasing CurlRequestTimeOut in Debug Settings."; } setStatus(LLXMLRPCTransaction::StatusOtherError, msg.str()); return; } AICurlEasyRequest_wat curlEasyRequest_w(*state_machine->mCurlEasyRequest); CURLcode result; curlEasyRequest_w->getResult(&result, &mTransferInfo); if (result != CURLE_OK) { setCurlStatus(result); llwarns << "LLXMLRPCTransaction CURL error " << mCurlCode << ": " << curlEasyRequest_w->getErrorString() << llendl; llwarns << "LLXMLRPCTransaction request URI: " << mURI << llendl; return; } setStatus(LLXMLRPCTransaction::StatusComplete); mResponse = XMLRPC_REQUEST_FromXML( mResponseText.data(), mResponseText.size(), NULL); bool hasError = false; bool hasFault = false; int faultCode = 0; std::string faultString; LLXMLRPCValue error(XMLRPC_RequestGetError(mResponse)); if (error.isValid()) { hasError = true; faultCode = error["faultCode"].asInt(); faultString = error["faultString"].asString(); } else if (XMLRPC_ResponseIsFault(mResponse)) { hasFault = true; faultCode = XMLRPC_GetResponseFaultCode(mResponse); faultString = XMLRPC_GetResponseFaultString(mResponse); } if (hasError || hasFault) { setStatus(LLXMLRPCTransaction::StatusXMLRPCError); llwarns << "LLXMLRPCTransaction XMLRPC " << (hasError ? "error " : "fault ") << faultCode << ": " << faultString << llendl; llwarns << "LLXMLRPCTransaction request URI: " << mURI << llendl; } }
/* with the exception of the registration calls, most everything in main * only needs to be written once per server. */ char* clientCallback( char* filebuf ) { XMLRPC_SERVER server; XMLRPC_REQUEST request, response; /* create a new server object */ server = XMLRPC_ServerCreate( ); /* Register public methods with the server */ XMLRPC_ServerRegisterMethod( server, "start", x_startCallback ); XMLRPC_ServerRegisterMethod( server, "stop", x_stopCallback ); XMLRPC_ServerRegisterMethod( server, "rm", x_rmCallback ); XMLRPC_ServerRegisterMethod( server, "mkdir", x_mkdirCallback ); XMLRPC_ServerRegisterMethod( server, "execute", x_executeCallback ); XMLRPC_ServerRegisterMethod( server, "checkcore", x_checkCoreCallback ); XMLRPC_ServerRegisterMethod( server, "listTests", x_listTestsCallback ); XMLRPC_ServerRegisterMethod( server, "runTests", x_runTestsCallback ); XMLRPC_ServerRegisterMethod( server, "listMachines", x_listMachinesCallback ); XMLRPC_ServerRegisterMethod( server, "getConfig", x_getConfigCallback ); XMLRPC_ServerRegisterMethod( server, "setConfig", x_setConfigCallback ); /* Now, let's get the client's request from stdin.... * This will be read from a socket */ { /* char filebuf[4096]; // not that intelligent. sue me. int len = fread( filebuf, sizeof( char ), sizeof( filebuf ) - 1, if( len ) { filebuf[len] = 0; stdin ); */ // parse the xml into a request structure request = XMLRPC_REQUEST_FromXML( ( const char * )filebuf, strlen(filebuf), NULL ); // } } if( !request ) { fprintf( stderr, "bogus xmlrpc request\n" ); return 0; } /* * The interesting part is below */ /* create a response struct */ response = XMLRPC_RequestNew( ); XMLRPC_RequestSetRequestType( response, xmlrpc_request_response ); /* call server method with client request and assign the response to our response struct */ XMLRPC_RequestSetData( response, XMLRPC_ServerCallMethod( server, request, NULL ) ); /* be courteous. reply in same vocabulary/manner as the request. */ XMLRPC_RequestSetOutputOptions( response, XMLRPC_RequestGetOutputOptions ( request ) ); /* serialize server response as XML */ char *outBuf = XMLRPC_REQUEST_ToXML( response, 0 ); if( outBuf ) { printf( outBuf ); } // cleanup. null safe. XMLRPC_RequestFree( request, 1 ); XMLRPC_RequestFree( response, 1 ); XMLRPC_ServerDestroy( server ); return outBuf; }
bool LLXMLRPCTransaction::Impl::process() { switch(mStatus) { case LLXMLRPCTransaction::StatusComplete: case LLXMLRPCTransaction::StatusCURLError: case LLXMLRPCTransaction::StatusXMLRPCError: case LLXMLRPCTransaction::StatusOtherError: { return true; } case LLXMLRPCTransaction::StatusNotStarted: { setStatus(LLXMLRPCTransaction::StatusStarted); break; } default: { // continue onward } } const F32 MAX_PROCESSING_TIME = 0.05f; LLTimer timer; int count; while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(mCurlMulti, &count)) { if (timer.getElapsedTimeF32() >= MAX_PROCESSING_TIME) { return false; } } while(CURLMsg* curl_msg = curl_multi_info_read(mCurlMulti, &count)) { if (CURLMSG_DONE == curl_msg->msg) { if (curl_msg->data.result != CURLE_OK) { setCurlStatus(curl_msg->data.result); llwarns << "LLXMLRPCTransaction CURL error " << mCurlCode << ": " << mCurlErrorBuffer << llendl; llwarns << "LLXMLRPCTransaction request URI: " << mURI << llendl; return true; } setStatus(LLXMLRPCTransaction::StatusComplete); mResponse = XMLRPC_REQUEST_FromXML( mResponseText.data(), mResponseText.size(), NULL); bool hasError = false; bool hasFault = false; int faultCode = 0; std::string faultString; LLXMLRPCValue error(XMLRPC_RequestGetError(mResponse)); if (error.isValid()) { hasError = true; faultCode = error["faultCode"].asInt(); faultString = error["faultString"].asString(); } else if (XMLRPC_ResponseIsFault(mResponse)) { hasFault = true; faultCode = XMLRPC_GetResponseFaultCode(mResponse); faultString = XMLRPC_GetResponseFaultString(mResponse); } if (hasError || hasFault) { setStatus(LLXMLRPCTransaction::StatusXMLRPCError); llwarns << "LLXMLRPCTransaction XMLRPC " << (hasError ? "error " : "fault ") << faultCode << ": " << faultString << llendl; llwarns << "LLXMLRPCTransaction request URI: " << mURI << llendl; } return true; } } return false; }
bool LLXMLRPCTransaction::Impl::process() { if(!mCurlRequest || !mCurlRequest->isValid()) { llwarns << "transaction failed." << llendl ; delete mCurlRequest ; mCurlRequest = NULL ; return true ; //failed, quit. } switch(mStatus) { case LLXMLRPCTransaction::StatusComplete: case LLXMLRPCTransaction::StatusCURLError: case LLXMLRPCTransaction::StatusXMLRPCError: case LLXMLRPCTransaction::StatusOtherError: { return true; } case LLXMLRPCTransaction::StatusNotStarted: { setStatus(LLXMLRPCTransaction::StatusStarted); break; } default: { // continue onward } } if(!mCurlRequest->wait()) { return false ; } while(1) { CURLcode result; bool newmsg = mCurlRequest->getResult(&result, &mTransferInfo); if (newmsg) { if (result != CURLE_OK) { if ((result != CURLE_SSL_PEER_CERTIFICATE) && (result != CURLE_SSL_CACERT)) { // if we have a curl error that's not already been handled // (a non cert error), then generate the error message as // appropriate setCurlStatus(result); llwarns << "LLXMLRPCTransaction CURL error " << mCurlCode << ": " << mCurlRequest->getErrorString() << llendl; llwarns << "LLXMLRPCTransaction request URI: " << mURI << llendl; } return true; } setStatus(LLXMLRPCTransaction::StatusComplete); mResponse = XMLRPC_REQUEST_FromXML( mResponseText.data(), mResponseText.size(), NULL); bool hasError = false; bool hasFault = false; int faultCode = 0; std::string faultString; LLXMLRPCValue error(XMLRPC_RequestGetError(mResponse)); if (error.isValid()) { hasError = true; faultCode = error["faultCode"].asInt(); faultString = error["faultString"].asString(); } else if (XMLRPC_ResponseIsFault(mResponse)) { hasFault = true; faultCode = XMLRPC_GetResponseFaultCode(mResponse); faultString = XMLRPC_GetResponseFaultString(mResponse); } if (hasError || hasFault) { setStatus(LLXMLRPCTransaction::StatusXMLRPCError); llwarns << "LLXMLRPCTransaction XMLRPC " << (hasError ? "error " : "fault ") << faultCode << ": " << faultString << llendl; llwarns << "LLXMLRPCTransaction request URI: " << mURI << llendl; } return true; } else { break; // done } } return false; }
bool LLXMLRPCTransaction::Impl::process() { switch(mStatus) { case LLXMLRPCTransaction::StatusComplete: case LLXMLRPCTransaction::StatusCURLError: case LLXMLRPCTransaction::StatusXMLRPCError: case LLXMLRPCTransaction::StatusOtherError: { return true; } case LLXMLRPCTransaction::StatusNotStarted: { setStatus(LLXMLRPCTransaction::StatusStarted); break; } default: { // continue onward } } const F32 MAX_PROCESSING_TIME = 0.05f; LLTimer timer; while (mCurlRequest->perform() > 0) { if (timer.getElapsedTimeF32() >= MAX_PROCESSING_TIME) { return false; } } while(1) { CURLcode result; bool newmsg = mCurlRequest->getResult(&result, &mTransferInfo); if (newmsg) { if (result != CURLE_OK) { setCurlStatus(result); llwarns << "LLXMLRPCTransaction CURL error " << mCurlCode << ": " << mCurlRequest->getErrorString() << llendl; llwarns << "LLXMLRPCTransaction request URI: " << mURI << llendl; return true; } setStatus(LLXMLRPCTransaction::StatusComplete); mResponse = XMLRPC_REQUEST_FromXML( mResponseText.data(), mResponseText.size(), NULL); bool hasError = false; bool hasFault = false; int faultCode = 0; std::string faultString; LLXMLRPCValue error(XMLRPC_RequestGetError(mResponse)); if (error.isValid()) { hasError = true; faultCode = error["faultCode"].asInt(); faultString = error["faultString"].asString(); } else if (XMLRPC_ResponseIsFault(mResponse)) { hasFault = true; faultCode = XMLRPC_GetResponseFaultCode(mResponse); faultString = XMLRPC_GetResponseFaultString(mResponse); } if (hasError || hasFault) { setStatus(LLXMLRPCTransaction::StatusXMLRPCError); llwarns << "LLXMLRPCTransaction XMLRPC " << (hasError ? "error " : "fault ") << faultCode << ": " << faultString << llendl; llwarns << "LLXMLRPCTransaction request URI: " << mURI << llendl; } return true; } else { break; // done } } return false; }
int main(int argc, char **argv) { int i; XMLRPC_SERVER server; XMLRPC_REQUEST xRequest=0; XMLRPC_REQUEST response; STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS call_options; /* args */ int verbosity = 0; int version = 0; int escaping = 0; int output = 0; char *methodName = "method_TestNormal"; char *encoding = 0; /* for every argument (after the program name) */ for(i=1; i<argc; i++) { char* arg = argv[i]; if(*arg == '-') { char* key = arg + 1; char* val = argv[i+1]; if(key && (!strcmp(key, "help") || !strcmp(key, "-help"))) { print_help(); return 0; } if(key && val) { if(!strcmp(key, "verbosity")) { if(!strcmp(val, "pretty")) { verbosity = 0; } else if(!strcmp(val, "none")) { verbosity = 1; } else if(!strcmp(val, "newlines")) { verbosity = 2; } } else if(!strcmp(key, "version")) { if(!strcmp(val, "xmlrpc")) { version = 0; } else if(!strcmp(val, "simple")) { version = 1; } } else if(!strcmp(key, "escaping")) { if(!strcmp(val, "markup")) { escaping |= xml_elem_markup_escaping ; } else if(!strcmp(val, "cdata")) { escaping |= xml_elem_cdata_escaping; } else if(!strcmp(val, "non-ascii")) { escaping |= xml_elem_non_ascii_escaping; } else if(!strcmp(val, "non-print")) { escaping |= xml_elem_non_print_escaping; } } else if(!strcmp(key, "encoding")) { encoding = val; } else if(!strcmp(key, "output")) { if(!strcmp(val, "response")) { output = 0; } else if(!strcmp(val, "xRequest")) { output = 1; } else if(!strcmp(val, "both")) { output = 2; } } else if(!strcmp(key, "method")) { methodName = val; } i++; } } } /* create a new server object */ server = XMLRPC_ServerCreate(); XMLRPC_ServerRegisterMethod(server, "validator1.arrayOfStructsTest", validator1_arrayOfStructsTest); XMLRPC_ServerRegisterMethod(server, "validator1.countTheEntities", validator1_countTheEntities); XMLRPC_ServerRegisterMethod(server, "validator1.easyStructTest", validator1_easyStructTest); XMLRPC_ServerRegisterMethod(server, "validator1.echoStructTest", validator1_echoStructTest); XMLRPC_ServerRegisterMethod(server, "validator1.manyTypesTest", validator1_manyTypesTest); XMLRPC_ServerRegisterMethod(server, "validator1.moderateSizeArrayCheck", validator1_moderateSizeArrayCheck); XMLRPC_ServerRegisterMethod(server, "validator1.nestedStructTest", validator1_nestedStructTest); XMLRPC_ServerRegisterMethod(server, "validator1.simpleStructReturnTest", validator1_simpleStructReturnTest); /* Now, let's get the client's xRequest from stdin.... */ { char* filebuf[1024 * 100]; int len = fread(filebuf, sizeof(char), sizeof(filebuf)-1, stdin); if(len) { filebuf[len] = 0; xRequest = XMLRPC_REQUEST_FromXML((const char*)filebuf, len, NULL); } } if(!xRequest) { fprintf(stderr, "bogus xmlrpc xRequest\n"); return 1; } /* create a response struct */ response = XMLRPC_RequestNew(); XMLRPC_RequestSetRequestType(response, xmlrpc_request_response); /* Set various xml output options. Or we could just use defaults. */ call_options.xml_elem_opts.verbosity = verbosity == 1 ? xml_elem_no_white_space : (verbosity == 2 ? xml_elem_newlines_only : xml_elem_pretty); call_options.xml_elem_opts.escaping = escaping; call_options.version = (version == 1) ? xmlrpc_version_simple : xmlrpc_version_1_0; call_options.xml_elem_opts.encoding = encoding; XMLRPC_RequestSetOutputOptions(response, &call_options); /* call server method with client xRequest and assign the response to our response struct */ XMLRPC_RequestSetData(response, XMLRPC_ServerCallMethod(server, xRequest, NULL)); if(output == 1 || output == 2) { /* serialize client request as XML */ char *outBuf; XMLRPC_RequestSetOutputOptions(xRequest, &call_options); outBuf = XMLRPC_REQUEST_ToXML(xRequest, 0); if(outBuf) { printf("%s\n\n --- \n\n", outBuf); free(outBuf); } } if(output == 0 || output == 2) { /* serialize server response as XML */ char *outBuf = XMLRPC_REQUEST_ToXML(response, 0); if(outBuf) { printf(outBuf); free(outBuf); } } if(xRequest) { /* Free xRequest */ XMLRPC_RequestFree(xRequest, 1); } if(response) { /* free response */ XMLRPC_RequestFree(response, 1); } if(server) { XMLRPC_ServerDestroy(server); } return 0; }