PageRenderTime 131ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmessage/llsdrpcclient.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 254 lines | 190 code | 15 blank | 49 comment | 17 complexity | c82ac775c483a296a1665ecdc6f85f12 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsdrpcclient.cpp
  3. * @author Phoenix
  4. * @date 2005-11-05
  5. * @brief Implementation of the llsd client classes.
  6. *
  7. * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. #include "linden_common.h"
  29. #include "llsdrpcclient.h"
  30. #include "llbufferstream.h"
  31. #include "llfiltersd2xmlrpc.h"
  32. #include "llmemtype.h"
  33. #include "llpumpio.h"
  34. #include "llsd.h"
  35. #include "llsdserialize.h"
  36. #include "llurlrequest.h"
  37. /**
  38. * String constants
  39. */
  40. static std::string LLSDRPC_RESPONSE_NAME("response");
  41. static std::string LLSDRPC_FAULT_NAME("fault");
  42. /**
  43. * LLSDRPCResponse
  44. */
  45. LLSDRPCResponse::LLSDRPCResponse() :
  46. mIsError(false),
  47. mIsFault(false)
  48. {
  49. LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
  50. }
  51. // virtual
  52. LLSDRPCResponse::~LLSDRPCResponse()
  53. {
  54. LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
  55. }
  56. bool LLSDRPCResponse::extractResponse(const LLSD& sd)
  57. {
  58. LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
  59. bool rv = true;
  60. if(sd.has(LLSDRPC_RESPONSE_NAME))
  61. {
  62. mReturnValue = sd[LLSDRPC_RESPONSE_NAME];
  63. mIsFault = false;
  64. }
  65. else if(sd.has(LLSDRPC_FAULT_NAME))
  66. {
  67. mReturnValue = sd[LLSDRPC_FAULT_NAME];
  68. mIsFault = true;
  69. }
  70. else
  71. {
  72. mReturnValue.clear();
  73. mIsError = true;
  74. rv = false;
  75. }
  76. return rv;
  77. }
  78. static LLFastTimer::DeclareTimer FTM_SDRPC_RESPONSE("SDRPC Response");
  79. // virtual
  80. LLIOPipe::EStatus LLSDRPCResponse::process_impl(
  81. const LLChannelDescriptors& channels,
  82. buffer_ptr_t& buffer,
  83. bool& eos,
  84. LLSD& context,
  85. LLPumpIO* pump)
  86. {
  87. LLFastTimer t(FTM_SDRPC_RESPONSE);
  88. PUMP_DEBUG;
  89. LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
  90. if(mIsError)
  91. {
  92. error(pump);
  93. }
  94. else if(mIsFault)
  95. {
  96. fault(pump);
  97. }
  98. else
  99. {
  100. response(pump);
  101. }
  102. PUMP_DEBUG;
  103. return STATUS_DONE;
  104. }
  105. /**
  106. * LLSDRPCClient
  107. */
  108. LLSDRPCClient::LLSDRPCClient() :
  109. mState(STATE_NONE),
  110. mQueue(EPBQ_PROCESS)
  111. {
  112. LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
  113. }
  114. // virtual
  115. LLSDRPCClient::~LLSDRPCClient()
  116. {
  117. LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
  118. }
  119. bool LLSDRPCClient::call(
  120. const std::string& uri,
  121. const std::string& method,
  122. const LLSD& parameter,
  123. LLSDRPCResponse* response,
  124. EPassBackQueue queue)
  125. {
  126. LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
  127. //llinfos << "RPC: " << uri << "." << method << "(" << *parameter << ")"
  128. // << llendl;
  129. if(method.empty() || !response)
  130. {
  131. return false;
  132. }
  133. mState = STATE_READY;
  134. mURI.assign(uri);
  135. std::stringstream req;
  136. req << LLSDRPC_REQUEST_HEADER_1 << method
  137. << LLSDRPC_REQUEST_HEADER_2;
  138. LLSDSerialize::toNotation(parameter, req);
  139. req << LLSDRPC_REQUEST_FOOTER;
  140. mRequest = req.str();
  141. mQueue = queue;
  142. mResponse = response;
  143. return true;
  144. }
  145. bool LLSDRPCClient::call(
  146. const std::string& uri,
  147. const std::string& method,
  148. const std::string& parameter,
  149. LLSDRPCResponse* response,
  150. EPassBackQueue queue)
  151. {
  152. LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
  153. //llinfos << "RPC: " << uri << "." << method << "(" << parameter << ")"
  154. // << llendl;
  155. if(method.empty() || parameter.empty() || !response)
  156. {
  157. return false;
  158. }
  159. mState = STATE_READY;
  160. mURI.assign(uri);
  161. std::stringstream req;
  162. req << LLSDRPC_REQUEST_HEADER_1 << method
  163. << LLSDRPC_REQUEST_HEADER_2 << parameter
  164. << LLSDRPC_REQUEST_FOOTER;
  165. mRequest = req.str();
  166. mQueue = queue;
  167. mResponse = response;
  168. return true;
  169. }
  170. static LLFastTimer::DeclareTimer FTM_PROCESS_SDRPC_CLIENT("SDRPC Client");
  171. // virtual
  172. LLIOPipe::EStatus LLSDRPCClient::process_impl(
  173. const LLChannelDescriptors& channels,
  174. buffer_ptr_t& buffer,
  175. bool& eos,
  176. LLSD& context,
  177. LLPumpIO* pump)
  178. {
  179. LLFastTimer t(FTM_PROCESS_SDRPC_CLIENT);
  180. PUMP_DEBUG;
  181. LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
  182. if((STATE_NONE == mState) || (!pump))
  183. {
  184. // You should have called the call() method already.
  185. return STATUS_PRECONDITION_NOT_MET;
  186. }
  187. EStatus rv = STATUS_DONE;
  188. switch(mState)
  189. {
  190. case STATE_READY:
  191. {
  192. PUMP_DEBUG;
  193. // lldebugs << "LLSDRPCClient::process_impl STATE_READY" << llendl;
  194. buffer->append(
  195. channels.out(),
  196. (U8*)mRequest.c_str(),
  197. mRequest.length());
  198. context[CONTEXT_DEST_URI_SD_LABEL] = mURI;
  199. mState = STATE_WAITING_FOR_RESPONSE;
  200. break;
  201. }
  202. case STATE_WAITING_FOR_RESPONSE:
  203. {
  204. PUMP_DEBUG;
  205. // The input channel has the sd response in it.
  206. //lldebugs << "LLSDRPCClient::process_impl STATE_WAITING_FOR_RESPONSE"
  207. // << llendl;
  208. LLBufferStream resp(channels, buffer.get());
  209. LLSD sd;
  210. LLSDSerialize::fromNotation(sd, resp, buffer->count(channels.in()));
  211. LLSDRPCResponse* response = (LLSDRPCResponse*)mResponse.get();
  212. if (!response)
  213. {
  214. mState = STATE_DONE;
  215. break;
  216. }
  217. response->extractResponse(sd);
  218. if(EPBQ_PROCESS == mQueue)
  219. {
  220. LLPumpIO::chain_t chain;
  221. chain.push_back(mResponse);
  222. pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS);
  223. }
  224. else
  225. {
  226. pump->respond(mResponse.get());
  227. }
  228. mState = STATE_DONE;
  229. break;
  230. }
  231. case STATE_DONE:
  232. default:
  233. PUMP_DEBUG;
  234. llinfos << "invalid state to process" << llendl;
  235. rv = STATUS_ERROR;
  236. break;
  237. }
  238. return rv;
  239. }