aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs
diff options
context:
space:
mode:
authorAdam Frisby2008-04-30 21:16:36 +0000
committerAdam Frisby2008-04-30 21:16:36 +0000
commitf5c312bc3c2567449c7268a54a08a54119f58d53 (patch)
tree424668a4bbec6873ebc5b8256f3671db102f5e9c /OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs
parent* Adds the AuthbuyerID field to sqlite and makes use of it. (diff)
downloadopensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.zip
opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.gz
opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.bz2
opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.xz
* Refactored Environment/Modules directory - modules now reside in their own directory with any associated module-specific classes.
* Each module directory is currently inside one of the following category folders: Agent (Anything relating to do with Client<->Server communications.), Avatar (Anything to do with the avatar or presence inworld), Framework (Classes modules can use), Grid (Grid traffic, new OGS2 grid comms), Scripting (Scripting functions, etc), World (The enrivonment/scene, IE Sun/Tree modules.) * This should be moved into a seperate project file.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs (renamed from OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs)720
1 files changed, 356 insertions, 364 deletions
diff --git a/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs b/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 2de5975..4977a86 100644
--- a/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -1,364 +1,356 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Net; 31using System.Net;
32using System.Text; 32using System.Text;
33using System.Threading; 33using System.Threading;
34using libsecondlife; 34using libsecondlife;
35using Nini.Config; 35using Nini.Config;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Region.Environment.Interfaces; 37using OpenSim.Region.Environment.Interfaces;
38using OpenSim.Region.Environment.Scenes; 38using OpenSim.Region.Environment.Scenes;
39 39
40/***************************************************** 40/*****************************************************
41 * 41 *
42 * ScriptsHttpRequests 42 * ScriptsHttpRequests
43 * 43 *
44 * Implements the llHttpRequest and http_response 44 * Implements the llHttpRequest and http_response
45 * callback. 45 * callback.
46 * 46 *
47 * Some stuff was already in LSLLongCmdHandler, and then 47 * Some stuff was already in LSLLongCmdHandler, and then
48 * there was this file with a stub class in it. So, 48 * there was this file with a stub class in it. So,
49 * I am moving some of the objects and functions out of 49 * I am moving some of the objects and functions out of
50 * LSLLongCmdHandler, such as the HttpRequestClass, the 50 * LSLLongCmdHandler, such as the HttpRequestClass, the
51 * start and stop methods, and setting up pending and 51 * start and stop methods, and setting up pending and
52 * completed queues. These are processed in the 52 * completed queues. These are processed in the
53 * LSLLongCmdHandler polling loop. Similiar to the 53 * LSLLongCmdHandler polling loop. Similiar to the
54 * XMLRPCModule, since that seems to work. 54 * XMLRPCModule, since that seems to work.
55 * 55 *
56 * //TODO 56 * //TODO
57 * 57 *
58 * This probably needs some throttling mechanism but 58 * This probably needs some throttling mechanism but
59 * its wide open right now. This applies to both 59 * its wide open right now. This applies to both
60 * number of requests and data volume. 60 * number of requests and data volume.
61 * 61 *
62 * Linden puts all kinds of header fields in the requests. 62 * Linden puts all kinds of header fields in the requests.
63 * Not doing any of that: 63 * Not doing any of that:
64 * User-Agent 64 * User-Agent
65 * X-SecondLife-Shard 65 * X-SecondLife-Shard
66 * X-SecondLife-Object-Name 66 * X-SecondLife-Object-Name
67 * X-SecondLife-Object-Key 67 * X-SecondLife-Object-Key
68 * X-SecondLife-Region 68 * X-SecondLife-Region
69 * X-SecondLife-Local-Position 69 * X-SecondLife-Local-Position
70 * X-SecondLife-Local-Velocity 70 * X-SecondLife-Local-Velocity
71 * X-SecondLife-Local-Rotation 71 * X-SecondLife-Local-Rotation
72 * X-SecondLife-Owner-Name 72 * X-SecondLife-Owner-Name
73 * X-SecondLife-Owner-Key 73 * X-SecondLife-Owner-Key
74 * 74 *
75 * HTTPS support 75 * HTTPS support
76 * 76 *
77 * Configurable timeout? 77 * Configurable timeout?
78 * Configurable max repsonse size? 78 * Configurable max repsonse size?
79 * Configurable 79 * Configurable
80 * 80 *
81 * **************************************************/ 81 * **************************************************/
82 82
83namespace OpenSim.Region.Environment.Modules 83namespace OpenSim.Region.Environment.Modules.Scripting.HttpRequest
84{ 84{
85 public class ScriptHTTPRequests : IRegionModule, IHttpRequests 85 public class HttpRequestModule : IRegionModule, IHttpRequests
86 { 86 {
87 private Scene m_scene; 87 private Scene m_scene;
88 private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); 88 private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
89 private object HttpListLock = new object(); 89 private object HttpListLock = new object();
90 private string m_name = "HttpScriptRequests"; 90 private string m_name = "HttpScriptRequests";
91 private int httpTimeout = 30000; 91 private int httpTimeout = 30000;
92 92
93 // <request id, HttpRequestClass> 93 // <request id, HttpRequestClass>
94 private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests; 94 private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests;
95 95
96 public ScriptHTTPRequests() 96 public HttpRequestModule()
97 { 97 {
98 } 98 }
99 99
100 public void Initialise(Scene scene, IConfigSource config) 100 public void Initialise(Scene scene, IConfigSource config)
101 { 101 {
102 m_scene = scene; 102 m_scene = scene;
103 103
104 m_scene.RegisterModuleInterface<IHttpRequests>(this); 104 m_scene.RegisterModuleInterface<IHttpRequests>(this);
105 105
106 m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>(); 106 m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>();
107 } 107 }
108 108
109 public void PostInitialise() 109 public void PostInitialise()
110 { 110 {
111 } 111 }
112 112
113 public void Close() 113 public void Close()
114 { 114 {
115 } 115 }
116 116
117 public string Name 117 public string Name
118 { 118 {
119 get { return m_name; } 119 get { return m_name; }
120 } 120 }
121 121
122 public bool IsSharedModule 122 public bool IsSharedModule
123 { 123 {
124 get { return true; } 124 get { return true; }
125 } 125 }
126 126
127 public LLUUID MakeHttpRequest(string url, string parameters, string body) 127 public LLUUID MakeHttpRequest(string url, string parameters, string body)
128 { 128 {
129 return LLUUID.Zero; 129 return LLUUID.Zero;
130 } 130 }
131 131
132 public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body) 132 public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body)
133 { 133 {
134 LLUUID reqID = LLUUID.Random(); 134 LLUUID reqID = LLUUID.Random();
135 HttpRequestClass htc = new HttpRequestClass(); 135 HttpRequestClass htc = new HttpRequestClass();
136 136
137 // Partial implementation: support for parameter flags needed 137 // Partial implementation: support for parameter flags needed
138 // see http://wiki.secondlife.com/wiki/LlHTTPRequest 138 // see http://wiki.secondlife.com/wiki/LlHTTPRequest
139 // 139 //
140 // Parameters are expected in {key, value, ... , key, value} 140 // Parameters are expected in {key, value, ... , key, value}
141 if (parameters != null) 141 if (parameters != null)
142 { 142 {
143 string[] parms = parameters.ToArray(); 143 string[] parms = parameters.ToArray();
144 for (int i = 0; i < parms.Length/2; i += 2) 144 for (int i = 0; i < parms.Length/2; i += 2)
145 { 145 {
146 switch (Int32.Parse(parms[i])) 146 switch (Int32.Parse(parms[i]))
147 { 147 {
148 case HttpRequestClass.HTTP_METHOD: 148 case HttpRequestClass.HTTP_METHOD:
149 149
150 htc.httpMethod = parms[i + 1]; 150 htc.httpMethod = parms[i + 1];
151 break; 151 break;
152 152
153 case HttpRequestClass.HTTP_MIMETYPE: 153 case HttpRequestClass.HTTP_MIMETYPE:
154 154
155 htc.httpMIMEType = parms[i + 1]; 155 htc.httpMIMEType = parms[i + 1];
156 break; 156 break;
157 157
158 case HttpRequestClass.HTTP_BODY_MAXLENGTH: 158 case HttpRequestClass.HTTP_BODY_MAXLENGTH:
159 159
160 // TODO implement me 160 // TODO implement me
161 break; 161 break;
162 162
163 case HttpRequestClass.HTTP_VERIFY_CERT: 163 case HttpRequestClass.HTTP_VERIFY_CERT:
164 164
165 // TODO implement me 165 // TODO implement me
166 break; 166 break;
167 } 167 }
168 } 168 }
169 } 169 }
170 170
171 htc.localID = localID; 171 htc.localID = localID;
172 htc.itemID = itemID; 172 htc.itemID = itemID;
173 htc.url = url; 173 htc.url = url;
174 htc.reqID = reqID; 174 htc.reqID = reqID;
175 htc.httpTimeout = httpTimeout; 175 htc.httpTimeout = httpTimeout;
176 htc.outbound_body = body; 176 htc.outbound_body = body;
177 177
178 lock (HttpListLock) 178 lock (HttpListLock)
179 { 179 {
180 m_pendingRequests.Add(reqID, htc); 180 m_pendingRequests.Add(reqID, htc);
181 } 181 }
182 182
183 htc.process(); 183 htc.process();
184 184
185 return reqID; 185 return reqID;
186 } 186 }
187 187
188 public void StopHttpRequest(uint m_localID, LLUUID m_itemID) 188 public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
189 { 189 {
190 if(m_pendingRequests != null) { 190 if(m_pendingRequests != null) {
191 lock (HttpListLock) 191 lock (HttpListLock)
192 { 192 {
193 HttpRequestClass tmpReq; 193 HttpRequestClass tmpReq;
194 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq)) 194 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
195 { 195 {
196 tmpReq.Stop(); 196 tmpReq.Stop();
197 m_pendingRequests.Remove(m_itemID); 197 m_pendingRequests.Remove(m_itemID);
198 } 198 }
199 } 199 }
200 } 200 }
201 } 201 }
202 202
203 /* 203 /*
204 * TODO 204 * TODO
205 * Not sure how important ordering is is here - the next first 205 * Not sure how important ordering is is here - the next first
206 * one completed in the list is returned, based soley on its list 206 * one completed in the list is returned, based soley on its list
207 * position, not the order in which the request was started or 207 * position, not the order in which the request was started or
208 * finsihed. I thought about setting up a queue for this, but 208 * finsihed. I thought about setting up a queue for this, but
209 * it will need some refactoring and this works 'enough' right now 209 * it will need some refactoring and this works 'enough' right now
210 */ 210 */
211 211
212 public HttpRequestClass GetNextCompletedRequest() 212 public HttpRequestClass GetNextCompletedRequest()
213 { 213 {
214 lock (HttpListLock) 214 lock (HttpListLock)
215 { 215 {
216 foreach (LLUUID luid in m_pendingRequests.Keys) 216 foreach (LLUUID luid in m_pendingRequests.Keys)
217 { 217 {
218 HttpRequestClass tmpReq; 218 HttpRequestClass tmpReq;
219 219
220 if (m_pendingRequests.TryGetValue(luid, out tmpReq)) 220 if (m_pendingRequests.TryGetValue(luid, out tmpReq))
221 { 221 {
222 if (tmpReq.finished) 222 if (tmpReq.finished)
223 { 223 {
224 return tmpReq; 224 return tmpReq;
225 } 225 }
226 } 226 }
227 } 227 }
228 } 228 }
229 return null; 229 return null;
230 } 230 }
231 231
232 public void RemoveCompletedRequest(LLUUID id) 232 public void RemoveCompletedRequest(LLUUID id)
233 { 233 {
234 lock (HttpListLock) 234 lock (HttpListLock)
235 { 235 {
236 HttpRequestClass tmpReq; 236 HttpRequestClass tmpReq;
237 if (m_pendingRequests.TryGetValue(id, out tmpReq)) 237 if (m_pendingRequests.TryGetValue(id, out tmpReq))
238 { 238 {
239 tmpReq.Stop(); 239 tmpReq.Stop();
240 tmpReq = null; 240 tmpReq = null;
241 m_pendingRequests.Remove(id); 241 m_pendingRequests.Remove(id);
242 } 242 }
243 } 243 }
244 } 244 }
245 245
246 } 246 }
247 247
248 // 248 public class HttpRequestClass
249 // HTTP REAQUEST 249 {
250 // This class was originally in LSLLongCmdHandler 250 // Constants for parameters
251 // 251 public const int HTTP_METHOD = 0;
252 // TODO: setter/getter methods, maybe pass some in 252 public const int HTTP_MIMETYPE = 1;
253 // constructor 253 public const int HTTP_BODY_MAXLENGTH = 2;
254 // 254 public const int HTTP_VERIFY_CERT = 3;
255 255
256 public class HttpRequestClass 256 // Parameter members and default values
257 { 257 public string httpMethod = "GET";
258 // Constants for parameters 258 public string httpMIMEType = "text/plain;charset=utf-8";
259 public const int HTTP_METHOD = 0; 259 public int httpBodyMaxLen = 2048; // not implemented
260 public const int HTTP_MIMETYPE = 1; 260 public bool httpVerifyCert = true; // not implemented
261 public const int HTTP_BODY_MAXLENGTH = 2; 261
262 public const int HTTP_VERIFY_CERT = 3; 262 // Request info
263 263 public uint localID;
264 // Parameter members and default values 264 public LLUUID itemID;
265 public string httpMethod = "GET"; 265 public LLUUID reqID;
266 public string httpMIMEType = "text/plain;charset=utf-8"; 266 public int httpTimeout;
267 public int httpBodyMaxLen = 2048; // not implemented 267 public string url;
268 public bool httpVerifyCert = true; // not implemented 268 public string outbound_body;
269 269 public DateTime next;
270 // Request info 270 public int status;
271 public uint localID; 271 public bool finished;
272 public LLUUID itemID; 272 public List<string> response_metadata;
273 public LLUUID reqID; 273 public string response_body;
274 public int httpTimeout; 274 public HttpWebRequest request;
275 public string url; 275 private Thread httpThread;
276 public string outbound_body; 276
277 public DateTime next; 277 public void process()
278 public int status; 278 {
279 public bool finished; 279 httpThread = new Thread(SendRequest);
280 public List<string> response_metadata; 280 httpThread.Name = "HttpRequestThread";
281 public string response_body; 281 httpThread.Priority = ThreadPriority.BelowNormal;
282 public HttpWebRequest request; 282 httpThread.IsBackground = true;
283 private Thread httpThread; 283 finished = false;
284 284 httpThread.Start();
285 public void process() 285 ThreadTracker.Add(httpThread);
286 { 286 }
287 httpThread = new Thread(SendRequest); 287
288 httpThread.Name = "HttpRequestThread"; 288 /*
289 httpThread.Priority = ThreadPriority.BelowNormal; 289 * TODO: More work on the response codes. Right now
290 httpThread.IsBackground = true; 290 * returning 200 for success or 499 for exception
291 finished = false; 291 */
292 httpThread.Start(); 292
293 ThreadTracker.Add(httpThread); 293 public void SendRequest()
294 } 294 {
295 295 HttpWebResponse response = null;
296 /* 296 StringBuilder sb = new StringBuilder();
297 * TODO: More work on the response codes. Right now 297 byte[] buf = new byte[8192];
298 * returning 200 for success or 499 for exception 298 string tempString = null;
299 */ 299 int count = 0;
300 300
301 public void SendRequest() 301 try
302 { 302 {
303 HttpWebResponse response = null; 303 request = (HttpWebRequest)
304 StringBuilder sb = new StringBuilder(); 304 WebRequest.Create(url);
305 byte[] buf = new byte[8192]; 305 request.Method = httpMethod;
306 string tempString = null; 306 request.ContentType = httpMIMEType;
307 int count = 0; 307
308 308 request.Timeout = httpTimeout;
309 try 309 // execute the request
310 { 310 response = (HttpWebResponse)
311 request = (HttpWebRequest) 311 request.GetResponse();
312 WebRequest.Create(url); 312
313 request.Method = httpMethod; 313 Stream resStream = response.GetResponseStream();
314 request.ContentType = httpMIMEType; 314
315 315 do
316 request.Timeout = httpTimeout; 316 {
317 // execute the request 317 // fill the buffer with data
318 response = (HttpWebResponse) 318 count = resStream.Read(buf, 0, buf.Length);
319 request.GetResponse(); 319
320 320 // make sure we read some data
321 Stream resStream = response.GetResponseStream(); 321 if (count != 0)
322 322 {
323 do 323 // translate from bytes to ASCII text
324 { 324 tempString = Encoding.UTF8.GetString(buf, 0, count);
325 // fill the buffer with data 325
326 count = resStream.Read(buf, 0, buf.Length); 326 // continue building the string
327 327 sb.Append(tempString);
328 // make sure we read some data 328 }
329 if (count != 0) 329 } while (count > 0); // any more data to read?
330 { 330
331 // translate from bytes to ASCII text 331 response_body = sb.ToString();
332 tempString = Encoding.UTF8.GetString(buf, 0, count); 332 }
333 333 catch (Exception e)
334 // continue building the string 334 {
335 sb.Append(tempString); 335 status = 499;
336 } 336 response_body = e.Message;
337 } while (count > 0); // any more data to read? 337 finished = true;
338 338 return;
339 response_body = sb.ToString(); 339 }
340 } 340
341 catch (Exception e) 341 status = 200;
342 { 342 finished = true;
343 status = 499; 343 }
344 response_body = e.Message; 344
345 finished = true; 345 public void Stop()
346 return; 346 {
347 } 347 try
348 348 {
349 status = 200; 349 httpThread.Abort();
350 finished = true; 350 }
351 } 351 catch (Exception)
352 352 {
353 public void Stop() 353 }
354 { 354 }
355 try 355 }
356 { 356} \ No newline at end of file
357 httpThread.Abort();
358 }
359 catch (Exception)
360 {
361 }
362 }
363 }
364}