00001
00034 #include "linden_common.h"
00035 #include "llsdrpcclient.h"
00036
00037 #include "llbufferstream.h"
00038 #include "llfiltersd2xmlrpc.h"
00039 #include "llmemtype.h"
00040 #include "llpumpio.h"
00041 #include "llsd.h"
00042 #include "llsdserialize.h"
00043 #include "llurlrequest.h"
00044
00048 static std::string LLSDRPC_RESPONSE_NAME("response");
00049 static std::string LLSDRPC_FAULT_NAME("fault");
00050
00054 LLSDRPCResponse::LLSDRPCResponse() :
00055 mIsError(false),
00056 mIsFault(false)
00057 {
00058 LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00059 }
00060
00061
00062 LLSDRPCResponse::~LLSDRPCResponse()
00063 {
00064 LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00065 }
00066
00067 bool LLSDRPCResponse::extractResponse(const LLSD& sd)
00068 {
00069 LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00070 bool rv = true;
00071 if(sd.has(LLSDRPC_RESPONSE_NAME))
00072 {
00073 mReturnValue = sd[LLSDRPC_RESPONSE_NAME];
00074 mIsFault = false;
00075 }
00076 else if(sd.has(LLSDRPC_FAULT_NAME))
00077 {
00078 mReturnValue = sd[LLSDRPC_FAULT_NAME];
00079 mIsFault = true;
00080 }
00081 else
00082 {
00083 mReturnValue.clear();
00084 mIsError = true;
00085 rv = false;
00086 }
00087 return rv;
00088 }
00089
00090
00091 LLIOPipe::EStatus LLSDRPCResponse::process_impl(
00092 const LLChannelDescriptors& channels,
00093 buffer_ptr_t& buffer,
00094 bool& eos,
00095 LLSD& context,
00096 LLPumpIO* pump)
00097 {
00098 PUMP_DEBUG;
00099 LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00100 if(mIsError)
00101 {
00102 error(pump);
00103 }
00104 else if(mIsFault)
00105 {
00106 fault(pump);
00107 }
00108 else
00109 {
00110 response(pump);
00111 }
00112 PUMP_DEBUG;
00113 return STATUS_DONE;
00114 }
00115
00120 LLSDRPCClient::LLSDRPCClient() :
00121 mState(STATE_NONE),
00122 mQueue(EPBQ_PROCESS)
00123 {
00124 LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00125 }
00126
00127
00128 LLSDRPCClient::~LLSDRPCClient()
00129 {
00130 LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00131 }
00132
00133 bool LLSDRPCClient::call(
00134 const std::string& uri,
00135 const std::string& method,
00136 const LLSD& parameter,
00137 LLSDRPCResponse* response,
00138 EPassBackQueue queue)
00139 {
00140 LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00141
00142
00143 if(method.empty() || !response)
00144 {
00145 return false;
00146 }
00147 mState = STATE_READY;
00148 mURI.assign(uri);
00149 std::stringstream req;
00150 req << LLSDRPC_REQUEST_HEADER_1 << method
00151 << LLSDRPC_REQUEST_HEADER_2;
00152 LLSDSerialize::toNotation(parameter, req);
00153 req << LLSDRPC_REQUEST_FOOTER;
00154 mRequest = req.str();
00155 mQueue = queue;
00156 mResponse = response;
00157 return true;
00158 }
00159
00160 bool LLSDRPCClient::call(
00161 const std::string& uri,
00162 const std::string& method,
00163 const std::string& parameter,
00164 LLSDRPCResponse* response,
00165 EPassBackQueue queue)
00166 {
00167 LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00168
00169
00170 if(method.empty() || parameter.empty() || !response)
00171 {
00172 return false;
00173 }
00174 mState = STATE_READY;
00175 mURI.assign(uri);
00176 std::stringstream req;
00177 req << LLSDRPC_REQUEST_HEADER_1 << method
00178 << LLSDRPC_REQUEST_HEADER_2 << parameter
00179 << LLSDRPC_REQUEST_FOOTER;
00180 mRequest = req.str();
00181 mQueue = queue;
00182 mResponse = response;
00183 return true;
00184 }
00185
00186
00187 LLIOPipe::EStatus LLSDRPCClient::process_impl(
00188 const LLChannelDescriptors& channels,
00189 buffer_ptr_t& buffer,
00190 bool& eos,
00191 LLSD& context,
00192 LLPumpIO* pump)
00193 {
00194 PUMP_DEBUG;
00195 LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
00196 if((STATE_NONE == mState) || (!pump))
00197 {
00198
00199 return STATUS_PRECONDITION_NOT_MET;
00200 }
00201 EStatus rv = STATUS_DONE;
00202 switch(mState)
00203 {
00204 case STATE_READY:
00205 {
00206 PUMP_DEBUG;
00207
00208 buffer->append(
00209 channels.out(),
00210 (U8*)mRequest.c_str(),
00211 mRequest.length());
00212 context[CONTEXT_DEST_URI_SD_LABEL] = mURI;
00213 mState = STATE_WAITING_FOR_RESPONSE;
00214 break;
00215 }
00216 case STATE_WAITING_FOR_RESPONSE:
00217 {
00218 PUMP_DEBUG;
00219
00220
00221
00222 LLBufferStream resp(channels, buffer.get());
00223 LLSD sd;
00224 LLSDSerialize::fromNotation(sd, resp);
00225 LLSDRPCResponse* response = (LLSDRPCResponse*)mResponse.get();
00226 if (!response)
00227 {
00228 mState = STATE_DONE;
00229 break;
00230 }
00231 response->extractResponse(sd);
00232 if(EPBQ_PROCESS == mQueue)
00233 {
00234 LLPumpIO::chain_t chain;
00235 chain.push_back(mResponse);
00236 pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS);
00237 }
00238 else
00239 {
00240 pump->respond(mResponse.get());
00241 }
00242 mState = STATE_DONE;
00243 break;
00244 }
00245 case STATE_DONE:
00246 default:
00247 PUMP_DEBUG;
00248 llinfos << "invalid state to process" << llendl;
00249 rv = STATUS_ERROR;
00250 break;
00251 }
00252 return rv;
00253 }