ULXR_API_IMPL(void) FileResource::open(bool do_read) { ULXR_TRACE(ULXR_PCHAR("FileResource::open ") << filename); if (opened) return; reset(); if (do_read) { ULXR_TRACE(ULXR_PCHAR("FileResource::open do_read")); #ifdef __unix__ if (0 == ulxr_access(getLatin1(getFilename()).c_str(), F_OK)) // file exists? #else if (0 == ulxr_access(getLatin1(getFilename()).c_str(), 0)) #endif { ulxr_FILE *ifs = ulxr_fopen (getLatin1(filename).c_str(), "rb"); char buffer [2000]; if (ifs != 0) { while (!ulxr_feof(ifs) && !error) { size_t readed = ulxr_fread(buffer, 1, sizeof(buffer), ifs); if (ulxr_ferror(ifs)) error = true; write(buffer, readed); } ulxr_fclose (ifs); } } } opened = true; }
void Protocol::setConnection(Connection *conn) { ULXR_TRACE("getConnection"); pimpl->connection = conn; pimpl->delete_connection = true; ULXR_TRACE("/getConnection"); }
MethodResponse Dispatcher::dispatchCallLoc(const MethodCall &call) const { ULXR_TRACE("dispatchCallLoc: " << call.getMethodName()); MethodCallDescriptor desc(call); MethodCallMap::const_iterator it; if ((it = methodcalls.find(desc)) != methodcalls.end() ) { MethodCall_t mc = (*it).second; if (!(*it).first.isEnabled()) { std::string s = "method \""; s += desc.getSignature(true, false); s += "\": currently unavailable."; return MethodResponse (MethodNotFoundError, s); } else { if ((*it).first.calltype == CallSystem) { ULXR_TRACE("Now calling system function: " + (*it).first.getSignature(true, true)); (*it).first.incInvoked(); return mc.system_function(call, this); } else if ((*it).first.calltype == CallStatic) { ULXR_TRACE("Now calling static function: " + (*it).first.getSignature(true, true)); (*it).first.incInvoked(); return mc.static_function(call); } else if ((*it).first.calltype == CallDynamic) { ULXR_TRACE("Now calling dynamic function: " + (*it).first.getSignature(true, true)); (*it).first.incInvoked(); return mc.dynamic_function->call(call); } else { std::string s = "method \""; s += desc.getSignature(true, false); s += "\": internal problem to find method."; return MethodResponse (MethodNotFoundError, s); } } } std::string s = "method \""; s += desc.getSignature(true, false); s += "\" unknown method and/or signature."; return MethodResponse (MethodNotFoundError, s); }
void Protocol::sendRpcCall(const MethodCall &call, const std::string &/*resource*/) { ULXR_TRACE("sendRpcCall"); std::string xml = call.getXml(0)+"\n"; getConnection()->write(xml.c_str(), xml.length()); }
void Protocol::closeConnection() { ULXR_TRACE("closeConnection"); if (getConnection()) getConnection()->close(); // resetConnection(); }
bool Protocol::accept(int _timeout) { ULXR_TRACE("accept"); bool res = getConnection()->accept(_timeout); resetConnection(); return res; }
bool Protocol::isOpen() const { const Connection *conn = getConnection(); bool op = conn != 0 && conn->isOpen(); ULXR_TRACE("isOpen " << op); return op; }
ULXR_API_IMPL(ValueParserBase::ValueState *) ValueParser::getTopValueState() const { ULXR_TRACE(ULXR_PCHAR("ValueParser::getTopState() size: ") << states.size()); #ifdef DEBUG ValueState *vs = dynamic_cast<ValueState*> (states.top()); // be careful about type if (vs == 0) { ULXR_TRACE(ULXR_PCHAR("ValueParser::getTopState(), top state: ") << (void*) states.top()); ULXR_TRACE(ULXR_PCHAR("ValueParser::getTopState(): state <> ValueState")); ULXR_TRACE(ULXR_PCHAR("ValueParser::getTopState(): state == ") << ULXR_GET_STRING(typeid(states.top()).name())); } return vs; #else return reinterpret_cast<ValueParserBase::ValueState*> (states.top()); // dont care anymore #endif }
MethodResponse Dispatcher::system_methodHelp(const MethodCall &calldata, const Dispatcher *disp) { ULXR_TRACE("system_methodHelp"); if (calldata.numParams() != 1) throw ParameterException(InvalidMethodParameterError, "Exactly 1 parameter allowed for \"system.methodHelp\""); if (calldata.getParam(0).getType() != RpcStrType) throw ParameterException(InvalidMethodParameterError, "Parameter 1 not of type \"String\" \"system.listMethods\""); RpcString vs = calldata.getParam(0); std::string name = vs.getString(); std::string s; MethodCallMap::const_iterator it; std::string s_prev; for (it = disp->methodcalls.begin(); it != disp->methodcalls.end(); ++it) if (name == (*it).first.method_name && (*it).first.documentation.length() != 0) { if ( s_prev != (*it).first.documentation && (*it).first.documentation.length() != 0) { if (s.length() != 0) s = "* " +s + "\n* "; s += (*it).first.documentation; } s_prev = (*it).first.documentation; } return MethodResponse (RpcString(s)); }
void Protocol::resetConnection() { ULXR_TRACE("resetConnection"); pimpl->connstate = ConnStart; pimpl->remain_content_length = -1; pimpl->content_length = -1; }
MethodResponse Dispatcher::system_listMethods(const MethodCall &calldata, const Dispatcher *disp) { ULXR_TRACE("system_listMethods"); if (calldata.numParams() > 1) throw ParameterException(InvalidMethodParameterError, "At most 1 parameter allowed for \"system.listMethods\""); if ( calldata.numParams() == 1 && calldata.getParam(0).getType() != RpcStrType) throw ParameterException(InvalidMethodParameterError, "Parameter 1 not of type \"String\" \"system.listMethods\""); // FIXME: what to do with param 1 if present ?? Array arr; std::string m_prev; MethodCallMap::const_iterator it; for (it = disp->methodcalls.begin(); it != disp->methodcalls.end(); ++it) if ( m_prev != (*it).first.method_name && (*it).first.method_name.length() != 0) { arr.addItem(RpcString((*it).first.method_name)); m_prev = (*it).first.method_name; } return MethodResponse (arr); }
void Dispatcher::setupSystemMethods() { ULXR_TRACE("setupSystemMethods"); addMethod(&Dispatcher::xml_pretty_print, "", "ulxmlrpcpp.pretty_print", "bool", "Enable pretty-printed xml responses."); //-- addMethod(&Dispatcher::system_listMethods, "array", "system.listMethods", "", "Lists all methods implemented by this server."); addMethod( &Dispatcher::system_listMethods, "array","system.listMethods", "string", "Lists all methods implemented by this server (overloaded)."); addMethod( &Dispatcher::system_methodSignature, "array", "system.methodSignature", "string", "Returns an array of possible signatures for this method."); addMethod(&Dispatcher::system_methodHelp, "string", "system.methodHelp", "string", "Returns a documentation string describing the use of this method."); addMethod(&Dispatcher::system_getCapabilities, "struct", "system.getCapabilities", "", "Returns Structs describing available capabilities."); }
ULXR_API_IMPL(void) FileResource::close() { ULXR_TRACE(ULXR_PCHAR("FileResource::close ") << filename); if (!opened) return; // size_t written; const std::string dat = data(); const unsigned len = dat.length(); ulxr_FILE *ifs = ulxr_fopen (getLatin1(filename).c_str(), "wb"); if (ifs != 0) { if (len != 0) { /* written = */ ulxr_fwrite(dat.data(), 1, len, ifs); if (ulxr_ferror(ifs)) error = true; } ulxr_fclose (ifs); } else error = true; opened = false; CachedResource::clear(); }
ULXR_API_IMPL(Cpp8BitString) HttpClient::msgPOST( const Cpp8BitString &msg, const CppString &type, const CppString &resource) { ULXR_TRACE(ULXR_PCHAR("msgPOST")); Cpp8BitString ret; if (!protocol->isOpen() ) protocol->open(); sendAuthentication(); protocol->sendRequestHeader(ULXR_PCHAR("POST"), resource, type, msg.length()); protocol->writeBody(msg.data(), msg.length()); StringProcessor sp (ret); receiveResponse(sp); if (getHttpStatus() != 200) throw ConnectionException(TransportError, getHttpPhrase(), getHttpStatus()); if (!protocol->isPersistent() ) protocol->close(); return ret; }
std::string Dispatcher::MethodCallDescriptor::getSignature(bool with_name, bool with_return) const { ULXR_TRACE("getSignature"); std::string s; std::string rs = return_signature; if (rs.length() == 0) rs = "void"; // emergency brake std::string sig = signature; if (sig.length() == 0) sig = "void"; // emergency brake if (with_return && with_name) s = rs + " " + method_name + "(" + sig + ")"; else if (!with_return && with_name) s = method_name + "(" + sig + ")"; else if (with_return && !with_name) { s = rs; if (sig.length() != 0) s += "," + sig; } else if (!with_return && !with_name) s = sig; return s; }
ULXR_API_IMPL(void) HttpClient::setMessageAuthentication(const CppString &user, const CppString &pass) { ULXR_TRACE(ULXR_PCHAR("setMessageAuthentication")); http_user = user; http_pass = pass; }
ULXR_API_IMPL(void) HttpClient::receiveResponse(BodyProcessor &proc) { ULXR_TRACE(ULXR_PCHAR("receiveResponse")); protocol->resetConnection(); char buffer[ULXR_RECV_BUFFER_SIZE]; char *buff_ptr; bool done = false; long readed; while (!done && ((readed = protocol->readRaw(buffer, sizeof(buffer))) > 0) ) { buff_ptr = buffer; if (!protocol->hasBytesToRead()) done = true; while (readed > 0) { Protocol::State state = protocol->connectionMachine(buff_ptr, readed); if (state == Protocol::ConnError) throw ConnectionException(TransportError, ulxr_i18n(ULXR_PCHAR("network problem occured")), 500); // switch to appropriate method when header is completely read else if ( state == Protocol::ConnSwitchToBody || state == Protocol::ConnBody) { interpreteHttpHeader(); proc.process(buff_ptr, readed); readed = 0; } } } }
long Protocol::readRaw(char *buff, long len) { ULXR_TRACE("readRaw, want: " << len); if (pimpl->remain_content_length >= 0) { ULXR_TRACE("read 0 " << len << " " << getRemainingContentLength()); if (pimpl->remain_content_length < len) len = pimpl->remain_content_length; } long myRead = getConnection()->read(buff, len); if (pimpl->remain_content_length >= 0) pimpl->remain_content_length -= myRead; return myRead; }
void Protocol::addAuthentication(const std::string &user, const std::string &pass, const std::string &realm) { ULXR_TRACE("addAuthentication"); pimpl->authdata.push_back(AuthData(stripWS(user), stripWS(pass), stripWS(realm))); }
Protocol::Protocol(Connection *conn) : pimpl (new PImpl) { pimpl->connection = conn; pimpl->delete_connection = false; ULXR_TRACE("Protocol"); init(); }
Requester::call (const MethodCall& calldata, const CppString &rpc_root, const CppString &user, const CppString &pass) { ULXR_TRACE(ULXR_PCHAR("call(..,user, pass)")); protocol->setMessageAuthentication(user, pass); send_call (calldata, rpc_root); return waitForResponse(); }
bool MethodResponseParser::testStartElement(const XML_Char* name, const XML_Char** /*atts*/) { ULXR_TRACE("MethodResponseParser::testStartElement(const XML_Char*, const char**)" << "\n name: " << name ); switch(states.top()->getParserState() ) { case eNone: if(strcmp(name, "methodResponse") == 0) { setComplete (false); states.push(new ValueState(eMethodResponse)); } else return false; break; case eMethodResponse: if(strcmp(name, "fault") == 0) states.push(new ValueState(eFault)); else if(strcmp(name, "params") == 0) states.push(new ValueState(eParams)); else return false; break; case eFault: if(strcmp(name, "value") == 0) states.push(new ValueState(eValue)); else return false; break; case eParams: if(strcmp(name, "param") == 0) states.push(new ValueState(eParam)); else return false; break; case eParam: if(strcmp(name, "value") == 0) states.push(new ValueState(eValue)); else return false; break; default: return false; } return true; }
ULXR_API_IMPL(void) TcpIpConnection::open() { ULXR_TRACE(ULXR_PCHAR("open")); if (isOpen() ) throw RuntimeException(ApplicationError, ulxr_i18n(ULXR_PCHAR("Attempt to open an already open connection"))); if (pimpl->server_data != 0) throw ConnectionException(SystemError, ulxr_i18n(ULXR_PCHAR("Connection is NOT prepared for client mode")), 500); // resetConnection(); setHandle(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); if (getHandle() < 0) throw ConnectionException(SystemError, ulxr_i18n(ULXR_PCHAR("Could not create socket: ")) + ULXR_GET_STRING(getErrorString(getLastError())), 500); int iOptVal = getTimeout() * 1000; int iOptLen = sizeof(int); ::setsockopt(getHandle(), SOL_SOCKET, SO_RCVTIMEO, (char*)&iOptVal, iOptLen); ::setsockopt(getHandle(), SOL_SOCKET, SO_SNDTIMEO, (char*)&iOptVal, iOptLen); doTcpNoDelay(); if(connect(getHandle(), (struct sockaddr *)&pimpl->hostdata, sizeof(pimpl->hostdata)) < 0) throw ConnectionException(SystemError, ulxr_i18n(ULXR_PCHAR("Could not connect: ")) + ULXR_GET_STRING(getErrorString(getLastError())), 500); ULXR_TRACE(ULXR_PCHAR("/open.peername")); #ifdef ULXR_ENABLE_GET_PEERNAME pimpl->remotedata_len = sizeof(pimpl->remotedata); if(getpeername(getHandle(), (struct sockaddr *)&pimpl->remotedata, &pimpl->remotedata_len)<0) throw ConnectionException(SystemError, ulxr_i18n(ULXR_PCHAR("Could not get peer data: ")) + ULXR_GET_STRING(getErrorString(getLastError())), 500); #ifdef __BORLANDC__ pimpl->remote_name = ULXR_PCHAR("<remote-host>"); // FIXME, not working host = 0; host; #else else {
void free_dynamic_method (const Dispatcher::MethodCallMap::value_type &method) { if (method.first.getCallType() == Dispatcher::CallDynamic) { ULXR_TRACE("Now deleting dynamic function: " + method.first.getSignature(true, true)); delete method.second.dynamic_function; const_cast<Dispatcher::MethodCallMap::value_type&>(method).second.dynamic_function = 0; } }
Protocol::~Protocol() { ULXR_TRACE("~Protocol"); if (pimpl->delete_connection) delete pimpl->connection; pimpl->connection = NULL; delete pimpl; pimpl = NULL; }
ULXR_API_IMPL(void) HttpClient::interpreteHttpHeader() { ULXR_TRACE(ULXR_PCHAR("interpreteHttpHeader")); head_version = ULXR_PCHAR(""); head_status = 500; head_phrase = ULXR_PCHAR("Internal error"); protocol->splitHeaderLine(head_version, head_status, head_phrase); protocol->setPersistent(!protocol->determineClosing(head_version)); }
unsigned Dispatcher::numMethods() const { ULXR_TRACE("numMethods"); unsigned i = 0; MethodCallMap::const_iterator it; for (it = methodcalls.begin(); it != methodcalls.end(); ++it) ++i; return i; }
Value ValueParserBase::getValue() const { ULXR_TRACE("ValueParserBase::getValue()"); Value *v = getTopValueState()->getValue(); if (v != 0) return *v; else return Value(); // return ulxr::Void() }
void ValueParserBase::ArrayState::takeValue(Value *v, bool del) { candel = del; ULXR_TRACE("ValueParserBase::ArrayState::takeValue(Value *)"); if (value == 0) value = new Value(Array()); value->getArray()->addItem(*v); delete v; }
ULXR_API_IMPL(void) TcpIpConnection::setProxy(const CppString &dom, unsigned port) { ULXR_TRACE(ULXR_PCHAR("setProxy ") << dom << ULXR_PCHAR(" ") << port); struct hostent *hp = getHostAdress(dom); if (hp == 0) throw ConnectionException(SystemError, ulxr_i18n(ULXR_PCHAR("Host adress for proxy not found: ")) + dom, 500); memcpy(&(pimpl->hostdata.sin_addr), hp->h_addr_list[0], hp->h_length); pimpl->hostdata.sin_port = htons(port); }