diff options
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer/RestSessionService.cs')
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/RestSessionService.cs | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs new file mode 100644 index 0000000..ad69cd2 --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs | |||
@@ -0,0 +1,295 @@ | |||
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.IO; | ||
30 | using System.Net; | ||
31 | using System.Reflection; | ||
32 | using System.Text; | ||
33 | using System.Xml; | ||
34 | using System.Xml.Serialization; | ||
35 | using log4net; | ||
36 | |||
37 | namespace OpenSim.Framework.Servers.HttpServer | ||
38 | { | ||
39 | public class RestSessionObject<TRequest> | ||
40 | { | ||
41 | private string sid; | ||
42 | private string aid; | ||
43 | private TRequest request_body; | ||
44 | |||
45 | public string SessionID | ||
46 | { | ||
47 | get { return sid; } | ||
48 | set { sid = value; } | ||
49 | } | ||
50 | |||
51 | public string AvatarID | ||
52 | { | ||
53 | get { return aid; } | ||
54 | set { aid = value; } | ||
55 | } | ||
56 | |||
57 | public TRequest Body | ||
58 | { | ||
59 | get { return request_body; } | ||
60 | set { request_body = value; } | ||
61 | } | ||
62 | } | ||
63 | |||
64 | public class SynchronousRestSessionObjectPoster<TRequest, TResponse> | ||
65 | { | ||
66 | public static TResponse BeginPostObject(string verb, string requestUrl, TRequest obj, string sid, string aid) | ||
67 | { | ||
68 | RestSessionObject<TRequest> sobj = new RestSessionObject<TRequest>(); | ||
69 | sobj.SessionID = sid; | ||
70 | sobj.AvatarID = aid; | ||
71 | sobj.Body = obj; | ||
72 | |||
73 | Type type = typeof(RestSessionObject<TRequest>); | ||
74 | |||
75 | WebRequest request = WebRequest.Create(requestUrl); | ||
76 | request.Method = verb; | ||
77 | request.ContentType = "text/xml"; | ||
78 | request.Timeout = 20000; | ||
79 | |||
80 | using (MemoryStream buffer = new MemoryStream()) | ||
81 | { | ||
82 | XmlWriterSettings settings = new XmlWriterSettings(); | ||
83 | settings.Encoding = Encoding.UTF8; | ||
84 | |||
85 | using (XmlWriter writer = XmlWriter.Create(buffer, settings)) | ||
86 | { | ||
87 | XmlSerializer serializer = new XmlSerializer(type); | ||
88 | serializer.Serialize(writer, sobj); | ||
89 | writer.Flush(); | ||
90 | } | ||
91 | |||
92 | int length = (int)buffer.Length; | ||
93 | request.ContentLength = length; | ||
94 | |||
95 | using (Stream requestStream = request.GetRequestStream()) | ||
96 | requestStream.Write(buffer.ToArray(), 0, length); | ||
97 | } | ||
98 | |||
99 | TResponse deserial = default(TResponse); | ||
100 | using (WebResponse resp = request.GetResponse()) | ||
101 | { | ||
102 | XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); | ||
103 | |||
104 | using (Stream respStream = resp.GetResponseStream()) | ||
105 | deserial = (TResponse)deserializer.Deserialize(respStream); | ||
106 | } | ||
107 | |||
108 | return deserial; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | public class RestSessionObjectPosterResponse<TRequest, TResponse> | ||
113 | { | ||
114 | public ReturnResponse<TResponse> ResponseCallback; | ||
115 | |||
116 | public void BeginPostObject(string requestUrl, TRequest obj, string sid, string aid) | ||
117 | { | ||
118 | BeginPostObject("POST", requestUrl, obj, sid, aid); | ||
119 | } | ||
120 | |||
121 | public void BeginPostObject(string verb, string requestUrl, TRequest obj, string sid, string aid) | ||
122 | { | ||
123 | RestSessionObject<TRequest> sobj = new RestSessionObject<TRequest>(); | ||
124 | sobj.SessionID = sid; | ||
125 | sobj.AvatarID = aid; | ||
126 | sobj.Body = obj; | ||
127 | |||
128 | Type type = typeof(RestSessionObject<TRequest>); | ||
129 | |||
130 | WebRequest request = WebRequest.Create(requestUrl); | ||
131 | request.Method = verb; | ||
132 | request.ContentType = "text/xml"; | ||
133 | request.Timeout = 10000; | ||
134 | |||
135 | using (MemoryStream buffer = new MemoryStream()) | ||
136 | { | ||
137 | XmlWriterSettings settings = new XmlWriterSettings(); | ||
138 | settings.Encoding = Encoding.UTF8; | ||
139 | |||
140 | using (XmlWriter writer = XmlWriter.Create(buffer, settings)) | ||
141 | { | ||
142 | XmlSerializer serializer = new XmlSerializer(type); | ||
143 | serializer.Serialize(writer, sobj); | ||
144 | writer.Flush(); | ||
145 | } | ||
146 | |||
147 | int length = (int)buffer.Length; | ||
148 | request.ContentLength = length; | ||
149 | |||
150 | using (Stream requestStream = request.GetRequestStream()) | ||
151 | requestStream.Write(buffer.ToArray(), 0, length); | ||
152 | } | ||
153 | |||
154 | // IAsyncResult result = request.BeginGetResponse(AsyncCallback, request); | ||
155 | request.BeginGetResponse(AsyncCallback, request); | ||
156 | } | ||
157 | |||
158 | private void AsyncCallback(IAsyncResult result) | ||
159 | { | ||
160 | WebRequest request = (WebRequest)result.AsyncState; | ||
161 | using (WebResponse resp = request.EndGetResponse(result)) | ||
162 | { | ||
163 | TResponse deserial; | ||
164 | XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); | ||
165 | Stream stream = resp.GetResponseStream(); | ||
166 | |||
167 | // This is currently a bad debug stanza since it gobbles us the response... | ||
168 | // StreamReader reader = new StreamReader(stream); | ||
169 | // m_log.DebugFormat("[REST OBJECT POSTER RESPONSE]: Received {0}", reader.ReadToEnd()); | ||
170 | |||
171 | deserial = (TResponse)deserializer.Deserialize(stream); | ||
172 | if (stream != null) | ||
173 | stream.Close(); | ||
174 | |||
175 | if (deserial != null && ResponseCallback != null) | ||
176 | { | ||
177 | ResponseCallback(deserial); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | |||
183 | public delegate bool CheckIdentityMethod(string sid, string aid); | ||
184 | |||
185 | public class RestDeserialiseSecureHandler<TRequest, TResponse> : BaseOutputStreamHandler, IStreamHandler | ||
186 | where TRequest : new() | ||
187 | { | ||
188 | private static readonly ILog m_log | ||
189 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
190 | |||
191 | private RestDeserialiseMethod<TRequest, TResponse> m_method; | ||
192 | private CheckIdentityMethod m_smethod; | ||
193 | |||
194 | public RestDeserialiseSecureHandler( | ||
195 | string httpMethod, string path, | ||
196 | RestDeserialiseMethod<TRequest, TResponse> method, CheckIdentityMethod smethod) | ||
197 | : base(httpMethod, path) | ||
198 | { | ||
199 | m_smethod = smethod; | ||
200 | m_method = method; | ||
201 | } | ||
202 | |||
203 | protected override void ProcessRequest(string path, Stream request, Stream responseStream, | ||
204 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||
205 | { | ||
206 | RestSessionObject<TRequest> deserial = default(RestSessionObject<TRequest>); | ||
207 | bool fail = false; | ||
208 | |||
209 | using (XmlTextReader xmlReader = new XmlTextReader(request)) | ||
210 | { | ||
211 | try | ||
212 | { | ||
213 | XmlSerializer deserializer = new XmlSerializer(typeof(RestSessionObject<TRequest>)); | ||
214 | deserial = (RestSessionObject<TRequest>)deserializer.Deserialize(xmlReader); | ||
215 | } | ||
216 | catch (Exception e) | ||
217 | { | ||
218 | m_log.Error("[REST]: Deserialization problem. Ignoring request. " + e); | ||
219 | fail = true; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | TResponse response = default(TResponse); | ||
224 | if (!fail && m_smethod(deserial.SessionID, deserial.AvatarID)) | ||
225 | { | ||
226 | response = m_method(deserial.Body); | ||
227 | } | ||
228 | |||
229 | using (XmlWriter xmlWriter = XmlTextWriter.Create(responseStream)) | ||
230 | { | ||
231 | XmlSerializer serializer = new XmlSerializer(typeof(TResponse)); | ||
232 | serializer.Serialize(xmlWriter, response); | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | public delegate bool CheckTrustedSourceMethod(IPEndPoint peer); | ||
238 | |||
239 | public class RestDeserialiseTrustedHandler<TRequest, TResponse> : BaseOutputStreamHandler, IStreamHandler | ||
240 | where TRequest : new() | ||
241 | { | ||
242 | private static readonly ILog m_log | ||
243 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
244 | |||
245 | /// <summary> | ||
246 | /// The operation to perform once trust has been established. | ||
247 | /// </summary> | ||
248 | private RestDeserialiseMethod<TRequest, TResponse> m_method; | ||
249 | |||
250 | /// <summary> | ||
251 | /// The method used to check whether a request is trusted. | ||
252 | /// </summary> | ||
253 | private CheckTrustedSourceMethod m_tmethod; | ||
254 | |||
255 | public RestDeserialiseTrustedHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, CheckTrustedSourceMethod tmethod) | ||
256 | : base(httpMethod, path) | ||
257 | { | ||
258 | m_tmethod = tmethod; | ||
259 | m_method = method; | ||
260 | } | ||
261 | |||
262 | protected override void ProcessRequest(string path, Stream request, Stream responseStream, | ||
263 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||
264 | { | ||
265 | TRequest deserial = default(TRequest); | ||
266 | bool fail = false; | ||
267 | |||
268 | using (XmlTextReader xmlReader = new XmlTextReader(request)) | ||
269 | { | ||
270 | try | ||
271 | { | ||
272 | XmlSerializer deserializer = new XmlSerializer(typeof(TRequest)); | ||
273 | deserial = (TRequest)deserializer.Deserialize(xmlReader); | ||
274 | } | ||
275 | catch (Exception e) | ||
276 | { | ||
277 | m_log.Error("[REST]: Deserialization problem. Ignoring request. " + e); | ||
278 | fail = true; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | TResponse response = default(TResponse); | ||
283 | if (!fail && m_tmethod(httpRequest.RemoteIPEndPoint)) | ||
284 | { | ||
285 | response = m_method(deserial); | ||
286 | } | ||
287 | |||
288 | using (XmlWriter xmlWriter = XmlTextWriter.Create(responseStream)) | ||
289 | { | ||
290 | XmlSerializer serializer = new XmlSerializer(typeof(TResponse)); | ||
291 | serializer.Serialize(xmlWriter, response); | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | } \ No newline at end of file | ||