PageRenderTime 46ms CodeModel.GetById 14ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 1ms

/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
  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
 29#include "linden_common.h"
 30#include "llsdrpcclient.h"
 31
 32#include "llbufferstream.h"
 33#include "llfiltersd2xmlrpc.h"
 34#include "llmemtype.h"
 35#include "llpumpio.h"
 36#include "llsd.h"
 37#include "llsdserialize.h"
 38#include "llurlrequest.h"
 39
 40/**
 41 * String constants
 42 */
 43static std::string LLSDRPC_RESPONSE_NAME("response");
 44static std::string LLSDRPC_FAULT_NAME("fault");
 45
 46/** 
 47 * LLSDRPCResponse
 48 */
 49LLSDRPCResponse::LLSDRPCResponse() :
 50	mIsError(false),
 51	mIsFault(false)
 52{
 53	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
 54}
 55
 56// virtual
 57LLSDRPCResponse::~LLSDRPCResponse()
 58{
 59	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
 60}
 61
 62bool LLSDRPCResponse::extractResponse(const LLSD& sd)
 63{
 64	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
 65	bool rv = true;
 66	if(sd.has(LLSDRPC_RESPONSE_NAME))
 67	{
 68		mReturnValue = sd[LLSDRPC_RESPONSE_NAME];
 69		mIsFault = false;
 70	}
 71	else if(sd.has(LLSDRPC_FAULT_NAME))
 72	{
 73		mReturnValue = sd[LLSDRPC_FAULT_NAME];
 74		mIsFault = true;
 75	}
 76	else
 77	{
 78		mReturnValue.clear();
 79		mIsError = true;
 80		rv = false;
 81	}
 82	return rv;
 83}
 84
 85static LLFastTimer::DeclareTimer FTM_SDRPC_RESPONSE("SDRPC Response");
 86
 87// virtual
 88LLIOPipe::EStatus LLSDRPCResponse::process_impl(
 89	const LLChannelDescriptors& channels,
 90	buffer_ptr_t& buffer,
 91	bool& eos,
 92	LLSD& context,
 93	LLPumpIO* pump)
 94{
 95	LLFastTimer t(FTM_SDRPC_RESPONSE);
 96	PUMP_DEBUG;
 97	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
 98	if(mIsError)
 99	{
100		error(pump);
101	}
102	else if(mIsFault)
103	{
104		fault(pump);
105	}
106	else
107	{
108		response(pump);
109	}
110	PUMP_DEBUG;
111	return STATUS_DONE;
112}
113
114/** 
115 * LLSDRPCClient
116 */
117
118LLSDRPCClient::LLSDRPCClient() :
119	mState(STATE_NONE),
120	mQueue(EPBQ_PROCESS)
121{
122	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
123}
124
125// virtual
126LLSDRPCClient::~LLSDRPCClient()
127{
128	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
129}
130
131bool LLSDRPCClient::call(
132	const std::string& uri,
133	const std::string& method,
134	const LLSD& parameter,
135	LLSDRPCResponse* response,
136	EPassBackQueue queue)
137{
138	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
139	//llinfos << "RPC: " << uri << "." << method << "(" << *parameter << ")"
140	//		<< llendl;
141	if(method.empty() || !response)
142	{
143		return false;
144	}
145	mState = STATE_READY;
146	mURI.assign(uri);
147	std::stringstream req;
148	req << LLSDRPC_REQUEST_HEADER_1 << method
149		<< LLSDRPC_REQUEST_HEADER_2;
150	LLSDSerialize::toNotation(parameter, req);
151	req << LLSDRPC_REQUEST_FOOTER;
152	mRequest = req.str();
153	mQueue = queue;
154	mResponse = response;
155	return true;
156}
157
158bool LLSDRPCClient::call(
159	const std::string& uri,
160	const std::string& method,
161	const std::string& parameter,
162	LLSDRPCResponse* response,
163	EPassBackQueue queue)
164{
165	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
166	//llinfos << "RPC: " << uri << "." << method << "(" << parameter << ")"
167	//		<< llendl;
168	if(method.empty() || parameter.empty() || !response)
169	{
170		return false;
171	}
172	mState = STATE_READY;
173	mURI.assign(uri);
174	std::stringstream req;
175	req << LLSDRPC_REQUEST_HEADER_1 << method
176		<< LLSDRPC_REQUEST_HEADER_2 << parameter
177		<< LLSDRPC_REQUEST_FOOTER;
178	mRequest = req.str();
179	mQueue = queue;
180	mResponse = response;
181	return true;
182}
183
184static LLFastTimer::DeclareTimer FTM_PROCESS_SDRPC_CLIENT("SDRPC Client");
185
186// virtual
187LLIOPipe::EStatus LLSDRPCClient::process_impl(
188	const LLChannelDescriptors& channels,
189	buffer_ptr_t& buffer,
190	bool& eos,
191	LLSD& context,
192	LLPumpIO* pump)
193{
194	LLFastTimer t(FTM_PROCESS_SDRPC_CLIENT);
195	PUMP_DEBUG;
196	LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
197	if((STATE_NONE == mState) || (!pump))
198	{
199		// You should have called the call() method already.
200		return STATUS_PRECONDITION_NOT_MET;
201	}
202	EStatus rv = STATUS_DONE;
203	switch(mState)
204	{
205	case STATE_READY:
206	{
207		PUMP_DEBUG;
208//		lldebugs << "LLSDRPCClient::process_impl STATE_READY" << llendl;
209		buffer->append(
210			channels.out(),
211			(U8*)mRequest.c_str(),
212			mRequest.length());
213		context[CONTEXT_DEST_URI_SD_LABEL] = mURI;
214		mState = STATE_WAITING_FOR_RESPONSE;
215		break;
216	}
217	case STATE_WAITING_FOR_RESPONSE:
218	{
219		PUMP_DEBUG;
220		// The input channel has the sd response in it.
221		//lldebugs << "LLSDRPCClient::process_impl STATE_WAITING_FOR_RESPONSE"
222		//		 << llendl;
223		LLBufferStream resp(channels, buffer.get());
224		LLSD sd;
225		LLSDSerialize::fromNotation(sd, resp, buffer->count(channels.in()));
226		LLSDRPCResponse* response = (LLSDRPCResponse*)mResponse.get();
227		if (!response)
228		{
229			mState = STATE_DONE;
230			break;
231		}
232		response->extractResponse(sd);
233		if(EPBQ_PROCESS == mQueue)
234		{
235			LLPumpIO::chain_t chain;
236			chain.push_back(mResponse);
237			pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS);
238		}
239		else
240		{
241			pump->respond(mResponse.get());
242		}
243		mState = STATE_DONE;
244		break;
245	}
246	case STATE_DONE:
247	default:
248		PUMP_DEBUG;
249		llinfos << "invalid state to process" << llendl;
250		rv = STATUS_ERROR;
251		break;
252	}
253	return rv;
254}