diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Server/Handlers/Simulation/AgentHandlers.cs | 299 |
1 files changed, 187 insertions, 112 deletions
diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 8b6fb4f..d52750b 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.IO.Compression; | ||
31 | using System.Reflection; | 32 | using System.Reflection; |
32 | using System.Net; | 33 | using System.Net; |
33 | using System.Text; | 34 | using System.Text; |
@@ -53,8 +54,6 @@ namespace OpenSim.Server.Handlers.Simulation | |||
53 | 54 | ||
54 | private ISimulationService m_SimulationService; | 55 | private ISimulationService m_SimulationService; |
55 | 56 | ||
56 | protected bool m_Proxy = false; | ||
57 | |||
58 | public AgentHandler() { } | 57 | public AgentHandler() { } |
59 | 58 | ||
60 | public AgentHandler(ISimulationService sim) | 59 | public AgentHandler(ISimulationService sim) |
@@ -91,16 +90,12 @@ namespace OpenSim.Server.Handlers.Simulation | |||
91 | 90 | ||
92 | // Next, let's parse the verb | 91 | // Next, let's parse the verb |
93 | string method = (string)request["http-method"]; | 92 | string method = (string)request["http-method"]; |
93 | m_log.DebugFormat("[SIMULATION]: Got verb {0} in HTTP handler", method); | ||
94 | if (method.Equals("PUT")) | 94 | if (method.Equals("PUT")) |
95 | { | 95 | { |
96 | DoAgentPut(request, responsedata); | 96 | DoAgentPut(request, responsedata); |
97 | return responsedata; | 97 | return responsedata; |
98 | } | 98 | } |
99 | else if (method.Equals("POST")) | ||
100 | { | ||
101 | DoAgentPost(request, responsedata, agentID); | ||
102 | return responsedata; | ||
103 | } | ||
104 | else if (method.Equals("GET")) | 99 | else if (method.Equals("GET")) |
105 | { | 100 | { |
106 | DoAgentGet(request, responsedata, agentID, regionID); | 101 | DoAgentGet(request, responsedata, agentID, regionID); |
@@ -127,111 +122,6 @@ namespace OpenSim.Server.Handlers.Simulation | |||
127 | 122 | ||
128 | } | 123 | } |
129 | 124 | ||
130 | protected void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) | ||
131 | { | ||
132 | OSDMap args = Utils.GetOSDMap((string)request["body"]); | ||
133 | if (args == null) | ||
134 | { | ||
135 | responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||
136 | responsedata["str_response_string"] = "Bad request"; | ||
137 | return; | ||
138 | } | ||
139 | |||
140 | // retrieve the input arguments | ||
141 | int x = 0, y = 0; | ||
142 | UUID uuid = UUID.Zero; | ||
143 | string regionname = string.Empty; | ||
144 | uint teleportFlags = 0; | ||
145 | if (args.ContainsKey("destination_x") && args["destination_x"] != null) | ||
146 | Int32.TryParse(args["destination_x"].AsString(), out x); | ||
147 | else | ||
148 | m_log.WarnFormat(" -- request didn't have destination_x"); | ||
149 | if (args.ContainsKey("destination_y") && args["destination_y"] != null) | ||
150 | Int32.TryParse(args["destination_y"].AsString(), out y); | ||
151 | else | ||
152 | m_log.WarnFormat(" -- request didn't have destination_y"); | ||
153 | if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) | ||
154 | UUID.TryParse(args["destination_uuid"].AsString(), out uuid); | ||
155 | if (args.ContainsKey("destination_name") && args["destination_name"] != null) | ||
156 | regionname = args["destination_name"].ToString(); | ||
157 | if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null) | ||
158 | teleportFlags = args["teleport_flags"].AsUInteger(); | ||
159 | |||
160 | GridRegion destination = new GridRegion(); | ||
161 | destination.RegionID = uuid; | ||
162 | destination.RegionLocX = x; | ||
163 | destination.RegionLocY = y; | ||
164 | destination.RegionName = regionname; | ||
165 | |||
166 | AgentCircuitData aCircuit = new AgentCircuitData(); | ||
167 | try | ||
168 | { | ||
169 | aCircuit.UnpackAgentCircuitData(args); | ||
170 | } | ||
171 | catch (Exception ex) | ||
172 | { | ||
173 | m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildCreate message {0}", ex.Message); | ||
174 | responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||
175 | responsedata["str_response_string"] = "Bad request"; | ||
176 | return; | ||
177 | } | ||
178 | |||
179 | OSDMap resp = new OSDMap(2); | ||
180 | string reason = String.Empty; | ||
181 | |||
182 | // This is the meaning of POST agent | ||
183 | //m_regionClient.AdjustUserInformation(aCircuit); | ||
184 | //bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||
185 | bool result = CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||
186 | |||
187 | resp["reason"] = OSD.FromString(reason); | ||
188 | resp["success"] = OSD.FromBoolean(result); | ||
189 | // Let's also send out the IP address of the caller back to the caller (HG 1.5) | ||
190 | resp["your_ip"] = OSD.FromString(GetCallerIP(request)); | ||
191 | |||
192 | // TODO: add reason if not String.Empty? | ||
193 | responsedata["int_response_code"] = HttpStatusCode.OK; | ||
194 | responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); | ||
195 | } | ||
196 | |||
197 | private string GetCallerIP(Hashtable request) | ||
198 | { | ||
199 | if (!m_Proxy) | ||
200 | return Util.GetCallerIP(request); | ||
201 | |||
202 | // We're behind a proxy | ||
203 | Hashtable headers = (Hashtable)request["headers"]; | ||
204 | |||
205 | //// DEBUG | ||
206 | //foreach (object o in headers.Keys) | ||
207 | // m_log.DebugFormat("XXX {0} = {1}", o.ToString(), (headers[o] == null? "null" : headers[o].ToString())); | ||
208 | |||
209 | string xff = "X-Forwarded-For"; | ||
210 | if (headers.ContainsKey(xff.ToLower())) | ||
211 | xff = xff.ToLower(); | ||
212 | |||
213 | if (!headers.ContainsKey(xff) || headers[xff] == null) | ||
214 | { | ||
215 | m_log.WarnFormat("[AGENT HANDLER]: No XFF header"); | ||
216 | return Util.GetCallerIP(request); | ||
217 | } | ||
218 | |||
219 | m_log.DebugFormat("[AGENT HANDLER]: XFF is {0}", headers[xff]); | ||
220 | |||
221 | IPEndPoint ep = Util.GetClientIPFromXFF((string)headers[xff]); | ||
222 | if (ep != null) | ||
223 | return ep.Address.ToString(); | ||
224 | |||
225 | // Oops | ||
226 | return Util.GetCallerIP(request); | ||
227 | } | ||
228 | |||
229 | // subclasses can override this | ||
230 | protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason) | ||
231 | { | ||
232 | return m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||
233 | } | ||
234 | |||
235 | protected void DoAgentPut(Hashtable request, Hashtable responsedata) | 125 | protected void DoAgentPut(Hashtable request, Hashtable responsedata) |
236 | { | 126 | { |
237 | OSDMap args = Utils.GetOSDMap((string)request["body"]); | 127 | OSDMap args = Utils.GetOSDMap((string)request["body"]); |
@@ -434,4 +324,189 @@ namespace OpenSim.Server.Handlers.Simulation | |||
434 | 324 | ||
435 | } | 325 | } |
436 | 326 | ||
327 | public class AgentPostHandler : BaseStreamHandler | ||
328 | { | ||
329 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
330 | |||
331 | private ISimulationService m_SimulationService; | ||
332 | protected bool m_Proxy = false; | ||
333 | |||
334 | public AgentPostHandler(ISimulationService service) : | ||
335 | base("POST", "/agent") | ||
336 | { | ||
337 | m_SimulationService = service; | ||
338 | } | ||
339 | |||
340 | public AgentPostHandler(string path) : | ||
341 | base("POST", path) | ||
342 | { | ||
343 | m_SimulationService = null; | ||
344 | } | ||
345 | |||
346 | public override byte[] Handle(string path, Stream request, | ||
347 | OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||
348 | { | ||
349 | m_log.DebugFormat("[SIMULATION]: Stream handler called"); | ||
350 | |||
351 | Hashtable keysvals = new Hashtable(); | ||
352 | Hashtable headervals = new Hashtable(); | ||
353 | |||
354 | string[] querystringkeys = httpRequest.QueryString.AllKeys; | ||
355 | string[] rHeaders = httpRequest.Headers.AllKeys; | ||
356 | |||
357 | keysvals.Add("uri", httpRequest.RawUrl); | ||
358 | keysvals.Add("content-type", httpRequest.ContentType); | ||
359 | keysvals.Add("http-method", httpRequest.HttpMethod); | ||
360 | |||
361 | foreach (string queryname in querystringkeys) | ||
362 | keysvals.Add(queryname, httpRequest.QueryString[queryname]); | ||
363 | |||
364 | foreach (string headername in rHeaders) | ||
365 | headervals[headername] = httpRequest.Headers[headername]; | ||
366 | |||
367 | keysvals.Add("headers", headervals); | ||
368 | keysvals.Add("querystringkeys", querystringkeys); | ||
369 | |||
370 | Stream inputStream; | ||
371 | if (httpRequest.ContentType == "application/x-gzip") | ||
372 | inputStream = new GZipStream(request, CompressionMode.Decompress); | ||
373 | else | ||
374 | inputStream = request; | ||
375 | |||
376 | Encoding encoding = Encoding.UTF8; | ||
377 | StreamReader reader = new StreamReader(inputStream, encoding); | ||
378 | |||
379 | string requestBody = reader.ReadToEnd(); | ||
380 | keysvals.Add("body", requestBody); | ||
381 | |||
382 | httpResponse.StatusCode = 200; | ||
383 | httpResponse.ContentType = "text/html"; | ||
384 | httpResponse.KeepAlive = false; | ||
385 | |||
386 | Hashtable responsedata = new Hashtable(); | ||
387 | |||
388 | UUID agentID; | ||
389 | UUID regionID; | ||
390 | string action; | ||
391 | |||
392 | if (!Utils.GetParams((string)keysvals["uri"], out agentID, out regionID, out action)) | ||
393 | { | ||
394 | m_log.InfoFormat("[AGENT HANDLER]: Invalid parameters for agent message {0}", keysvals["uri"]); | ||
395 | |||
396 | httpResponse.StatusCode = 404; | ||
397 | |||
398 | return encoding.GetBytes("false"); | ||
399 | } | ||
400 | |||
401 | DoAgentPost(keysvals, responsedata, agentID); | ||
402 | |||
403 | httpResponse.StatusCode = (int)responsedata["int_response_code"]; | ||
404 | return encoding.GetBytes((string)responsedata["str_response_string"]); | ||
405 | } | ||
406 | |||
407 | protected void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) | ||
408 | { | ||
409 | OSDMap args = Utils.GetOSDMap((string)request["body"]); | ||
410 | if (args == null) | ||
411 | { | ||
412 | responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||
413 | responsedata["str_response_string"] = "Bad request"; | ||
414 | return; | ||
415 | } | ||
416 | |||
417 | // retrieve the input arguments | ||
418 | int x = 0, y = 0; | ||
419 | UUID uuid = UUID.Zero; | ||
420 | string regionname = string.Empty; | ||
421 | uint teleportFlags = 0; | ||
422 | if (args.ContainsKey("destination_x") && args["destination_x"] != null) | ||
423 | Int32.TryParse(args["destination_x"].AsString(), out x); | ||
424 | else | ||
425 | m_log.WarnFormat(" -- request didn't have destination_x"); | ||
426 | if (args.ContainsKey("destination_y") && args["destination_y"] != null) | ||
427 | Int32.TryParse(args["destination_y"].AsString(), out y); | ||
428 | else | ||
429 | m_log.WarnFormat(" -- request didn't have destination_y"); | ||
430 | if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null) | ||
431 | UUID.TryParse(args["destination_uuid"].AsString(), out uuid); | ||
432 | if (args.ContainsKey("destination_name") && args["destination_name"] != null) | ||
433 | regionname = args["destination_name"].ToString(); | ||
434 | if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null) | ||
435 | teleportFlags = args["teleport_flags"].AsUInteger(); | ||
436 | |||
437 | GridRegion destination = new GridRegion(); | ||
438 | destination.RegionID = uuid; | ||
439 | destination.RegionLocX = x; | ||
440 | destination.RegionLocY = y; | ||
441 | destination.RegionName = regionname; | ||
442 | |||
443 | AgentCircuitData aCircuit = new AgentCircuitData(); | ||
444 | try | ||
445 | { | ||
446 | aCircuit.UnpackAgentCircuitData(args); | ||
447 | } | ||
448 | catch (Exception ex) | ||
449 | { | ||
450 | m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildCreate message {0}", ex.Message); | ||
451 | responsedata["int_response_code"] = HttpStatusCode.BadRequest; | ||
452 | responsedata["str_response_string"] = "Bad request"; | ||
453 | return; | ||
454 | } | ||
455 | |||
456 | OSDMap resp = new OSDMap(2); | ||
457 | string reason = String.Empty; | ||
458 | |||
459 | // This is the meaning of POST agent | ||
460 | //m_regionClient.AdjustUserInformation(aCircuit); | ||
461 | //bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||
462 | bool result = CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||
463 | |||
464 | resp["reason"] = OSD.FromString(reason); | ||
465 | resp["success"] = OSD.FromBoolean(result); | ||
466 | // Let's also send out the IP address of the caller back to the caller (HG 1.5) | ||
467 | resp["your_ip"] = OSD.FromString(GetCallerIP(request)); | ||
468 | |||
469 | // TODO: add reason if not String.Empty? | ||
470 | responsedata["int_response_code"] = HttpStatusCode.OK; | ||
471 | responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); | ||
472 | } | ||
473 | |||
474 | private string GetCallerIP(Hashtable request) | ||
475 | { | ||
476 | if (!m_Proxy) | ||
477 | return Util.GetCallerIP(request); | ||
478 | |||
479 | // We're behind a proxy | ||
480 | Hashtable headers = (Hashtable)request["headers"]; | ||
481 | |||
482 | //// DEBUG | ||
483 | //foreach (object o in headers.Keys) | ||
484 | // m_log.DebugFormat("XXX {0} = {1}", o.ToString(), (headers[o] == null? "null" : headers[o].ToString())); | ||
485 | |||
486 | string xff = "X-Forwarded-For"; | ||
487 | if (headers.ContainsKey(xff.ToLower())) | ||
488 | xff = xff.ToLower(); | ||
489 | |||
490 | if (!headers.ContainsKey(xff) || headers[xff] == null) | ||
491 | { | ||
492 | m_log.WarnFormat("[AGENT HANDLER]: No XFF header"); | ||
493 | return Util.GetCallerIP(request); | ||
494 | } | ||
495 | |||
496 | m_log.DebugFormat("[AGENT HANDLER]: XFF is {0}", headers[xff]); | ||
497 | |||
498 | IPEndPoint ep = Util.GetClientIPFromXFF((string)headers[xff]); | ||
499 | if (ep != null) | ||
500 | return ep.Address.ToString(); | ||
501 | |||
502 | // Oops | ||
503 | return Util.GetCallerIP(request); | ||
504 | } | ||
505 | |||
506 | // subclasses can override this | ||
507 | protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason) | ||
508 | { | ||
509 | return m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); | ||
510 | } | ||
511 | } | ||
437 | } | 512 | } |