aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs326
-rw-r--r--OpenSim/Framework/Communications/RestClient/RestClient.cs656
2 files changed, 491 insertions, 491 deletions
diff --git a/OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs b/OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs
index 4be459d..55456ae 100644
--- a/OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs
+++ b/OpenSim/Framework/Communications/RestClient/GenericAsyncResult.cs
@@ -1,163 +1,163 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4using System.Threading; 4using System.Threading;
5 5
6namespace OpenSim.Framework.RestClient 6namespace OpenSim.Framework.RestClient
7{ 7{
8 internal class SimpleAsyncResult : IAsyncResult 8 internal class SimpleAsyncResult : IAsyncResult
9 { 9 {
10 10
11 private readonly AsyncCallback m_callback; 11 private readonly AsyncCallback m_callback;
12 12
13 /// <summary> 13 /// <summary>
14 /// Is process completed? 14 /// Is process completed?
15 /// </summary> 15 /// </summary>
16 /// <remarks>Should really be boolean, but VolatileRead has no boolean method</remarks> 16 /// <remarks>Should really be boolean, but VolatileRead has no boolean method</remarks>
17 private byte m_completed; 17 private byte m_completed;
18 18
19 /// <summary> 19 /// <summary>
20 /// Did process complete synchroneously? 20 /// Did process complete synchroneously?
21 /// </summary> 21 /// </summary>
22 /// <remarks>I have a hard time imagining a scenario where this is the case, again, same issue about 22 /// <remarks>I have a hard time imagining a scenario where this is the case, again, same issue about
23 /// booleans and VolatileRead as m_completed 23 /// booleans and VolatileRead as m_completed
24 /// </remarks> 24 /// </remarks>
25 private byte m_completedSynchronously; 25 private byte m_completedSynchronously;
26 26
27 private readonly object m_asyncState; 27 private readonly object m_asyncState;
28 private ManualResetEvent m_waitHandle; 28 private ManualResetEvent m_waitHandle;
29 private Exception m_exception; 29 private Exception m_exception;
30 30
31 internal SimpleAsyncResult(AsyncCallback cb, object state) 31 internal SimpleAsyncResult(AsyncCallback cb, object state)
32 { 32 {
33 m_callback = cb; 33 m_callback = cb;
34 m_asyncState = state; 34 m_asyncState = state;
35 m_completed = 0; 35 m_completed = 0;
36 m_completedSynchronously = 1; 36 m_completedSynchronously = 1;
37 } 37 }
38 38
39 39
40 #region IAsyncResult Members 40 #region IAsyncResult Members
41 41
42 public object AsyncState 42 public object AsyncState
43 { 43 {
44 get { return m_asyncState; } 44 get { return m_asyncState; }
45 } 45 }
46 46
47 47
48 48
49 public WaitHandle AsyncWaitHandle 49 public WaitHandle AsyncWaitHandle
50 { 50 {
51 get 51 get
52 { 52 {
53 if (m_waitHandle == null) 53 if (m_waitHandle == null)
54 { 54 {
55 bool done = IsCompleted; 55 bool done = IsCompleted;
56 ManualResetEvent mre = new ManualResetEvent(done); 56 ManualResetEvent mre = new ManualResetEvent(done);
57 if (Interlocked.CompareExchange(ref m_waitHandle, mre, null) != null) 57 if (Interlocked.CompareExchange(ref m_waitHandle, mre, null) != null)
58 { 58 {
59 mre.Close(); 59 mre.Close();
60 } 60 }
61 else 61 else
62 { 62 {
63 if (!done && IsCompleted) 63 if (!done && IsCompleted)
64 { 64 {
65 m_waitHandle.Set(); 65 m_waitHandle.Set();
66 } 66 }
67 } 67 }
68 } 68 }
69 return m_waitHandle; 69 return m_waitHandle;
70 } 70 }
71 } 71 }
72 72
73 73
74 public bool CompletedSynchronously 74 public bool CompletedSynchronously
75 { 75 {
76 get { return Thread.VolatileRead(ref m_completedSynchronously) == 1; } 76 get { return Thread.VolatileRead(ref m_completedSynchronously) == 1; }
77 } 77 }
78 78
79 79
80 public bool IsCompleted 80 public bool IsCompleted
81 { 81 {
82 get { return Thread.VolatileRead(ref m_completed) == 1; } 82 get { return Thread.VolatileRead(ref m_completed) == 1; }
83 } 83 }
84 84
85 85
86 #endregion 86 #endregion
87 87
88 88
89 #region class Methods 89 #region class Methods
90 internal void SetAsCompleted(bool completedSynchronously) 90 internal void SetAsCompleted(bool completedSynchronously)
91 { 91 {
92 m_completed = 1; 92 m_completed = 1;
93 if(completedSynchronously) 93 if(completedSynchronously)
94 m_completedSynchronously = 1; 94 m_completedSynchronously = 1;
95 else 95 else
96 m_completedSynchronously = 0; 96 m_completedSynchronously = 0;
97 97
98 SignalCompletion(); 98 SignalCompletion();
99 } 99 }
100 100
101 internal void HandleException(Exception e, bool completedSynchronously) 101 internal void HandleException(Exception e, bool completedSynchronously)
102 { 102 {
103 m_completed = 1; 103 m_completed = 1;
104 if (completedSynchronously) 104 if (completedSynchronously)
105 m_completedSynchronously = 1; 105 m_completedSynchronously = 1;
106 else 106 else
107 m_completedSynchronously = 0; 107 m_completedSynchronously = 0;
108 m_exception = e; 108 m_exception = e;
109 109
110 SignalCompletion(); 110 SignalCompletion();
111 } 111 }
112 112
113 private void SignalCompletion() 113 private void SignalCompletion()
114 { 114 {
115 if(m_waitHandle != null) m_waitHandle.Set(); 115 if(m_waitHandle != null) m_waitHandle.Set();
116 116
117 if(m_callback != null) m_callback(this); 117 if(m_callback != null) m_callback(this);
118 } 118 }
119 119
120 public void EndInvoke() 120 public void EndInvoke()
121 { 121 {
122 // This method assumes that only 1 thread calls EndInvoke 122 // This method assumes that only 1 thread calls EndInvoke
123 if (!IsCompleted) 123 if (!IsCompleted)
124 { 124 {
125 // If the operation isn't done, wait for it 125 // If the operation isn't done, wait for it
126 AsyncWaitHandle.WaitOne(); 126 AsyncWaitHandle.WaitOne();
127 AsyncWaitHandle.Close(); 127 AsyncWaitHandle.Close();
128 m_waitHandle = null; // Allow early GC 128 m_waitHandle = null; // Allow early GC
129 } 129 }
130 130
131 // Operation is done: if an exception occured, throw it 131 // Operation is done: if an exception occured, throw it
132 if (m_exception != null) throw m_exception; 132 if (m_exception != null) throw m_exception;
133 } 133 }
134 134
135 #endregion 135 #endregion
136 } 136 }
137 137
138 internal class AsyncResult<T> : SimpleAsyncResult 138 internal class AsyncResult<T> : SimpleAsyncResult
139 { 139 {
140 private T m_result = default(T); 140 private T m_result = default(T);
141 141
142 public AsyncResult(AsyncCallback asyncCallback, Object state) : 142 public AsyncResult(AsyncCallback asyncCallback, Object state) :
143 base(asyncCallback, state) { } 143 base(asyncCallback, state) { }
144 144
145 145
146 public void SetAsCompleted(T result, bool completedSynchronously) 146 public void SetAsCompleted(T result, bool completedSynchronously)
147 { 147 {
148 // Save the asynchronous operation's result 148 // Save the asynchronous operation's result
149 m_result = result; 149 m_result = result;
150 150
151 // Tell the base class that the operation completed 151 // Tell the base class that the operation completed
152 // sucessfully (no exception) 152 // sucessfully (no exception)
153 base.SetAsCompleted(completedSynchronously); 153 base.SetAsCompleted(completedSynchronously);
154 } 154 }
155 155
156 new public T EndInvoke() 156 new public T EndInvoke()
157 { 157 {
158 base.EndInvoke(); 158 base.EndInvoke();
159 return m_result; 159 return m_result;
160 } 160 }
161 161
162 } 162 }
163} 163}
diff --git a/OpenSim/Framework/Communications/RestClient/RestClient.cs b/OpenSim/Framework/Communications/RestClient/RestClient.cs
index ccf8376..25fc61a 100644
--- a/OpenSim/Framework/Communications/RestClient/RestClient.cs
+++ b/OpenSim/Framework/Communications/RestClient/RestClient.cs
@@ -1,328 +1,328 @@
1using System; 1using System;
2using System.IO; 2using System.IO;
3using System.Net; 3using System.Net;
4using System.Web; 4using System.Web;
5using System.Text; 5using System.Text;
6using System.Collections.Generic; 6using System.Collections.Generic;
7using System.Threading; 7using System.Threading;
8 8
9namespace OpenSim.Framework.RestClient 9namespace OpenSim.Framework.RestClient
10{ 10{
11 /// <summary> 11 /// <summary>
12 /// Implementation of a generic REST client 12 /// Implementation of a generic REST client
13 /// </summary> 13 /// </summary>
14 /// <remarks> 14 /// <remarks>
15 /// This class is a generic implementation of a REST (Representational State Transfer) web service. This 15 /// This class is a generic implementation of a REST (Representational State Transfer) web service. This
16 /// class is designed to execute both synchroneously and asynchroneously. 16 /// class is designed to execute both synchroneously and asynchroneously.
17 /// 17 ///
18 /// Internally the implementation works as a two stage asynchroneous web-client. 18 /// Internally the implementation works as a two stage asynchroneous web-client.
19 /// When the request is initiated, RestClient will query asynchroneously for for a web-response, 19 /// When the request is initiated, RestClient will query asynchroneously for for a web-response,
20 /// sleeping until the initial response is returned by the server. Once the initial response is retrieved 20 /// sleeping until the initial response is returned by the server. Once the initial response is retrieved
21 /// the second stage of asynchroneous requests will be triggered, in an attempt to read of the response 21 /// the second stage of asynchroneous requests will be triggered, in an attempt to read of the response
22 /// object into a memorystream as a sequence of asynchroneous reads. 22 /// object into a memorystream as a sequence of asynchroneous reads.
23 /// 23 ///
24 /// The asynchronisity of RestClient is designed to move as much processing into the back-ground, allowing 24 /// The asynchronisity of RestClient is designed to move as much processing into the back-ground, allowing
25 /// other threads to execute, while it waits for a response from the web-service. RestClient it self, can be 25 /// other threads to execute, while it waits for a response from the web-service. RestClient it self, can be
26 /// invoked by the caller in either synchroneous mode or asynchroneous mode. 26 /// invoked by the caller in either synchroneous mode or asynchroneous mode.
27 /// </remarks> 27 /// </remarks>
28 public class RestClient 28 public class RestClient
29 { 29 {
30 /// <summary> 30 /// <summary>
31 /// The base Uri of the web-service e.g. http://www.google.com 31 /// The base Uri of the web-service e.g. http://www.google.com
32 /// </summary> 32 /// </summary>
33 private string _url; 33 private string _url;
34 34
35 /// <summary> 35 /// <summary>
36 /// Path elements of the query 36 /// Path elements of the query
37 /// </summary> 37 /// </summary>
38 private List<string> _pathElements = new List<string>(); 38 private List<string> _pathElements = new List<string>();
39 39
40 /// <summary> 40 /// <summary>
41 /// Parameter elements of the query, e.g. min=34 41 /// Parameter elements of the query, e.g. min=34
42 /// </summary> 42 /// </summary>
43 private Dictionary<string, string> _parameterElements = new Dictionary<string, string>(); 43 private Dictionary<string, string> _parameterElements = new Dictionary<string, string>();
44 44
45 /// <summary> 45 /// <summary>
46 /// Request method. E.g. GET, POST, PUT or DELETE 46 /// Request method. E.g. GET, POST, PUT or DELETE
47 /// </summary> 47 /// </summary>
48 private string _method; 48 private string _method;
49 49
50 /// <summary> 50 /// <summary>
51 /// Temporary buffer used to store bytes temporarily as they come in from the server 51 /// Temporary buffer used to store bytes temporarily as they come in from the server
52 /// </summary> 52 /// </summary>
53 private byte[] _readbuf; 53 private byte[] _readbuf;
54 54
55 /// <summary> 55 /// <summary>
56 /// MemoryStream representing the resultiong resource 56 /// MemoryStream representing the resultiong resource
57 /// </summary> 57 /// </summary>
58 MemoryStream _resource; 58 MemoryStream _resource;
59 59
60 /// <summary> 60 /// <summary>
61 /// WebRequest object, held as a member variable 61 /// WebRequest object, held as a member variable
62 /// </summary> 62 /// </summary>
63 private HttpWebRequest _request; 63 private HttpWebRequest _request;
64 64
65 /// <summary> 65 /// <summary>
66 /// WebResponse object, held as a member variable, so we can close it 66 /// WebResponse object, held as a member variable, so we can close it
67 /// </summary> 67 /// </summary>
68 private HttpWebResponse _response; 68 private HttpWebResponse _response;
69 69
70 /// <summary> 70 /// <summary>
71 /// This flag will help block the main synchroneous method, in case we run in synchroneous mode 71 /// This flag will help block the main synchroneous method, in case we run in synchroneous mode
72 /// </summary> 72 /// </summary>
73 public static ManualResetEvent _allDone = new ManualResetEvent(false); 73 public static ManualResetEvent _allDone = new ManualResetEvent(false);
74 74
75 /// <summary> 75 /// <summary>
76 /// Default time out period 76 /// Default time out period
77 /// </summary> 77 /// </summary>
78 const int DefaultTimeout = 10 * 1000; // 10 seconds timeout 78 const int DefaultTimeout = 10 * 1000; // 10 seconds timeout
79 79
80 /// <summary> 80 /// <summary>
81 /// Default Buffer size of a block requested from the web-server 81 /// Default Buffer size of a block requested from the web-server
82 /// </summary> 82 /// </summary>
83 const int BufferSize = 4096; // Read blocks of 4 KB. 83 const int BufferSize = 4096; // Read blocks of 4 KB.
84 84
85 85
86 /// <summary> 86 /// <summary>
87 /// if an exception occours during async processing, we need to save it, so it can be 87 /// if an exception occours during async processing, we need to save it, so it can be
88 /// rethrown on the primary thread; 88 /// rethrown on the primary thread;
89 /// </summary> 89 /// </summary>
90 private Exception _asyncException; 90 private Exception _asyncException;
91 91
92 /// <summary> 92 /// <summary>
93 /// Instantiate a new RestClient 93 /// Instantiate a new RestClient
94 /// </summary> 94 /// </summary>
95 /// <param name="url">Web-service to query, e.g. http://osgrid.org:8003</param> 95 /// <param name="url">Web-service to query, e.g. http://osgrid.org:8003</param>
96 public RestClient(string url) 96 public RestClient(string url)
97 { 97 {
98 _url = url; 98 _url = url;
99 _readbuf = new byte[BufferSize]; 99 _readbuf = new byte[BufferSize];
100 _resource = new MemoryStream(); 100 _resource = new MemoryStream();
101 _request = null; 101 _request = null;
102 _response = null; 102 _response = null;
103 } 103 }
104 104
105 /// <summary> 105 /// <summary>
106 /// Add a path element to the query, e.g. assets 106 /// Add a path element to the query, e.g. assets
107 /// </summary> 107 /// </summary>
108 /// <param name="element">path entry</param> 108 /// <param name="element">path entry</param>
109 public void AddResourcePath(string element) 109 public void AddResourcePath(string element)
110 { 110 {
111 if(isSlashed(element)) 111 if(isSlashed(element))
112 _pathElements.Add(element.Substring(0, element.Length-1)); 112 _pathElements.Add(element.Substring(0, element.Length-1));
113 else 113 else
114 _pathElements.Add(element); 114 _pathElements.Add(element);
115 } 115 }
116 116
117 /// <summary> 117 /// <summary>
118 /// Add a query parameter to the Url 118 /// Add a query parameter to the Url
119 /// </summary> 119 /// </summary>
120 /// <param name="name">Name of the parameter, e.g. min</param> 120 /// <param name="name">Name of the parameter, e.g. min</param>
121 /// <param name="value">Value of the parameter, e.g. 42</param> 121 /// <param name="value">Value of the parameter, e.g. 42</param>
122 public void AddQueryParameter(string name, string value) 122 public void AddQueryParameter(string name, string value)
123 { 123 {
124 _parameterElements.Add(HttpUtility.UrlEncode(name), HttpUtility.UrlEncode(value)); 124 _parameterElements.Add(HttpUtility.UrlEncode(name), HttpUtility.UrlEncode(value));
125 } 125 }
126 126
127 /// <summary> 127 /// <summary>
128 /// Web-Request method, e.g. GET, PUT, POST, DELETE 128 /// Web-Request method, e.g. GET, PUT, POST, DELETE
129 /// </summary> 129 /// </summary>
130 public string RequestMethod 130 public string RequestMethod
131 { 131 {
132 get { return _method; } 132 get { return _method; }
133 set { _method = value; } 133 set { _method = value; }
134 } 134 }
135 135
136 /// <summary> 136 /// <summary>
137 /// True if string contains a trailing slash '/' 137 /// True if string contains a trailing slash '/'
138 /// </summary> 138 /// </summary>
139 /// <param name="s">string to be examined</param> 139 /// <param name="s">string to be examined</param>
140 /// <returns>true if slash is present</returns> 140 /// <returns>true if slash is present</returns>
141 private bool isSlashed(string s) 141 private bool isSlashed(string s)
142 { 142 {
143 return s.Substring(s.Length - 1, 1) == "/"; 143 return s.Substring(s.Length - 1, 1) == "/";
144 } 144 }
145 145
146 /// <summary> 146 /// <summary>
147 /// return a slash or blank. A slash will be returned if the string does not contain one 147 /// return a slash or blank. A slash will be returned if the string does not contain one
148 /// </summary> 148 /// </summary>
149 /// <param name="s">stromg to be examined</param> 149 /// <param name="s">stromg to be examined</param>
150 /// <returns>slash '/' if not already present</returns> 150 /// <returns>slash '/' if not already present</returns>
151 private string slash(string s) 151 private string slash(string s)
152 { 152 {
153 return isSlashed(s) ? "" : "/"; 153 return isSlashed(s) ? "" : "/";
154 } 154 }
155 155
156 /// <summary> 156 /// <summary>
157 /// Build a Uri based on the intial Url, path elements and parameters 157 /// Build a Uri based on the intial Url, path elements and parameters
158 /// </summary> 158 /// </summary>
159 /// <returns>fully constructed Uri</returns> 159 /// <returns>fully constructed Uri</returns>
160 Uri buildUri() 160 Uri buildUri()
161 { 161 {
162 StringBuilder sb = new StringBuilder(); 162 StringBuilder sb = new StringBuilder();
163 sb.Append(_url); 163 sb.Append(_url);
164 164
165 foreach (string e in _pathElements) 165 foreach (string e in _pathElements)
166 { 166 {
167 sb.Append("/"); 167 sb.Append("/");
168 sb.Append(e); 168 sb.Append(e);
169 } 169 }
170 170
171 bool firstElement = true; 171 bool firstElement = true;
172 foreach (KeyValuePair<string, string> kv in _parameterElements) 172 foreach (KeyValuePair<string, string> kv in _parameterElements)
173 { 173 {
174 if (firstElement) 174 if (firstElement)
175 { 175 {
176 sb.Append("?"); 176 sb.Append("?");
177 firstElement = false; 177 firstElement = false;
178 } else 178 } else
179 sb.Append("&"); 179 sb.Append("&");
180 180
181 sb.Append(kv.Key); 181 sb.Append(kv.Key);
182 if (kv.Value != null && kv.Value.Length != 0) 182 if (kv.Value != null && kv.Value.Length != 0)
183 { 183 {
184 sb.Append("="); 184 sb.Append("=");
185 sb.Append(kv.Value); 185 sb.Append(kv.Value);
186 } 186 }
187 } 187 }
188 return new Uri(sb.ToString()); 188 return new Uri(sb.ToString());
189 } 189 }
190 190
191 /// <summary> 191 /// <summary>
192 /// Async method, invoked when a block of data has been received from the service 192 /// Async method, invoked when a block of data has been received from the service
193 /// </summary> 193 /// </summary>
194 /// <param name="ar"></param> 194 /// <param name="ar"></param>
195 private void StreamIsReadyDelegate(IAsyncResult ar) 195 private void StreamIsReadyDelegate(IAsyncResult ar)
196 { 196 {
197 try 197 try
198 { 198 {
199 Stream s = (Stream)ar.AsyncState; 199 Stream s = (Stream)ar.AsyncState;
200 int read = s.EndRead(ar); 200 int read = s.EndRead(ar);
201 201
202 // Read the HTML page and then print it to the console. 202 // Read the HTML page and then print it to the console.
203 if (read > 0) 203 if (read > 0)
204 { 204 {
205 _resource.Write(_readbuf, 0, read); 205 _resource.Write(_readbuf, 0, read);
206 IAsyncResult asynchronousResult = s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s); 206 IAsyncResult asynchronousResult = s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s);
207 207
208 // TODO! Implement timeout, without killing the server 208 // TODO! Implement timeout, without killing the server
209 //ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); 209 //ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
210 return; 210 return;
211 } 211 }
212 else 212 else
213 { 213 {
214 s.Close(); 214 s.Close();
215 _allDone.Set(); 215 _allDone.Set();
216 } 216 }
217 } 217 }
218 catch (Exception e) 218 catch (Exception e)
219 { 219 {
220 _allDone.Set(); 220 _allDone.Set();
221 _asyncException = e; 221 _asyncException = e;
222 } 222 }
223 } 223 }
224 224
225 /// <summary> 225 /// <summary>
226 /// Async method, invoked when the intial response if received from the server 226 /// Async method, invoked when the intial response if received from the server
227 /// </summary> 227 /// </summary>
228 /// <param name="ar"></param> 228 /// <param name="ar"></param>
229 private void ResponseIsReadyDelegate(IAsyncResult ar) 229 private void ResponseIsReadyDelegate(IAsyncResult ar)
230 { 230 {
231 try 231 try
232 { 232 {
233 // grab response 233 // grab response
234 WebRequest wr = (WebRequest)ar.AsyncState; 234 WebRequest wr = (WebRequest)ar.AsyncState;
235 _response = (HttpWebResponse)wr.EndGetResponse(ar); 235 _response = (HttpWebResponse)wr.EndGetResponse(ar);
236 236
237 // get response stream, and setup async reading 237 // get response stream, and setup async reading
238 Stream s = _response.GetResponseStream(); 238 Stream s = _response.GetResponseStream();
239 IAsyncResult asynchronousResult = s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s); 239 IAsyncResult asynchronousResult = s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s);
240 240
241 // TODO! Implement timeout, without killing the server 241 // TODO! Implement timeout, without killing the server
242 // wait until completed, or we timed out 242 // wait until completed, or we timed out
243 // ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); 243 // ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
244 } 244 }
245 catch (Exception e) 245 catch (Exception e)
246 { 246 {
247 _allDone.Set(); 247 _allDone.Set();
248 _asyncException = e; 248 _asyncException = e;
249 } 249 }
250 } 250 }
251 251
252 // Abort the request if the timer fires. 252 // Abort the request if the timer fires.
253 private static void TimeoutCallback(object state, bool timedOut) 253 private static void TimeoutCallback(object state, bool timedOut)
254 { 254 {
255 if (timedOut) 255 if (timedOut)
256 { 256 {
257 HttpWebRequest request = state as HttpWebRequest; 257 HttpWebRequest request = state as HttpWebRequest;
258 if (request != null) 258 if (request != null)
259 { 259 {
260 request.Abort(); 260 request.Abort();
261 } 261 }
262 } 262 }
263 } 263 }
264 264
265 /// <summary> 265 /// <summary>
266 /// Perform synchroneous request 266 /// Perform synchroneous request
267 /// </summary> 267 /// </summary>
268 public Stream Request() 268 public Stream Request()
269 { 269 {
270 _request = (HttpWebRequest)WebRequest.Create(buildUri()); 270 _request = (HttpWebRequest)WebRequest.Create(buildUri());
271 _request.KeepAlive = false; 271 _request.KeepAlive = false;
272 _request.ContentType = "text/html"; 272 _request.ContentType = "text/html";
273 _request.Timeout = 200; 273 _request.Timeout = 200;
274 _asyncException = null; 274 _asyncException = null;
275 275
276 IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); 276 IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
277 277
278 // TODO! Implement timeout, without killing the server 278 // TODO! Implement timeout, without killing the server
279 // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted 279 // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
280 //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); 280 //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
281 281
282 _allDone.WaitOne(); 282 _allDone.WaitOne();
283 if(_response != null) 283 if(_response != null)
284 _response.Close(); 284 _response.Close();
285 if (_asyncException != null) 285 if (_asyncException != null)
286 throw _asyncException; 286 throw _asyncException;
287 return _resource; 287 return _resource;
288 } 288 }
289 289
290 #region Async Invocation 290 #region Async Invocation
291 public IAsyncResult BeginRequest(AsyncCallback callback, object state) 291 public IAsyncResult BeginRequest(AsyncCallback callback, object state)
292 { 292 {
293 /// <summary> 293 /// <summary>
294 /// In case, we are invoked asynchroneously this object will keep track of the state 294 /// In case, we are invoked asynchroneously this object will keep track of the state
295 /// </summary> 295 /// </summary>
296 AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state); 296 AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state);
297 ThreadPool.QueueUserWorkItem(RequestHelper, ar); 297 ThreadPool.QueueUserWorkItem(RequestHelper, ar);
298 return ar; 298 return ar;
299 } 299 }
300 300
301 public Stream EndRequest(IAsyncResult asyncResult) 301 public Stream EndRequest(IAsyncResult asyncResult)
302 { 302 {
303 AsyncResult<Stream> ar = (AsyncResult<Stream>)asyncResult; 303 AsyncResult<Stream> ar = (AsyncResult<Stream>)asyncResult;
304 304
305 // Wait for operation to complete, then return result or 305 // Wait for operation to complete, then return result or
306 // throw exception 306 // throw exception
307 return ar.EndInvoke(); 307 return ar.EndInvoke();
308 } 308 }
309 309
310 private void RequestHelper(Object asyncResult) 310 private void RequestHelper(Object asyncResult)
311 { 311 {
312 // We know that it's really an AsyncResult<DateTime> object 312 // We know that it's really an AsyncResult<DateTime> object
313 AsyncResult<Stream> ar = (AsyncResult<Stream>)asyncResult; 313 AsyncResult<Stream> ar = (AsyncResult<Stream>)asyncResult;
314 try 314 try
315 { 315 {
316 // Perform the operation; if sucessful set the result 316 // Perform the operation; if sucessful set the result
317 Stream s = Request(); 317 Stream s = Request();
318 ar.SetAsCompleted(s, false); 318 ar.SetAsCompleted(s, false);
319 } 319 }
320 catch (Exception e) 320 catch (Exception e)
321 { 321 {
322 // If operation fails, set the exception 322 // If operation fails, set the exception
323 ar.HandleException(e, false); 323 ar.HandleException(e, false);
324 } 324 }
325 } 325 }
326 #endregion Async Invocation 326 #endregion Async Invocation
327 } 327 }
328} 328}