clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Reflection;
32 using System.Xml;
33  
34 using Nini.Config;
35 using log4net;
36 using OpenMetaverse;
37  
38 using OpenSim.Framework;
39 using OpenSim.Server.Base;
40 using OpenSim.Services.Interfaces;
41 using OpenSim.Framework.ServiceAuth;
42 using OpenSim.Framework.Servers.HttpServer;
43 using OpenSim.Server.Handlers.Base;
44  
45 using GridRegion = OpenSim.Services.Interfaces.GridRegion;
46  
47 namespace OpenSim.Server.Handlers.MapImage
48 {
49 public class MapAddServiceConnector : ServiceConnector
50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52  
53 private IMapImageService m_MapService;
54 private IGridService m_GridService;
55 private string m_ConfigName = "MapImageService";
56  
57 public MapAddServiceConnector(IConfigSource config, IHttpServer server, string configName) :
58 base(config, server, configName)
59 {
60 IConfig serverConfig = config.Configs[m_ConfigName];
61 if (serverConfig == null)
62 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
63  
64 string mapService = serverConfig.GetString("LocalServiceModule",
65 String.Empty);
66  
67 if (mapService == String.Empty)
68 throw new Exception("No LocalServiceModule in config file");
69  
70 Object[] args = new Object[] { config };
71 m_MapService = ServerUtils.LoadPlugin<IMapImageService>(mapService, args);
72  
73 string gridService = serverConfig.GetString("GridService", String.Empty);
74 if (gridService != string.Empty)
75 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
76  
77 if (m_GridService != null)
78 m_log.InfoFormat("[MAP IMAGE HANDLER]: GridService check is ON");
79 else
80 m_log.InfoFormat("[MAP IMAGE HANDLER]: GridService check is OFF");
81  
82 bool proxy = serverConfig.GetBoolean("HasProxy", false);
83 IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
84 server.AddStreamHandler(new MapServerPostHandler(m_MapService, m_GridService, proxy, auth));
85  
86 }
87 }
88  
89 class MapServerPostHandler : BaseStreamHandler
90 {
91 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
92 private IMapImageService m_MapService;
93 private IGridService m_GridService;
94 bool m_Proxy;
95  
96 public MapServerPostHandler(IMapImageService service, IGridService grid, bool proxy, IServiceAuth auth) :
97 base("POST", "/map", auth)
98 {
99 m_MapService = service;
100 m_GridService = grid;
101 m_Proxy = proxy;
102 }
103  
104 protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
105 {
106 // m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: Received {0}", path);
107 StreamReader sr = new StreamReader(requestData);
108 string body = sr.ReadToEnd();
109 sr.Close();
110 body = body.Trim();
111  
112 try
113 {
114 Dictionary<string, object> request = ServerUtils.ParseQueryString(body);
115  
116 if (!request.ContainsKey("X") || !request.ContainsKey("Y") || !request.ContainsKey("DATA"))
117 {
118 httpResponse.StatusCode = (int)OSHttpStatusCode.ClientErrorBadRequest;
119 return FailureResult("Bad request.");
120 }
121 uint x = 0, y = 0;
122 UInt32.TryParse(request["X"].ToString(), out x);
123 UInt32.TryParse(request["Y"].ToString(), out y);
124  
125 m_log.DebugFormat("[MAP ADD SERVER CONNECTOR]: Received map data for region at {0}-{1}", x, y);
126  
127 // string type = "image/jpeg";
128 //
129 // if (request.ContainsKey("TYPE"))
130 // type = request["TYPE"].ToString();
131  
132 if (m_GridService != null)
133 {
134 System.Net.IPAddress ipAddr = GetCallerIP(httpRequest);
135 GridRegion r = m_GridService.GetRegionByPosition(UUID.Zero, (int)Util.RegionToWorldLoc(x), (int)Util.RegionToWorldLoc(y));
136 if (r != null)
137 {
138 if (r.ExternalEndPoint.Address.ToString() != ipAddr.ToString())
139 {
140 m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be trying to impersonate region in IP {1}", ipAddr, r.ExternalEndPoint.Address);
141 return FailureResult("IP address of caller does not match IP address of registered region");
142 }
143  
144 }
145 else
146 {
147 m_log.WarnFormat("[MAP IMAGE HANDLER]: IP address {0} may be rogue. Region not found at coordinates {1}-{2}",
148 ipAddr, x, y);
149 return FailureResult("Region not found at given coordinates");
150 }
151 }
152  
153 byte[] data = Convert.FromBase64String(request["DATA"].ToString());
154  
155 string reason = string.Empty;
156 bool result = m_MapService.AddMapTile((int)x, (int)y, data, out reason);
157  
158 if (result)
159 return SuccessResult();
160 else
161 return FailureResult(reason);
162  
163 }
164 catch (Exception e)
165 {
166 m_log.ErrorFormat("[MAP SERVICE IMAGE HANDLER]: Exception {0} {1}", e.Message, e.StackTrace);
167 }
168  
169 return FailureResult("Unexpected server error");
170 }
171  
172 private byte[] SuccessResult()
173 {
174 XmlDocument doc = new XmlDocument();
175  
176 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
177 "", "");
178  
179 doc.AppendChild(xmlnode);
180  
181 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
182 "");
183  
184 doc.AppendChild(rootElement);
185  
186 XmlElement result = doc.CreateElement("", "Result", "");
187 result.AppendChild(doc.CreateTextNode("Success"));
188  
189 rootElement.AppendChild(result);
190  
191 return Util.DocToBytes(doc);
192 }
193  
194 private byte[] FailureResult(string msg)
195 {
196 XmlDocument doc = new XmlDocument();
197  
198 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
199 "", "");
200  
201 doc.AppendChild(xmlnode);
202  
203 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
204 "");
205  
206 doc.AppendChild(rootElement);
207  
208 XmlElement result = doc.CreateElement("", "Result", "");
209 result.AppendChild(doc.CreateTextNode("Failure"));
210  
211 rootElement.AppendChild(result);
212  
213 XmlElement message = doc.CreateElement("", "Message", "");
214 message.AppendChild(doc.CreateTextNode(msg));
215  
216 rootElement.AppendChild(message);
217  
218 return Util.DocToBytes(doc);
219 }
220  
221 private System.Net.IPAddress GetCallerIP(IOSHttpRequest request)
222 {
223 if (!m_Proxy)
224 return request.RemoteIPEndPoint.Address;
225  
226 // We're behind a proxy
227 string xff = "X-Forwarded-For";
228 string xffValue = request.Headers[xff.ToLower()];
229 if (xffValue == null || (xffValue != null && xffValue == string.Empty))
230 xffValue = request.Headers[xff];
231  
232 if (xffValue == null || (xffValue != null && xffValue == string.Empty))
233 {
234 m_log.WarnFormat("[MAP IMAGE HANDLER]: No XFF header");
235 return request.RemoteIPEndPoint.Address;
236 }
237  
238 System.Net.IPEndPoint ep = Util.GetClientIPFromXFF(xffValue);
239 if (ep != null)
240 return ep.Address;
241  
242 // Oops
243 return request.RemoteIPEndPoint.Address;
244 }
245  
246 }
247 }