aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs152
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs138
2 files changed, 230 insertions, 60 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 2359bd6..b77ead3 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -27,12 +27,15 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
32using System.Threading;
31using log4net; 33using log4net;
32using Nini.Config; 34using Nini.Config;
33using Mono.Addins; 35using Mono.Addins;
34using OpenMetaverse; 36using OpenMetaverse;
35using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Servers;
36using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
@@ -48,67 +51,49 @@ namespace OpenSim.Region.ClientStack.Linden
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class WebFetchInvDescModule : INonSharedRegionModule 52 public class WebFetchInvDescModule : INonSharedRegionModule
50 { 53 {
51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 55
53 private Scene m_scene; 56 private Scene m_scene;
54 57
55 private IInventoryService m_InventoryService; 58 private IInventoryService m_InventoryService;
56 private ILibraryService m_LibraryService; 59 private ILibraryService m_LibraryService;
57 60
58 private bool m_Enabled; 61 private WebFetchInvDescHandler m_webFetchHandler;
59 62
60 private string m_fetchInventoryDescendents2Url; 63 private ManualResetEvent m_ev = new ManualResetEvent(true);
61 private string m_webFetchInventoryDescendentsUrl; 64 private object m_lock = new object();
62 65
63 private WebFetchInvDescHandler m_webFetchHandler; 66 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
67 private Dictionary<UUID, Hashtable> m_requests = new Dictionary<UUID, Hashtable>();
64 68
65 #region ISharedRegionModule Members 69 #region ISharedRegionModule Members
66 70
67 public void Initialise(IConfigSource source) 71 public void Initialise(IConfigSource source)
68 { 72 {
69 IConfig config = source.Configs["ClientStack.LindenCaps"];
70 if (config == null)
71 return;
72
73 m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty);
74 m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
75
76 if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty)
77 {
78 m_Enabled = true;
79 }
80 } 73 }
81 74
82 public void AddRegion(Scene s) 75 public void AddRegion(Scene s)
83 { 76 {
84 if (!m_Enabled)
85 return;
86
87 m_scene = s; 77 m_scene = s;
88 } 78 }
89 79
90 public void RemoveRegion(Scene s) 80 public void RemoveRegion(Scene s)
91 { 81 {
92 if (!m_Enabled)
93 return;
94
95 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 82 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
83 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
96 m_scene = null; 84 m_scene = null;
97 } 85 }
98 86
99 public void RegionLoaded(Scene s) 87 public void RegionLoaded(Scene s)
100 { 88 {
101 if (!m_Enabled)
102 return;
103
104 m_InventoryService = m_scene.InventoryService; 89 m_InventoryService = m_scene.InventoryService;
105 m_LibraryService = m_scene.LibraryService; 90 m_LibraryService = m_scene.LibraryService;
106 91
107 // We'll reuse the same handler for all requests. 92 // We'll reuse the same handler for all requests.
108 if (m_fetchInventoryDescendents2Url == "localhost" || m_webFetchInventoryDescendentsUrl == "localhost") 93 m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
109 m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
110 94
111 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 95 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
96 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
112 } 97 }
113 98
114 public void PostInitialise() 99 public void PostInitialise()
@@ -128,41 +113,110 @@ namespace OpenSim.Region.ClientStack.Linden
128 113
129 private void RegisterCaps(UUID agentID, Caps caps) 114 private void RegisterCaps(UUID agentID, Caps caps)
130 { 115 {
131 if (m_webFetchInventoryDescendentsUrl != "") 116 string capUrl = "/CAPS/" + UUID.Random() + "/";
132 RegisterFetchCap(agentID, caps, "WebFetchInventoryDescendents", m_webFetchInventoryDescendentsUrl); 117
118 // Register this as a poll service
119 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, agentID, 300000);
120 args.Type = PollServiceEventArgs.EventType.Inventory;
121 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
122
123 string hostName = m_scene.RegionInfo.ExternalHostName;
124 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
125 string protocol = "http";
126
127 if (MainServer.Instance.UseSSL)
128 {
129 hostName = MainServer.Instance.SSLCommonName;
130 port = MainServer.Instance.SSLPort;
131 protocol = "https";
132 }
133 caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
133 134
134 if (m_fetchInventoryDescendents2Url != "") 135 m_capsDict[agentID] = capUrl;
135 RegisterFetchCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
136 } 136 }
137 137
138 private void RegisterFetchCap(UUID agentID, Caps caps, string capName, string url) 138 private void DeregisterCaps(UUID agentID, Caps caps)
139 { 139 {
140 string capUrl; 140 string capUrl;
141 141
142 if (url == "localhost") 142 if (m_capsDict.TryGetValue(agentID, out capUrl))
143 { 143 {
144 capUrl = "/CAPS/" + UUID.Random(); 144 MainServer.Instance.RemoveHTTPHandler("", capUrl);
145 m_capsDict.Remove(agentID);
146 }
147 }
145 148
146 IRequestHandler reqHandler 149 public void HttpRequestHandler(UUID requestID, Hashtable request)
147 = new RestStreamHandler( 150 {
148 "POST", 151// m_log.DebugFormat("[FETCH2]: Received request {0}", requestID);
149 capUrl, 152 m_requests[requestID] = request;
150 m_webFetchHandler.FetchInventoryDescendentsRequest, 153 }
151 "FetchInventoryDescendents2",
152 agentID.ToString());
153 154
154 caps.RegisterHandler(capName, reqHandler); 155 private bool HasEvents(UUID requestID, UUID sessionID)
156 {
157 lock (m_lock)
158 {
159 if (m_ev.WaitOne(0))
160 {
161 m_ev.Reset();
162 return true;
163 }
164 return false;
155 } 165 }
156 else 166 }
167
168 private Hashtable NoEvents(UUID requestID, UUID sessionID)
169 {
170 m_requests.Remove(requestID);
171
172 Hashtable response = new Hashtable();
173
174 response["int_response_code"] = 500;
175 response["str_response_string"] = "Script timeout";
176 response["content_type"] = "text/plain";
177 response["keepalive"] = false;
178 response["reusecontext"] = false;
179
180 return response;
181 }
182
183 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
184 {
185 Hashtable response = new Hashtable();
186
187 response["int_response_code"] = 500;
188 response["str_response_string"] = "Internal error";
189 response["content_type"] = "text/plain";
190 response["keepalive"] = false;
191 response["reusecontext"] = false;
192
193 try
157 { 194 {
158 capUrl = url; 195 Hashtable requestHash;
196 if (!m_requests.TryGetValue(requestID, out requestHash))
197 {
198 lock (m_lock)
199 m_ev.Set();
200 response["str_response_string"] = "Invalid request";
201 return response;
202 }
203
204// m_log.DebugFormat("[FETCH2]: Processed request {0}", requestID);
159 205
160 caps.RegisterHandler(capName, capUrl); 206 string reply = m_webFetchHandler.FetchInventoryDescendentsRequest(requestHash["body"].ToString(), String.Empty, String.Empty, null, null);
207
208 m_requests.Remove(requestID);
209
210 response["int_response_code"] = 200;
211 response["str_response_string"] = reply;
212 }
213 finally
214 {
215 lock (m_lock)
216 m_ev.Set();
161 } 217 }
162 218
163// m_log.DebugFormat( 219 return response;
164// "[WEB FETCH INV DESC MODULE]: Registered capability {0} at {1} in region {2} for {3}",
165// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
166 } 220 }
167 } 221 }
168} \ No newline at end of file 222}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index fb73e1d..60ab70e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -110,7 +110,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
110 /// <summary>Handlers for incoming packets</summary> 110 /// <summary>Handlers for incoming packets</summary>
111 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 111 //PacketEventDictionary packetEvents = new PacketEventDictionary();
112 /// <summary>Incoming packets that are awaiting handling</summary> 112 /// <summary>Incoming packets that are awaiting handling</summary>
113 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 113 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
114
115 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
116
114 /// <summary></summary> 117 /// <summary></summary>
115 //private UDPClientCollection m_clients = new UDPClientCollection(); 118 //private UDPClientCollection m_clients = new UDPClientCollection();
116 /// <summary>Bandwidth throttle for this UDP server</summary> 119 /// <summary>Bandwidth throttle for this UDP server</summary>
@@ -919,7 +922,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
919 #endregion Ping Check Handling 922 #endregion Ping Check Handling
920 923
921 // Inbox insertion 924 // Inbox insertion
922 packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet)); 925 if (packet.Type == PacketType.AgentUpdate ||
926 packet.Type == PacketType.ChatFromViewer)
927 packetInbox.EnqueueHigh(new IncomingPacket((LLClientView)client, packet));
928 else
929 packetInbox.EnqueueLow(new IncomingPacket((LLClientView)client, packet));
930// packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
923 } 931 }
924 932
925 #region BinaryStats 933 #region BinaryStats
@@ -1471,8 +1479,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1471 Packet packet = incomingPacket.Packet; 1479 Packet packet = incomingPacket.Packet;
1472 LLClientView client = incomingPacket.Client; 1480 LLClientView client = incomingPacket.Client;
1473 1481
1474 if (client.IsActive) 1482// if (client.IsActive)
1475 { 1483// {
1476 m_currentIncomingClient = client; 1484 m_currentIncomingClient = client;
1477 1485
1478 try 1486 try
@@ -1499,13 +1507,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1499 { 1507 {
1500 m_currentIncomingClient = null; 1508 m_currentIncomingClient = null;
1501 } 1509 }
1502 } 1510// }
1503 else 1511// else
1504 { 1512// {
1505 m_log.DebugFormat( 1513// m_log.DebugFormat(
1506 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1514// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1507 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1515// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1508 } 1516// }
1509 } 1517 }
1510 1518
1511 protected void LogoutHandler(IClientAPI client) 1519 protected void LogoutHandler(IClientAPI client)
@@ -1519,4 +1527,112 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1519 } 1527 }
1520 } 1528 }
1521 } 1529 }
1530
1531 internal class DoubleQueue<T> where T:class
1532 {
1533 private Queue<T> m_lowQueue = new Queue<T>();
1534 private Queue<T> m_highQueue = new Queue<T>();
1535
1536 private object m_syncRoot = new object();
1537 private Semaphore m_s = new Semaphore(0, 1);
1538
1539 public DoubleQueue()
1540 {
1541 }
1542
1543 public virtual int Count
1544 {
1545 get { return m_highQueue.Count + m_lowQueue.Count; }
1546 }
1547
1548 public virtual void Enqueue(T data)
1549 {
1550 Enqueue(m_lowQueue, data);
1551 }
1552
1553 public virtual void EnqueueLow(T data)
1554 {
1555 Enqueue(m_lowQueue, data);
1556 }
1557
1558 public virtual void EnqueueHigh(T data)
1559 {
1560 Enqueue(m_highQueue, data);
1561 }
1562
1563 private void Enqueue(Queue<T> q, T data)
1564 {
1565 lock (m_syncRoot)
1566 {
1567 m_lowQueue.Enqueue(data);
1568 m_s.WaitOne(0);
1569 m_s.Release();
1570 }
1571 }
1572
1573 public virtual T Dequeue()
1574 {
1575 return Dequeue(Timeout.Infinite);
1576 }
1577
1578 public virtual T Dequeue(int tmo)
1579 {
1580 return Dequeue(TimeSpan.FromMilliseconds(tmo));
1581 }
1582
1583 public virtual T Dequeue(TimeSpan wait)
1584 {
1585 T res = null;
1586
1587 if (!Dequeue(wait, ref res))
1588 return null;
1589
1590 return res;
1591 }
1592
1593 public bool Dequeue(int timeout, ref T res)
1594 {
1595 return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
1596 }
1597
1598 public bool Dequeue(TimeSpan wait, ref T res)
1599 {
1600 if (!m_s.WaitOne(wait))
1601 return false;
1602
1603 lock (m_syncRoot)
1604 {
1605 if (m_highQueue.Count > 0)
1606 res = m_highQueue.Dequeue();
1607 else
1608 res = m_lowQueue.Dequeue();
1609
1610 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
1611 return true;
1612
1613 try
1614 {
1615 m_s.Release();
1616 }
1617 catch
1618 {
1619 }
1620
1621 return true;
1622 }
1623 }
1624
1625 public virtual void Clear()
1626 {
1627
1628 lock (m_syncRoot)
1629 {
1630 // Make sure sem count is 0
1631 m_s.WaitOne(0);
1632
1633 m_lowQueue.Clear();
1634 m_highQueue.Clear();
1635 }
1636 }
1637 }
1522} 1638}