ulxr_protocol.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                      ulxr_protocol.cpp  -  rpc prootocol
00003                              -------------------
00004     begin                : Mon May 3 2004
00005     copyright            : (C) 2002-2007 by Ewald Arnold
00006     email                : ulxmlrpcpp@ewald-arnold.de
00007 
00008     $Id: ulxr_protocol.cpp 1062 2007-08-19 09:07:58Z ewald-arnold $
00009 
00010  ***************************************************************************/
00011 
00012 /**************************************************************************
00013  *
00014  * This program is free software; you can redistribute it and/or modify
00015  * it under the terms of the GNU Lesser General Public License as
00016  * published by the Free Software Foundation; either version 2 of the License,
00017  * or (at your option) any later version.
00018  *
00019  * This program is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program; if not, write to the Free Software
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00027  *
00028  ***************************************************************************/
00029 
00030 // #define ULXR_SHOW_TRACE
00031 // #define ULXR_DEBUG_OUTPUT
00032 // #define ULXR_SHOW_READ
00033 // #define ULXR_SHOW_WRITE
00034 
00035 #define ULXR_NEED_EXPORTS
00036 #include <ulxmlrpcpp/ulxmlrpcpp.h>  // always first header
00037 
00038 #include <ulxmlrpcpp/ulxr_connection.h>
00039 #include <ulxmlrpcpp/ulxr_protocol.h>
00040 #include <ulxmlrpcpp/ulxr_response.h>
00041 #include <ulxmlrpcpp/ulxr_call.h>
00042 
00043 
00044 namespace ulxr {
00045 
00046 
00047 struct Protocol::AuthData
00048 {
00049   AuthData(const CppString &user_, const CppString &pass_, const CppString &realm_)
00050   : user(user_)
00051   , pass(pass_)
00052   , realm(realm_)
00053   {}
00054 
00055   CppString  user;
00056   CppString  pass;
00057   CppString  realm;
00058 };
00059 
00060 
00061 struct Protocol::PImpl
00062 {
00063    Connection     *connection;
00064    bool            delete_connection;
00065    State           connstate;
00066    long            content_length;
00067    long            remain_content_length;
00068    bool            persistent;
00069 
00070    std::vector<AuthData>  authdata;
00071 };
00072 
00073 
00074 ULXR_API_IMPL0 Protocol::Protocol(const Protocol &prot)
00075   : pimpl (new PImpl)
00076 {
00077   *pimpl = *prot.pimpl;
00078 }
00079 
00080 
00081 ULXR_API_IMPL0 Protocol::Protocol(Connection *conn)
00082   : pimpl (new PImpl)
00083 {
00084   pimpl->connection = conn;
00085   pimpl->delete_connection = false;
00086   ULXR_TRACE(ULXR_PCHAR("Protocol"));
00087   init();
00088 }
00089 
00090 
00091 ULXR_API_IMPL0 Protocol::~Protocol()
00092 {
00093   ULXR_TRACE(ULXR_PCHAR("~Protocol"));
00094   if (pimpl->delete_connection)
00095     delete pimpl->connection;
00096   pimpl->connection = 0;
00097   delete pimpl;
00098   pimpl = 0;
00099 }
00100 
00101 
00102 ULXR_API_IMPL(void) Protocol::init()
00103 {
00104   ULXR_TRACE(ULXR_PCHAR("init"));
00105   setPersistent(false);
00106   resetConnection();
00107 }
00108 
00109 
00110 ULXR_API_IMPL(void) Protocol::writeRaw(char const *buff, long len)
00111 {
00112   ULXR_TRACE(ULXR_PCHAR("writeRaw"));
00113   getConnection()->write(buff, len);
00114 }
00115 
00116 
00117 ULXR_API_IMPL(long) Protocol::readRaw(char *buff, long len)
00118 {
00119   ULXR_TRACE(ULXR_PCHAR("readRaw, want: ") << len);
00120   if (pimpl->remain_content_length >= 0)
00121   {
00122     ULXR_TRACE(ULXR_PCHAR("read 0 ") << len << ULXR_PCHAR(" ") << getRemainingContentLength());
00123     if (pimpl->remain_content_length < len)
00124       len = pimpl->remain_content_length;
00125   }
00126 
00127   long readed = getConnection()->read(buff, len);
00128 
00129   if (pimpl->remain_content_length >= 0)
00130     pimpl->remain_content_length -= readed;
00131 
00132   return readed;
00133 }
00134 
00135 
00136 ULXR_API_IMPL(void) Protocol::open()
00137 {
00138   ULXR_TRACE(ULXR_PCHAR("open"));
00139   getConnection()->open();
00140   resetConnection();
00141 }
00142 
00143 
00144 ULXR_API_IMPL(bool) Protocol::isOpen() const
00145 {
00146   const Connection *conn = getConnection();
00147   bool op = conn != 0 && conn->isOpen();
00148   ULXR_TRACE(ULXR_PCHAR("isOpen ") << op);
00149   return op;
00150 }
00151 
00152 
00153 ULXR_API_IMPL(bool) Protocol::accept(int _timeout)
00154 {
00155   ULXR_TRACE(ULXR_PCHAR("accept"));
00156   bool res = getConnection()->accept(_timeout);
00157   resetConnection();
00158   return res;
00159 }
00160 
00161 
00162 ULXR_API_IMPL(void) Protocol::close()
00163 {
00164   ULXR_TRACE(ULXR_PCHAR("close"));
00165   if (getConnection() != 0)
00166     getConnection()->close();
00167 //  resetConnection();
00168 }
00169 
00170 
00171 ULXR_API_IMPL(Connection *) Protocol::getConnection() const
00172 {
00173   ULXR_TRACE(ULXR_PCHAR("getConnection"));
00174   return pimpl->connection;
00175 }
00176 
00177 
00178 ULXR_API_IMPL(void) Protocol::setConnection(Connection *conn)
00179 {
00180   ULXR_TRACE(ULXR_PCHAR("getConnection"));
00181   pimpl->connection = conn;
00182   pimpl->delete_connection = true;
00183   ULXR_TRACE(ULXR_PCHAR("/getConnection"));
00184 }
00185 
00186 
00187 ULXR_API_IMPL(Protocol::State) Protocol::getConnectionState() const
00188 {
00189   return pimpl->connstate;
00190 }
00191 
00192 
00193 ULXR_API_IMPL(void) Protocol::setConnectionState(State state)
00194 {
00195   pimpl->connstate = state;
00196 }
00197 
00198 
00199 ULXR_API_IMPL(void) Protocol::setRemainingContentLength(long len)
00200 {
00201   pimpl->remain_content_length = len;
00202 }
00203 
00204 
00205 ULXR_API_IMPL(long) Protocol::getRemainingContentLength() const
00206 {
00207   return pimpl->remain_content_length;
00208 }
00209 
00210 
00211 ULXR_API_IMPL(long) Protocol::getContentLength() const
00212 {
00213   return pimpl->content_length;
00214 }
00215 
00216 
00217 ULXR_API_IMPL(void) Protocol::setContentLength(long len)
00218 {
00219   pimpl->content_length = len;
00220 }
00221 
00222 
00223 ULXR_API_IMPL(Protocol::State)
00224   Protocol::connectionMachine(char * &/*buffer*/, long &/*len*/)
00225 {
00226   ULXR_TRACE(ULXR_PCHAR("connectionMachine"));
00227   pimpl->connstate = ConnBody;
00228   return ConnBody;
00229 }
00230 
00231 
00232 ULXR_API_IMPL(void) Protocol::sendRpcResponse(const MethodResponse &resp, bool wbxml_mode)
00233 {
00234   ULXR_TRACE(ULXR_PCHAR("sendRpcResponse"));
00235   if (wbxml_mode)
00236   {
00237     std::string xml = resp.getWbXml();
00238     getConnection()->write(xml.c_str(), xml.length());
00239   }
00240   else
00241   {
00242     CppString xml = resp.getXml(0)+ULXR_PCHAR("\n");
00243 
00244 #ifdef ULXR_UNICODE
00245     Cpp8BitString utf = unicodeToUtf8(xml);
00246     getConnection()->write(utf.c_str(), utf.length());
00247 #else
00248     getConnection()->write(xml.c_str(), xml.length());
00249 #endif
00250   }
00251 }
00252 
00253 
00254 ULXR_API_IMPL(void) Protocol::sendRpcCall(const MethodCall &call,
00255                                        const CppString &/*resource*/,
00256                                        bool wbxml_mode)
00257 {
00258   ULXR_TRACE(ULXR_PCHAR("sendRpcCall"));
00259   if (wbxml_mode)
00260   {
00261     std::string xml = call.getWbXml();
00262     getConnection()->write(xml.c_str(), xml.length());
00263   }
00264   else
00265   {
00266     CppString xml = call.getXml(0)+ULXR_PCHAR("\n");
00267 #ifdef ULXR_UNICODE
00268     Cpp8BitString utf = unicodeToUtf8(xml);
00269     getConnection()->write(utf.c_str(), utf.length());
00270 #else
00271     getConnection()->write(xml.c_str(), xml.length());
00272 #endif
00273   }
00274 }
00275 
00276 
00277 ULXR_API_IMPL(void)
00278   Protocol::addAuthentication(const CppString &user,
00279                               const CppString &pass,
00280                               const CppString &realm)
00281 {
00282   ULXR_TRACE(ULXR_PCHAR("addAuthentication"));
00283   pimpl->authdata.push_back(AuthData(stripWS(user), stripWS(pass), stripWS(realm)));
00284 }
00285 
00286 
00287 ULXR_API_IMPL(bool) Protocol::checkAuthentication(const CppString &realm) const
00288 {
00289   ULXR_TRACE(ULXR_PCHAR("checkAuthentication ") << realm);
00290   if (pimpl->authdata.size() == 0)
00291     return true;   // accept all
00292 
00293   ULXR_TRACE(ULXR_PCHAR("checkAuthentication 1"));
00294   CppString user, pass;
00295   if (!getUserPass(user, pass))
00296     return false;
00297 
00298   ULXR_TRACE(ULXR_PCHAR("checkAuthentication 2 ")
00299              << ULXR_PCHAR("user: ") << user
00300              << ULXR_PCHAR(" pass: ") << pass);
00301   for (unsigned i = 0; i < pimpl->authdata.size(); ++i)
00302     if (   pimpl->authdata[i].user == user
00303         && pimpl->authdata[i].pass == pass
00304         && pimpl->authdata[i].realm == realm)
00305       return true;
00306 
00307   ULXR_TRACE(ULXR_PCHAR("checkAuthentication 3"));
00308   return false;
00309 }
00310 
00311 
00312 ULXR_API_IMPL(bool) Protocol::getUserPass(CppString & /* user */,
00313                                        CppString & /* pass */) const
00314 {
00315   ULXR_TRACE(ULXR_PCHAR("getUserPass"));
00316   return false;
00317 }
00318 
00319 
00320 ULXR_API_IMPL(void) Protocol::rejectAuthentication(const CppString & /* realm */)
00321 {
00322   ULXR_TRACE(ULXR_PCHAR("rejectAuthentication"));
00323 }
00324 
00325 
00326 ULXR_API_IMPL(void) Protocol::setMessageAuthentication(const CppString & /* user */,
00327                                                     const CppString & /* pass */)
00328 {
00329   ULXR_TRACE(ULXR_PCHAR("setMessageAuthentication"));
00330 }
00331 
00332 
00333 ULXR_API_IMPL(void) Protocol::setTransmitOnly()
00334 {
00335   ULXR_TRACE(ULXR_PCHAR("setTransmitOnly"));
00336 }
00337 
00338 
00339 ULXR_API_IMPL(bool) Protocol::isTransmitOnly()
00340 {
00341   ULXR_TRACE(ULXR_PCHAR("isTransmitOnly"));
00342   return false; // always return a value
00343 }
00344 
00345 
00346 ULXR_API_IMPL(void) Protocol::resetConnection()
00347 {
00348   ULXR_TRACE(ULXR_PCHAR("resetConnection"));
00349   pimpl->connstate = ConnStart;
00350   pimpl->remain_content_length = -1;
00351   pimpl->content_length = -1;
00352 //  getConnection()->setTimeout(getConnection()->getDefaultTimeout());
00353 }
00354 
00355 
00356 ULXR_API_IMPL(void) Protocol::setPersistent(bool pers)
00357 {
00358   ULXR_TRACE(ULXR_PCHAR("setPersistent ") << pers);
00359   pimpl->persistent = pers;
00360 
00361   Connection *conn = getConnection();
00362   if (pers)
00363     conn->setTimeout(conn->getPersistentTimeout());
00364   else
00365     conn->setTimeout(conn->getDefaultTimeout());
00366 }
00367 
00368 
00369 ULXR_API_IMPL(bool) Protocol::isPersistent() const
00370 {
00371   return pimpl->persistent;
00372 }
00373 
00374 
00375 }  // namespace ulxr

Generated on Sun Aug 19 20:08:57 2007 for ulxmlrpcpp by  doxygen 1.5.1