OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
EstateDataRobustConnector.cs
Go to the documentation of this file.
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 OpenSimulator 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 using System;
28 using System.Collections.Generic;
29 using System.IO;
30 using System.Reflection;
31 using System.Net;
32 
33 using Nini.Config;
34 using log4net;
35 using OpenMetaverse;
36 
37 using OpenSim.Server.Base;
38 using OpenSim.Services.Interfaces;
39 using OpenSim.Framework;
40 using OpenSim.Framework.ServiceAuth;
41 using OpenSim.Framework.Servers.HttpServer;
42 using OpenSim.Server.Handlers.Base;
43 
44 namespace OpenSim.Server.Handlers
45 {
47  {
48  private string m_ConfigName = "EstateService";
49 
50  public EstateDataRobustConnector(IConfigSource config, IHttpServer server, string configName) :
51  base(config, server, configName)
52  {
53  IConfig serverConfig = config.Configs[m_ConfigName];
54  if (serverConfig == null)
55  throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
56 
57  string service = serverConfig.GetString("LocalServiceModule",
58  String.Empty);
59 
60  if (service == String.Empty)
61  throw new Exception("No LocalServiceModule in config file");
62 
63  Object[] args = new Object[] { config };
64  IEstateDataService e_service = ServerUtils.LoadPlugin<IEstateDataService>(service, args);
65 
66  IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName); ;
67 
68  server.AddStreamHandler(new EstateServerGetHandler(e_service, auth));
69  server.AddStreamHandler(new EstateServerPostHandler(e_service, auth));
70  }
71  }
72 
73 
75  {
76 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 
78  IEstateDataService m_EstateService;
79 
80  // Possibilities
81  // /estates/estate/?region=uuid&create=[t|f]
82  // /estates/estate/?eid=int
83  // /estates/?name=string
84  // /estates/?owner=uuid
85  // /estates/ (all)
86  // /estates/regions/?eid=int
87 
89  base("GET", "/estates", auth)
90  {
91  m_EstateService = service;
92  }
93 
94  protected override byte[] ProcessRequest(string path, Stream request,
95  IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
96  {
97  Dictionary<string, object> data = null;
98 
99  string[] p = SplitParams(path);
100 
101  // /estates/ (all)
102  // /estates/?name=string
103  // /estates/?owner=uuid
104  if (p.Length == 0)
105  data = GetEstates(httpRequest, httpResponse);
106  else
107  {
108  string resource = p[0];
109 
110  // /estates/estate/?region=uuid&create=[t|f]
111  // /estates/estate/?eid=int
112  if ("estate".Equals(resource))
113  data = GetEstate(httpRequest, httpResponse);
114  // /estates/regions/?eid=int
115  else if ("regions".Equals(resource))
116  data = GetRegions(httpRequest, httpResponse);
117  }
118 
119  if (data == null)
120  data = new Dictionary<string, object>();
121 
122  string xmlString = ServerUtils.BuildXmlResponse(data);
123  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
124 
125  }
126 
127  private Dictionary<string, object> GetEstates(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
128  {
129  // /estates/ (all)
130  // /estates/?name=string
131  // /estates/?owner=uuid
132 
133  Dictionary<string, object> data = null;
134  string name = (string)httpRequest.Query["name"];
135  string owner = (string)httpRequest.Query["owner"];
136 
137  if (!string.IsNullOrEmpty(name) || !string.IsNullOrEmpty(owner))
138  {
139  List<int> estateIDs = null;
140  if (!string.IsNullOrEmpty(name))
141  {
142  estateIDs = m_EstateService.GetEstates(name);
143  }
144  else if (!string.IsNullOrEmpty(owner))
145  {
146  UUID ownerID = UUID.Zero;
147  if (UUID.TryParse(owner, out ownerID))
148  estateIDs = m_EstateService.GetEstatesByOwner(ownerID);
149  }
150 
151  if (estateIDs == null || (estateIDs != null && estateIDs.Count == 0))
152  httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
153  else
154  {
155  httpResponse.StatusCode = (int)HttpStatusCode.OK;
156  httpResponse.ContentType = "text/xml";
157  data = new Dictionary<string, object>();
158  int i = 0;
159  foreach (int id in estateIDs)
160  data["estate" + i++] = id;
161  }
162  }
163  else
164  {
165  List<EstateSettings> estates = m_EstateService.LoadEstateSettingsAll();
166  if (estates == null || estates.Count == 0)
167  {
168  httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
169  }
170  else
171  {
172  httpResponse.StatusCode = (int)HttpStatusCode.OK;
173  httpResponse.ContentType = "text/xml";
174  data = new Dictionary<string, object>();
175  int i = 0;
176  foreach (EstateSettings es in estates)
177  data["estate" + i++] = es.ToMap();
178 
179  }
180  }
181 
182  return data;
183  }
184 
185  private Dictionary<string, object> GetEstate(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
186  {
187  // /estates/estate/?region=uuid&create=[t|f]
188  // /estates/estate/?eid=int
189  Dictionary<string, object> data = null;
190  string region = (string)httpRequest.Query["region"];
191  string eid = (string)httpRequest.Query["eid"];
192 
193  EstateSettings estate = null;
194 
195  if (!string.IsNullOrEmpty(region))
196  {
197  UUID regionID = UUID.Zero;
198  if (UUID.TryParse(region, out regionID))
199  {
200  string create = (string)httpRequest.Query["create"];
201  bool createYN = false;
202  Boolean.TryParse(create, out createYN);
203  estate = m_EstateService.LoadEstateSettings(regionID, createYN);
204  }
205  }
206  else if (!string.IsNullOrEmpty(eid))
207  {
208  int id = 0;
209  if (Int32.TryParse(eid, out id))
210  estate = m_EstateService.LoadEstateSettings(id);
211  }
212 
213  if (estate != null)
214  {
215  httpResponse.StatusCode = (int)HttpStatusCode.OK;
216  httpResponse.ContentType = "text/xml";
217  data = estate.ToMap();
218  }
219  else
220  httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
221 
222  return data;
223  }
224 
225  private Dictionary<string, object> GetRegions(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
226  {
227  // /estates/regions/?eid=int
228  Dictionary<string, object> data = null;
229  string eid = (string)httpRequest.Query["eid"];
230 
231  httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
232  if (!string.IsNullOrEmpty(eid))
233  {
234  int id = 0;
235  if (Int32.TryParse(eid, out id))
236  {
237  List<UUID> regions = m_EstateService.GetRegions(id);
238  if (regions != null && regions.Count > 0)
239  {
240  data = new Dictionary<string, object>();
241  int i = 0;
242  foreach (UUID uuid in regions)
243  data["region" + i++] = uuid.ToString();
244  httpResponse.StatusCode = (int)HttpStatusCode.OK;
245  httpResponse.ContentType = "text/xml";
246  }
247  }
248  }
249 
250  return data;
251  }
252  }
253 
255  {
256  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
257 
258  IEstateDataService m_EstateService;
259 
260  // Possibilities
261  // /estates/estate/ (post an estate)
262  // /estates/estate/?eid=int&region=uuid (link a region to an estate)
263 
265  base("POST", "/estates", auth)
266  {
267  m_EstateService = service;
268  }
269 
270  protected override byte[] ProcessRequest(string path, Stream request,
271  IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
272  {
273  Dictionary<string, object> data = null;
274 
275  string[] p = SplitParams(path);
276 
277  if (p.Length > 0)
278  {
279  string resource = p[0];
280 
281  // /estates/estate/
282  // /estates/estate/?eid=int&region=uuid
283  if ("estate".Equals(resource))
284  {
285  StreamReader sr = new StreamReader(request);
286  string body = sr.ReadToEnd();
287  sr.Close();
288  body = body.Trim();
289 
290  Dictionary<string, object> requestData = ServerUtils.ParseQueryString(body);
291 
292  data = UpdateEstate(requestData, httpRequest, httpResponse);
293  }
294  }
295 
296  if (data == null)
297  data = new Dictionary<string, object>();
298 
299  string xmlString = ServerUtils.BuildXmlResponse(data);
300  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
301 
302  }
303 
304  private Dictionary<string, object> UpdateEstate(Dictionary<string, object> requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
305  {
306  // /estates/estate/
307  // /estates/estate/?eid=int&region=uuid
308  Dictionary<string, object> result = new Dictionary<string, object>();
309  string eid = (string)httpRequest.Query["eid"];
310  string region = (string)httpRequest.Query["region"];
311 
312  httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
313 
314  if (string.IsNullOrEmpty(eid) && string.IsNullOrEmpty(region) &&
315  requestData.ContainsKey("OP") && requestData["OP"] != null && "STORE".Equals(requestData["OP"]))
316  {
317  // /estates/estate/
318  EstateSettings es = new EstateSettings(requestData);
319  m_EstateService.StoreEstateSettings(es);
320  //m_log.DebugFormat("[EstateServerPostHandler]: Store estate {0}", es.ToString());
321  httpResponse.StatusCode = (int)HttpStatusCode.OK;
322  result["Result"] = true;
323  }
324  else if (!string.IsNullOrEmpty(region) && !string.IsNullOrEmpty(eid) &&
325  requestData.ContainsKey("OP") && requestData["OP"] != null && "LINK".Equals(requestData["OP"]))
326  {
327  int id = 0;
328  UUID regionID = UUID.Zero;
329  if (UUID.TryParse(region, out regionID) && Int32.TryParse(eid, out id))
330  {
331  m_log.DebugFormat("[EstateServerPostHandler]: Link region {0} to estate {1}", regionID, id);
332  httpResponse.StatusCode = (int)HttpStatusCode.OK;
333  result["Result"] = m_EstateService.LinkRegion(regionID, id);
334  }
335  }
336  else
337  m_log.WarnFormat("[EstateServerPostHandler]: something wrong with POST request {0}", httpRequest.RawUrl);
338 
339  return result;
340  }
341 
342  }
343 }
override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
Dictionary< string, object > ToMap()
EstateDataRobustConnector(IConfigSource config, IHttpServer server, string configName)
EstateServerPostHandler(IEstateDataService service, IServiceAuth auth)
Interface to OpenSimulator's built in HTTP server. Use this to register handlers (http, llsd, xmlrpc, etc.) for given URLs.
Definition: IHttpServer.cs:36
EstateServerGetHandler(IEstateDataService service, IServiceAuth auth)
override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)