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