diff options
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r-- | OpenSim/Framework/WebUtil.cs | 168 |
1 files changed, 165 insertions, 3 deletions
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 1c856af..1cd9054 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs | |||
@@ -50,6 +50,8 @@ namespace OpenSim.Framework | |||
50 | LogManager.GetLogger( | 50 | LogManager.GetLogger( |
51 | MethodBase.GetCurrentMethod().DeclaringType); | 51 | MethodBase.GetCurrentMethod().DeclaringType); |
52 | 52 | ||
53 | private static int m_requestNumber = 0; | ||
54 | |||
53 | /// <summary> | 55 | /// <summary> |
54 | /// Send LLSD to an HTTP client in application/llsd+json form | 56 | /// Send LLSD to an HTTP client in application/llsd+json form |
55 | /// </summary> | 57 | /// </summary> |
@@ -123,12 +125,145 @@ namespace OpenSim.Framework | |||
123 | } | 125 | } |
124 | 126 | ||
125 | /// <summary> | 127 | /// <summary> |
128 | /// PUT JSON-encoded data to a web service that returns LLSD or | ||
129 | /// JSON data | ||
130 | /// </summary> | ||
131 | public static OSDMap PutToService(string url, OSDMap data) | ||
132 | { | ||
133 | return ServiceOSDRequest(url,data,"PUT",10000); | ||
134 | } | ||
135 | |||
136 | public static OSDMap PostToService(string url, OSDMap data) | ||
137 | { | ||
138 | return ServiceOSDRequest(url,data,"POST",10000); | ||
139 | } | ||
140 | |||
141 | public static OSDMap GetFromService(string url) | ||
142 | { | ||
143 | return ServiceOSDRequest(url,null,"GET",10000); | ||
144 | } | ||
145 | |||
146 | public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout) | ||
147 | { | ||
148 | int reqnum = m_requestNumber++; | ||
149 | m_log.WarnFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | ||
150 | |||
151 | string errorMessage = "unknown error"; | ||
152 | int tickstart = Util.EnvironmentTickCount(); | ||
153 | try | ||
154 | { | ||
155 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); | ||
156 | request.Method = method; | ||
157 | request.Timeout = timeout; | ||
158 | //request.KeepAlive = false; | ||
159 | |||
160 | // If there is some input, write it into the request | ||
161 | if (data != null) | ||
162 | { | ||
163 | string strBuffer = OSDParser.SerializeJsonString(data); | ||
164 | byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); | ||
165 | |||
166 | request.ContentType = "application/json"; | ||
167 | request.ContentLength = buffer.Length; //Count bytes to send | ||
168 | using (Stream requestStream = request.GetRequestStream()) | ||
169 | { | ||
170 | requestStream.Write(buffer, 0, strBuffer.Length); //Send it | ||
171 | } | ||
172 | } | ||
173 | |||
174 | using (WebResponse webResponse = request.GetResponse()) | ||
175 | { | ||
176 | using (Stream responseStream = webResponse.GetResponseStream()) | ||
177 | { | ||
178 | string responseStr = null; | ||
179 | responseStr = responseStream.GetStreamString(); | ||
180 | m_log.WarnFormat("[WEB UTIL]: <{0}> response is <{1}>",reqnum,responseStr); | ||
181 | return CanonicalizeResults(responseStr); | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | catch (WebException we) | ||
186 | { | ||
187 | errorMessage = we.Message; | ||
188 | if (we.Status == WebExceptionStatus.ProtocolError) | ||
189 | { | ||
190 | HttpWebResponse webResponse = (HttpWebResponse)we.Response; | ||
191 | errorMessage = String.Format("[{0}] {1}",webResponse.StatusCode,webResponse.StatusDescription); | ||
192 | } | ||
193 | } | ||
194 | catch (Exception ex) | ||
195 | { | ||
196 | errorMessage = ex.Message; | ||
197 | } | ||
198 | finally | ||
199 | { | ||
200 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | ||
201 | if (tickdiff > 100) | ||
202 | m_log.WarnFormat("[WEB UTIL]: request <{0}> took {1} milliseconds",reqnum,tickdiff); | ||
203 | } | ||
204 | |||
205 | m_log.WarnFormat("[WEB UTIL] <{0}> request failed: {1}",reqnum,errorMessage); | ||
206 | return ErrorResponseMap(errorMessage); | ||
207 | } | ||
208 | |||
209 | /// <summary> | ||
210 | /// Since there are no consistencies in the way web requests are | ||
211 | /// formed, we need to do a little guessing about the result format. | ||
212 | /// Keys: | ||
213 | /// Success|success == the success fail of the request | ||
214 | /// _RawResult == the raw string that came back | ||
215 | /// _Result == the OSD unpacked string | ||
216 | /// </summary> | ||
217 | private static OSDMap CanonicalizeResults(string response) | ||
218 | { | ||
219 | OSDMap result = new OSDMap(); | ||
220 | |||
221 | // Default values | ||
222 | result["Success"] = OSD.FromBoolean(true); | ||
223 | result["success"] = OSD.FromBoolean(true); | ||
224 | result["_RawResult"] = OSD.FromString(response); | ||
225 | result["_Result"] = new OSDMap(); | ||
226 | |||
227 | if (response.Equals("true",System.StringComparison.OrdinalIgnoreCase)) | ||
228 | return result; | ||
229 | |||
230 | if (response.Equals("false",System.StringComparison.OrdinalIgnoreCase)) | ||
231 | { | ||
232 | result["Success"] = OSD.FromBoolean(false); | ||
233 | result["success"] = OSD.FromBoolean(false); | ||
234 | return result; | ||
235 | } | ||
236 | |||
237 | try | ||
238 | { | ||
239 | OSD responseOSD = OSDParser.Deserialize(response); | ||
240 | if (responseOSD.Type == OSDType.Map) | ||
241 | { | ||
242 | result["_Result"] = (OSDMap)responseOSD; | ||
243 | return result; | ||
244 | } | ||
245 | } | ||
246 | catch (Exception e) | ||
247 | { | ||
248 | // don't need to treat this as an error... we're just guessing anyway | ||
249 | m_log.DebugFormat("[WEB UTIL] couldn't decode result: <{0}>",response); | ||
250 | } | ||
251 | |||
252 | return result; | ||
253 | } | ||
254 | |||
255 | /// <summary> | ||
126 | /// POST URL-encoded form data to a web service that returns LLSD or | 256 | /// POST URL-encoded form data to a web service that returns LLSD or |
127 | /// JSON data | 257 | /// JSON data |
128 | /// </summary> | 258 | /// </summary> |
129 | public static OSDMap PostToService(string url, NameValueCollection data) | 259 | public static OSDMap PostToService(string url, NameValueCollection data) |
130 | { | 260 | { |
261 | int reqnum = m_requestNumber++; | ||
262 | string method = data["RequestMethod"] != null ? data["RequestMethod"] : "unknown"; | ||
263 | m_log.WarnFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method); | ||
264 | |||
131 | string errorMessage; | 265 | string errorMessage; |
266 | int tickstart = Util.EnvironmentTickCount(); | ||
132 | 267 | ||
133 | try | 268 | try |
134 | { | 269 | { |
@@ -139,7 +274,7 @@ namespace OpenSim.Framework | |||
139 | request.Method = "POST"; | 274 | request.Method = "POST"; |
140 | request.ContentLength = requestData.Length; | 275 | request.ContentLength = requestData.Length; |
141 | request.ContentType = "application/x-www-form-urlencoded"; | 276 | request.ContentType = "application/x-www-form-urlencoded"; |
142 | 277 | ||
143 | Stream requestStream = request.GetRequestStream(); | 278 | Stream requestStream = request.GetRequestStream(); |
144 | requestStream.Write(requestData, 0, requestData.Length); | 279 | requestStream.Write(requestData, 0, requestData.Length); |
145 | requestStream.Close(); | 280 | requestStream.Close(); |
@@ -169,15 +304,42 @@ namespace OpenSim.Framework | |||
169 | } | 304 | } |
170 | } | 305 | } |
171 | } | 306 | } |
307 | catch (WebException we) | ||
308 | { | ||
309 | errorMessage = we.Message; | ||
310 | if (we.Status == WebExceptionStatus.ProtocolError) | ||
311 | { | ||
312 | HttpWebResponse webResponse = (HttpWebResponse)we.Response; | ||
313 | errorMessage = String.Format("[{0}] {1}",webResponse.StatusCode,webResponse.StatusDescription); | ||
314 | } | ||
315 | } | ||
172 | catch (Exception ex) | 316 | catch (Exception ex) |
173 | { | 317 | { |
174 | m_log.Warn("POST to URL " + url + " failed: " + ex); | ||
175 | errorMessage = ex.Message; | 318 | errorMessage = ex.Message; |
176 | } | 319 | } |
320 | finally | ||
321 | { | ||
322 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | ||
323 | if (tickdiff > 100) | ||
324 | m_log.WarnFormat("[WEB UTIL]: request <{0}> took {1} milliseconds",reqnum,tickdiff); | ||
325 | } | ||
177 | 326 | ||
178 | return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } }; | 327 | m_log.WarnFormat("[WEB UTIL]: <{0}> request failed: {1}",reqnum,errorMessage); |
328 | return ErrorResponseMap(errorMessage); | ||
179 | } | 329 | } |
180 | 330 | ||
331 | /// <summary> | ||
332 | /// Create a response map for an error, trying to keep | ||
333 | /// the result formats consistent | ||
334 | /// </summary> | ||
335 | private static OSDMap ErrorResponseMap(string msg) | ||
336 | { | ||
337 | OSDMap result = new OSDMap(); | ||
338 | result["Success"] = "False"; | ||
339 | result["Message"] = OSD.FromString("Service request failed: " + msg); | ||
340 | return result; | ||
341 | } | ||
342 | |||
181 | #region Uri | 343 | #region Uri |
182 | 344 | ||
183 | /// <summary> | 345 | /// <summary> |