diff options
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Scripting/XMLRPC')
-rw-r--r-- | OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs | 672 |
1 files changed, 672 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs new file mode 100644 index 0000000..1139b4b --- /dev/null +++ b/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs | |||
@@ -0,0 +1,672 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Net; | ||
32 | using System.Reflection; | ||
33 | using System.Threading; | ||
34 | using libsecondlife; | ||
35 | using log4net; | ||
36 | using Nini.Config; | ||
37 | using Nwc.XmlRpc; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Framework.Servers; | ||
40 | using OpenSim.Region.Environment.Interfaces; | ||
41 | using OpenSim.Region.Environment.Scenes; | ||
42 | |||
43 | /***************************************************** | ||
44 | * | ||
45 | * XMLRPCModule | ||
46 | * | ||
47 | * Module for accepting incoming communications from | ||
48 | * external XMLRPC client and calling a remote data | ||
49 | * procedure for a registered data channel/prim. | ||
50 | * | ||
51 | * | ||
52 | * 1. On module load, open a listener port | ||
53 | * 2. Attach an XMLRPC handler | ||
54 | * 3. When a request is received: | ||
55 | * 3.1 Parse into components: channel key, int, string | ||
56 | * 3.2 Look up registered channel listeners | ||
57 | * 3.3 Call the channel (prim) remote data method | ||
58 | * 3.4 Capture the response (llRemoteDataReply) | ||
59 | * 3.5 Return response to client caller | ||
60 | * 3.6 If no response from llRemoteDataReply within | ||
61 | * RemoteReplyScriptTimeout, generate script timeout fault | ||
62 | * | ||
63 | * Prims in script must: | ||
64 | * 1. Open a remote data channel | ||
65 | * 1.1 Generate a channel ID | ||
66 | * 1.2 Register primid,channelid pair with module | ||
67 | * 2. Implement the remote data procedure handler | ||
68 | * | ||
69 | * llOpenRemoteDataChannel | ||
70 | * llRemoteDataReply | ||
71 | * remote_data(integer type, key channel, key messageid, string sender, integer ival, string sval) | ||
72 | * llCloseRemoteDataChannel | ||
73 | * | ||
74 | * **************************************************/ | ||
75 | |||
76 | namespace OpenSim.Region.Environment.Modules.Scripting.XMLRPC | ||
77 | { | ||
78 | public class XMLRPCModule : IRegionModule, IXMLRPC | ||
79 | { | ||
80 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
81 | |||
82 | private object XMLRPCListLock = new object(); | ||
83 | private string m_name = "XMLRPCModule"; | ||
84 | private int RemoteReplyScriptWait = 300; | ||
85 | private int RemoteReplyScriptTimeout = 9000; | ||
86 | private int m_remoteDataPort = 0; | ||
87 | private List<Scene> m_scenes = new List<Scene>(); | ||
88 | |||
89 | // <channel id, RPCChannelInfo> | ||
90 | private Dictionary<LLUUID, RPCChannelInfo> m_openChannels; | ||
91 | |||
92 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending; | ||
93 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses; | ||
94 | |||
95 | private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses; | ||
96 | |||
97 | public void Initialise(Scene scene, IConfigSource config) | ||
98 | { | ||
99 | try | ||
100 | { | ||
101 | m_remoteDataPort = config.Configs["Network"].GetInt("remoteDataPort", m_remoteDataPort); | ||
102 | } | ||
103 | catch (Exception) | ||
104 | { | ||
105 | } | ||
106 | |||
107 | if (!m_scenes.Contains(scene)) | ||
108 | { | ||
109 | m_scenes.Add(scene); | ||
110 | |||
111 | scene.RegisterModuleInterface<IXMLRPC>(this); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | public void PostInitialise() | ||
116 | { | ||
117 | if (IsEnabled()) | ||
118 | { | ||
119 | m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>(); | ||
120 | m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>(); | ||
121 | m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>(); | ||
122 | m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>(); | ||
123 | |||
124 | // Start http server | ||
125 | // Attach xmlrpc handlers | ||
126 | m_log.Info("[REMOTE_DATA]: " + | ||
127 | "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); | ||
128 | BaseHttpServer httpServer = new BaseHttpServer((uint)m_remoteDataPort); | ||
129 | httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); | ||
130 | httpServer.Start(); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | public void Close() | ||
135 | { | ||
136 | } | ||
137 | |||
138 | public string Name | ||
139 | { | ||
140 | get { return m_name; } | ||
141 | } | ||
142 | |||
143 | public bool IsSharedModule | ||
144 | { | ||
145 | get { return true; } | ||
146 | } | ||
147 | |||
148 | public bool IsEnabled() | ||
149 | { | ||
150 | return (m_remoteDataPort > 0); | ||
151 | } | ||
152 | |||
153 | /********************************************** | ||
154 | * OpenXMLRPCChannel | ||
155 | * | ||
156 | * Generate a LLUUID channel key and add it and | ||
157 | * the prim id to dictionary <channelUUID, primUUID> | ||
158 | * | ||
159 | * First check if there is a channel assigned for | ||
160 | * this itemID. If there is, then someone called | ||
161 | * llOpenRemoteDataChannel twice. Just return the | ||
162 | * original channel. Other option is to delete the | ||
163 | * current channel and assign a new one. | ||
164 | * | ||
165 | * ********************************************/ | ||
166 | |||
167 | public LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID) | ||
168 | { | ||
169 | LLUUID channel = new LLUUID(); | ||
170 | |||
171 | //Is a dupe? | ||
172 | foreach (RPCChannelInfo ci in m_openChannels.Values) | ||
173 | { | ||
174 | if (ci.GetItemID().Equals(itemID)) | ||
175 | { | ||
176 | // return the original channel ID for this item | ||
177 | channel = ci.GetChannelID(); | ||
178 | break; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | if (channel == LLUUID.Zero) | ||
183 | { | ||
184 | channel = LLUUID.Random(); | ||
185 | RPCChannelInfo rpcChanInfo = new RPCChannelInfo(localID, itemID, channel); | ||
186 | lock (XMLRPCListLock) | ||
187 | { | ||
188 | m_openChannels.Add(channel, rpcChanInfo); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | return channel; | ||
193 | } | ||
194 | |||
195 | // Delete channels based on itemID | ||
196 | // for when a script is deleted | ||
197 | public void DeleteChannels(LLUUID itemID) | ||
198 | { | ||
199 | |||
200 | if (m_openChannels != null) | ||
201 | { | ||
202 | ArrayList tmp = new ArrayList(); | ||
203 | |||
204 | lock (XMLRPCListLock) | ||
205 | { | ||
206 | foreach (RPCChannelInfo li in m_openChannels.Values) | ||
207 | { | ||
208 | if (li.GetItemID().Equals(itemID)) | ||
209 | { | ||
210 | tmp.Add(itemID); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | IEnumerator tmpEnumerator = tmp.GetEnumerator(); | ||
215 | while ( tmpEnumerator.MoveNext() ) | ||
216 | m_openChannels.Remove((LLUUID)tmpEnumerator.Current); | ||
217 | } | ||
218 | |||
219 | } | ||
220 | |||
221 | } | ||
222 | |||
223 | /********************************************** | ||
224 | * Remote Data Reply | ||
225 | * | ||
226 | * Response to RPC message | ||
227 | * | ||
228 | *********************************************/ | ||
229 | |||
230 | public void RemoteDataReply(string channel, string message_id, string sdata, int idata) | ||
231 | { | ||
232 | RPCRequestInfo rpcInfo; | ||
233 | LLUUID message_key = new LLUUID(message_id); | ||
234 | |||
235 | if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo)) | ||
236 | { | ||
237 | rpcInfo.SetStrRetval(sdata); | ||
238 | rpcInfo.SetIntRetval(idata); | ||
239 | rpcInfo.SetProcessed(true); | ||
240 | m_rpcPendingResponses.Remove(message_key); | ||
241 | } | ||
242 | } | ||
243 | |||
244 | /********************************************** | ||
245 | * CloseXMLRPCChannel | ||
246 | * | ||
247 | * Remove channel from dictionary | ||
248 | * | ||
249 | *********************************************/ | ||
250 | |||
251 | public void CloseXMLRPCChannel(LLUUID channelKey) | ||
252 | { | ||
253 | if (m_openChannels.ContainsKey(channelKey)) | ||
254 | m_openChannels.Remove(channelKey); | ||
255 | } | ||
256 | |||
257 | |||
258 | public XmlRpcResponse XmlRpcRemoteData(XmlRpcRequest request) | ||
259 | { | ||
260 | XmlRpcResponse response = new XmlRpcResponse(); | ||
261 | |||
262 | Hashtable requestData = (Hashtable)request.Params[0]; | ||
263 | bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") && | ||
264 | requestData.Contains("StringValue")); | ||
265 | |||
266 | if (GoodXML) | ||
267 | { | ||
268 | LLUUID channel = new LLUUID((string)requestData["Channel"]); | ||
269 | RPCChannelInfo rpcChanInfo; | ||
270 | if (m_openChannels.TryGetValue(channel, out rpcChanInfo)) | ||
271 | { | ||
272 | string intVal = (string)requestData["IntValue"]; | ||
273 | string strVal = (string)requestData["StringValue"]; | ||
274 | |||
275 | RPCRequestInfo rpcInfo; | ||
276 | |||
277 | lock (XMLRPCListLock) | ||
278 | { | ||
279 | rpcInfo = | ||
280 | new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, | ||
281 | intVal); | ||
282 | m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo); | ||
283 | } | ||
284 | |||
285 | int timeoutCtr = 0; | ||
286 | |||
287 | while (!rpcInfo.IsProcessed() && (timeoutCtr < RemoteReplyScriptTimeout)) | ||
288 | { | ||
289 | Thread.Sleep(RemoteReplyScriptWait); | ||
290 | timeoutCtr += RemoteReplyScriptWait; | ||
291 | } | ||
292 | if (rpcInfo.IsProcessed()) | ||
293 | { | ||
294 | Hashtable param = new Hashtable(); | ||
295 | param["StringValue"] = rpcInfo.GetStrRetval(); | ||
296 | param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval()); | ||
297 | |||
298 | ArrayList parameters = new ArrayList(); | ||
299 | parameters.Add(param); | ||
300 | |||
301 | response.Value = parameters; | ||
302 | rpcInfo = null; | ||
303 | } | ||
304 | else | ||
305 | { | ||
306 | response.SetFault(-1, "Script timeout"); | ||
307 | rpcInfo = null; | ||
308 | } | ||
309 | } | ||
310 | else | ||
311 | { | ||
312 | response.SetFault(-1, "Invalid channel"); | ||
313 | } | ||
314 | } | ||
315 | |||
316 | return response; | ||
317 | } | ||
318 | |||
319 | public bool hasRequests() | ||
320 | { | ||
321 | lock (XMLRPCListLock) | ||
322 | { | ||
323 | if (m_rpcPending != null) | ||
324 | return (m_rpcPending.Count > 0); | ||
325 | else | ||
326 | return false; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | public RPCRequestInfo GetNextCompletedRequest() | ||
331 | { | ||
332 | if (m_rpcPending != null) | ||
333 | { | ||
334 | lock (XMLRPCListLock) | ||
335 | { | ||
336 | foreach (LLUUID luid in m_rpcPending.Keys) | ||
337 | { | ||
338 | RPCRequestInfo tmpReq; | ||
339 | |||
340 | if (m_rpcPending.TryGetValue(luid, out tmpReq)) | ||
341 | { | ||
342 | |||
343 | if (!tmpReq.IsProcessed()) return tmpReq; | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | return null; | ||
349 | } | ||
350 | |||
351 | public void RemoveCompletedRequest(LLUUID id) | ||
352 | { | ||
353 | lock (XMLRPCListLock) | ||
354 | { | ||
355 | RPCRequestInfo tmp; | ||
356 | if (m_rpcPending.TryGetValue(id, out tmp)) | ||
357 | { | ||
358 | m_rpcPending.Remove(id); | ||
359 | m_rpcPendingResponses.Add(id, tmp); | ||
360 | } | ||
361 | else | ||
362 | { | ||
363 | Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST"); | ||
364 | } | ||
365 | } | ||
366 | } | ||
367 | |||
368 | public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) | ||
369 | { | ||
370 | |||
371 | SendRemoteDataRequest req = new SendRemoteDataRequest( | ||
372 | localID, itemID, channel, dest, idata, sdata | ||
373 | ); | ||
374 | m_pendingSRDResponses.Add(req.GetReqID(), req); | ||
375 | return req.process(); | ||
376 | |||
377 | } | ||
378 | |||
379 | public SendRemoteDataRequest GetNextCompletedSRDRequest() | ||
380 | { | ||
381 | if (m_pendingSRDResponses != null) | ||
382 | { | ||
383 | lock (XMLRPCListLock) | ||
384 | { | ||
385 | foreach (LLUUID luid in m_pendingSRDResponses.Keys) | ||
386 | { | ||
387 | SendRemoteDataRequest tmpReq; | ||
388 | |||
389 | if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq)) | ||
390 | { | ||
391 | if (tmpReq.finished) | ||
392 | return tmpReq; | ||
393 | } | ||
394 | } | ||
395 | } | ||
396 | } | ||
397 | return null; | ||
398 | } | ||
399 | |||
400 | public void RemoveCompletedSRDRequest(LLUUID id) | ||
401 | { | ||
402 | lock (XMLRPCListLock) | ||
403 | { | ||
404 | SendRemoteDataRequest tmpReq; | ||
405 | if (m_pendingSRDResponses.TryGetValue(id, out tmpReq)) | ||
406 | { | ||
407 | m_pendingSRDResponses.Remove(id); | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | |||
412 | public void CancelSRDRequests(LLUUID itemID) | ||
413 | { | ||
414 | if (m_pendingSRDResponses != null) | ||
415 | { | ||
416 | lock (XMLRPCListLock) | ||
417 | { | ||
418 | foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values) | ||
419 | { | ||
420 | if (li.m_itemID.Equals(itemID)) | ||
421 | m_pendingSRDResponses.Remove(li.GetReqID()); | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | } | ||
427 | |||
428 | public class RPCRequestInfo | ||
429 | { | ||
430 | private string m_StrVal; | ||
431 | private string m_IntVal; | ||
432 | private bool m_processed; | ||
433 | private string m_respStr; | ||
434 | private int m_respInt; | ||
435 | private uint m_localID; | ||
436 | private LLUUID m_ItemID; | ||
437 | private LLUUID m_MessageID; | ||
438 | private LLUUID m_ChannelKey; | ||
439 | |||
440 | public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal) | ||
441 | { | ||
442 | m_localID = localID; | ||
443 | m_StrVal = strVal; | ||
444 | m_IntVal = intVal; | ||
445 | m_ItemID = itemID; | ||
446 | m_ChannelKey = channelKey; | ||
447 | m_MessageID = LLUUID.Random(); | ||
448 | m_processed = false; | ||
449 | m_respStr = String.Empty; | ||
450 | m_respInt = 0; | ||
451 | } | ||
452 | |||
453 | public bool IsProcessed() | ||
454 | { | ||
455 | return m_processed; | ||
456 | } | ||
457 | |||
458 | public LLUUID GetChannelKey() | ||
459 | { | ||
460 | return m_ChannelKey; | ||
461 | } | ||
462 | |||
463 | public void SetProcessed(bool processed) | ||
464 | { | ||
465 | m_processed = processed; | ||
466 | } | ||
467 | |||
468 | public void SetStrRetval(string resp) | ||
469 | { | ||
470 | m_respStr = resp; | ||
471 | } | ||
472 | |||
473 | public string GetStrRetval() | ||
474 | { | ||
475 | return m_respStr; | ||
476 | } | ||
477 | public void SetIntRetval(int resp) | ||
478 | { | ||
479 | m_respInt = resp; | ||
480 | } | ||
481 | |||
482 | public int GetIntRetval() | ||
483 | { | ||
484 | return m_respInt; | ||
485 | } | ||
486 | public uint GetLocalID() | ||
487 | { | ||
488 | return m_localID; | ||
489 | } | ||
490 | |||
491 | public LLUUID GetItemID() | ||
492 | { | ||
493 | return m_ItemID; | ||
494 | } | ||
495 | |||
496 | public string GetStrVal() | ||
497 | { | ||
498 | return m_StrVal; | ||
499 | } | ||
500 | |||
501 | public int GetIntValue() | ||
502 | { | ||
503 | return int.Parse(m_IntVal); | ||
504 | } | ||
505 | |||
506 | public LLUUID GetMessageID() | ||
507 | { | ||
508 | return m_MessageID; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | public class RPCChannelInfo | ||
513 | { | ||
514 | private LLUUID m_itemID; | ||
515 | private uint m_localID; | ||
516 | private LLUUID m_ChannelKey; | ||
517 | |||
518 | public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID) | ||
519 | { | ||
520 | m_ChannelKey = channelID; | ||
521 | m_localID = localID; | ||
522 | m_itemID = itemID; | ||
523 | } | ||
524 | |||
525 | public LLUUID GetItemID() | ||
526 | { | ||
527 | return m_itemID; | ||
528 | } | ||
529 | |||
530 | public LLUUID GetChannelID() | ||
531 | { | ||
532 | return m_ChannelKey; | ||
533 | } | ||
534 | |||
535 | public uint GetLocalID() | ||
536 | { | ||
537 | return m_localID; | ||
538 | } | ||
539 | |||
540 | } | ||
541 | |||
542 | public class SendRemoteDataRequest | ||
543 | { | ||
544 | |||
545 | public LLUUID reqID; | ||
546 | public string destURL; | ||
547 | public string channel; | ||
548 | public string sdata; | ||
549 | public int idata; | ||
550 | public bool finished; | ||
551 | public string response_sdata; | ||
552 | public int response_idata; | ||
553 | public XmlRpcRequest request; | ||
554 | private Thread httpThread; | ||
555 | public LLUUID m_itemID; | ||
556 | public uint m_localID; | ||
557 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
558 | |||
559 | public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) | ||
560 | { | ||
561 | |||
562 | this.channel = channel; | ||
563 | this.destURL = dest; | ||
564 | this.idata = idata; | ||
565 | this.sdata = sdata; | ||
566 | m_itemID = itemID; | ||
567 | m_localID = localID; | ||
568 | |||
569 | reqID = LLUUID.Random(); | ||
570 | |||
571 | } | ||
572 | |||
573 | public LLUUID process() | ||
574 | { | ||
575 | httpThread = new Thread(SendRequest); | ||
576 | httpThread.Name = "HttpRequestThread"; | ||
577 | httpThread.Priority = ThreadPriority.BelowNormal; | ||
578 | httpThread.IsBackground = true; | ||
579 | finished = false; | ||
580 | httpThread.Start(); | ||
581 | ThreadTracker.Add(httpThread); | ||
582 | |||
583 | return reqID; | ||
584 | |||
585 | } | ||
586 | |||
587 | /* | ||
588 | * TODO: More work on the response codes. Right now | ||
589 | * returning 200 for success or 499 for exception | ||
590 | */ | ||
591 | |||
592 | public void SendRequest() | ||
593 | { | ||
594 | Hashtable param = new Hashtable(); | ||
595 | |||
596 | // Check if channel is an LLUUID | ||
597 | // if not, use as method name | ||
598 | LLUUID parseUID; | ||
599 | string mName = "llRemoteData"; | ||
600 | if( (channel != null) && (channel != "") ) | ||
601 | if( !LLUUID.TryParse(channel, out parseUID) ) | ||
602 | mName = channel; | ||
603 | else | ||
604 | param["Channel"] = channel; | ||
605 | |||
606 | param["StringValue"] = sdata; | ||
607 | param["IntValue"] = Convert.ToString(idata); | ||
608 | |||
609 | ArrayList parameters = new ArrayList(); | ||
610 | parameters.Add(param); | ||
611 | XmlRpcRequest req = new XmlRpcRequest(mName, parameters); | ||
612 | try | ||
613 | { | ||
614 | XmlRpcResponse resp = req.Send(destURL, 30000); | ||
615 | if (resp != null) | ||
616 | { | ||
617 | Hashtable respParms; | ||
618 | if(resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) { | ||
619 | respParms = (Hashtable)resp.Value; | ||
620 | } | ||
621 | else { | ||
622 | ArrayList respData = (ArrayList)resp.Value; | ||
623 | respParms = (Hashtable)respData[0]; | ||
624 | } | ||
625 | if (respParms != null) | ||
626 | { | ||
627 | if (respParms.Contains("StringValue")) | ||
628 | { | ||
629 | sdata = (string)respParms["StringValue"]; | ||
630 | } | ||
631 | if (respParms.Contains("IntValue")) | ||
632 | { | ||
633 | idata = Convert.ToInt32((string)respParms["IntValue"]); | ||
634 | } | ||
635 | if (respParms.Contains("faultString")) | ||
636 | { | ||
637 | sdata = (string)respParms["faultString"]; | ||
638 | } | ||
639 | if (respParms.Contains("faultCode")) | ||
640 | { | ||
641 | idata = Convert.ToInt32(respParms["faultCode"]); | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | } | ||
646 | catch (WebException we) | ||
647 | { | ||
648 | sdata = we.Message; | ||
649 | m_log.Warn("[SendRemoteDataRequest]: Request failed"); | ||
650 | m_log.Warn(we.StackTrace); | ||
651 | } | ||
652 | |||
653 | finished = true; | ||
654 | } | ||
655 | |||
656 | public void Stop() | ||
657 | { | ||
658 | try | ||
659 | { | ||
660 | httpThread.Abort(); | ||
661 | } | ||
662 | catch (Exception) | ||
663 | { | ||
664 | } | ||
665 | } | ||
666 | |||
667 | public LLUUID GetReqID() | ||
668 | { | ||
669 | return reqID; | ||
670 | } | ||
671 | } | ||
672 | } \ No newline at end of file | ||