diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/WebUtil.cs | 220 |
1 files changed, 102 insertions, 118 deletions
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index b180c8a..20d30b5 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs | |||
@@ -72,11 +72,6 @@ namespace OpenSim.Framework | |||
72 | public static int RequestNumber { get; set; } | 72 | public static int RequestNumber { get; set; } |
73 | 73 | ||
74 | /// <summary> | 74 | /// <summary> |
75 | /// Control where OSD requests should be serialized per endpoint. | ||
76 | /// </summary> | ||
77 | public static bool SerializeOSDRequestsPerEndpoint { get; set; } | ||
78 | |||
79 | /// <summary> | ||
80 | /// this is the header field used to communicate the local request id | 75 | /// this is the header field used to communicate the local request id |
81 | /// used for performance and debugging | 76 | /// used for performance and debugging |
82 | /// </summary> | 77 | /// </summary> |
@@ -98,31 +93,6 @@ namespace OpenSim.Framework | |||
98 | /// </remarks> | 93 | /// </remarks> |
99 | public const int MaxRequestDiagLength = 200; | 94 | public const int MaxRequestDiagLength = 200; |
100 | 95 | ||
101 | /// <summary> | ||
102 | /// Dictionary of end points | ||
103 | /// </summary> | ||
104 | private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>(); | ||
105 | |||
106 | private static object EndPointLock(string url) | ||
107 | { | ||
108 | System.Uri uri = new System.Uri(url); | ||
109 | string endpoint = string.Format("{0}:{1}",uri.Host,uri.Port); | ||
110 | |||
111 | lock (m_endpointSerializer) | ||
112 | { | ||
113 | object eplock = null; | ||
114 | |||
115 | if (! m_endpointSerializer.TryGetValue(endpoint,out eplock)) | ||
116 | { | ||
117 | eplock = new object(); | ||
118 | m_endpointSerializer.Add(endpoint,eplock); | ||
119 | // m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint); | ||
120 | } | ||
121 | |||
122 | return eplock; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | #region JSONRequest | 96 | #region JSONRequest |
127 | 97 | ||
128 | /// <summary> | 98 | /// <summary> |
@@ -154,21 +124,6 @@ namespace OpenSim.Framework | |||
154 | return ServiceOSDRequest(url, null, "GET", timeout, false, false); | 124 | return ServiceOSDRequest(url, null, "GET", timeout, false, false); |
155 | } | 125 | } |
156 | 126 | ||
157 | public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) | ||
158 | { | ||
159 | if (SerializeOSDRequestsPerEndpoint) | ||
160 | { | ||
161 | lock (EndPointLock(url)) | ||
162 | { | ||
163 | return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc); | ||
164 | } | ||
165 | } | ||
166 | else | ||
167 | { | ||
168 | return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | public static void LogOutgoingDetail(Stream outputStream) | 127 | public static void LogOutgoingDetail(Stream outputStream) |
173 | { | 128 | { |
174 | LogOutgoingDetail("", outputStream); | 129 | LogOutgoingDetail("", outputStream); |
@@ -222,7 +177,7 @@ namespace OpenSim.Framework | |||
222 | LogOutgoingDetail(string.Format("RESPONSE {0}: ", reqnum), input); | 177 | LogOutgoingDetail(string.Format("RESPONSE {0}: ", reqnum), input); |
223 | } | 178 | } |
224 | 179 | ||
225 | private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) | 180 | public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) |
226 | { | 181 | { |
227 | int reqnum = RequestNumber++; | 182 | int reqnum = RequestNumber++; |
228 | 183 | ||
@@ -233,6 +188,9 @@ namespace OpenSim.Framework | |||
233 | string errorMessage = "unknown error"; | 188 | string errorMessage = "unknown error"; |
234 | int tickstart = Util.EnvironmentTickCount(); | 189 | int tickstart = Util.EnvironmentTickCount(); |
235 | int tickdata = 0; | 190 | int tickdata = 0; |
191 | int tickcompressdata = 0; | ||
192 | int tickJsondata = 0; | ||
193 | int compsize = 0; | ||
236 | string strBuffer = null; | 194 | string strBuffer = null; |
237 | 195 | ||
238 | try | 196 | try |
@@ -242,21 +200,23 @@ namespace OpenSim.Framework | |||
242 | request.Timeout = timeout; | 200 | request.Timeout = timeout; |
243 | request.KeepAlive = false; | 201 | request.KeepAlive = false; |
244 | request.MaximumAutomaticRedirections = 10; | 202 | request.MaximumAutomaticRedirections = 10; |
245 | request.ReadWriteTimeout = timeout / 4; | 203 | request.ReadWriteTimeout = timeout / 2; |
246 | request.Headers[OSHeaderRequestID] = reqnum.ToString(); | 204 | request.Headers[OSHeaderRequestID] = reqnum.ToString(); |
247 | 205 | ||
248 | // If there is some input, write it into the request | 206 | // If there is some input, write it into the request |
249 | if (data != null) | 207 | if (data != null) |
250 | { | 208 | { |
251 | strBuffer = OSDParser.SerializeJsonString(data); | 209 | strBuffer = OSDParser.SerializeJsonString(data); |
252 | 210 | ||
211 | tickJsondata = Util.EnvironmentTickCountSubtract(tickstart); | ||
212 | |||
253 | if (DebugLevel >= 5) | 213 | if (DebugLevel >= 5) |
254 | LogOutgoingDetail("SEND", reqnum, strBuffer); | 214 | LogOutgoingDetail("SEND", reqnum, strBuffer); |
255 | 215 | ||
256 | byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); | 216 | byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); |
257 | 217 | ||
258 | request.ContentType = rpc ? "application/json-rpc" : "application/json"; | 218 | request.ContentType = rpc ? "application/json-rpc" : "application/json"; |
259 | 219 | ||
260 | if (compressed) | 220 | if (compressed) |
261 | { | 221 | { |
262 | request.Headers["X-Content-Encoding"] = "gzip"; // can't set "Content-Encoding" because old OpenSims fail if they get an unrecognized Content-Encoding | 222 | request.Headers["X-Content-Encoding"] = "gzip"; // can't set "Content-Encoding" because old OpenSims fail if they get an unrecognized Content-Encoding |
@@ -271,19 +231,25 @@ namespace OpenSim.Framework | |||
271 | // gets written on the stream upon Dispose() | 231 | // gets written on the stream upon Dispose() |
272 | } | 232 | } |
273 | byte[] buf = ms.ToArray(); | 233 | byte[] buf = ms.ToArray(); |
234 | |||
235 | tickcompressdata = Util.EnvironmentTickCountSubtract(tickstart); | ||
236 | |||
274 | request.ContentLength = buf.Length; //Count bytes to send | 237 | request.ContentLength = buf.Length; //Count bytes to send |
238 | compsize = buf.Length; | ||
275 | using (Stream requestStream = request.GetRequestStream()) | 239 | using (Stream requestStream = request.GetRequestStream()) |
276 | requestStream.Write(buf, 0, (int)buf.Length); | 240 | requestStream.Write(buf, 0, (int)buf.Length); |
277 | } | 241 | } |
278 | } | 242 | } |
279 | else | 243 | else |
280 | { | 244 | { |
245 | compsize = buffer.Length; | ||
246 | |||
281 | request.ContentLength = buffer.Length; //Count bytes to send | 247 | request.ContentLength = buffer.Length; //Count bytes to send |
282 | using (Stream requestStream = request.GetRequestStream()) | 248 | using (Stream requestStream = request.GetRequestStream()) |
283 | requestStream.Write(buffer, 0, buffer.Length); //Send it | 249 | requestStream.Write(buffer, 0, buffer.Length); //Send it |
284 | } | 250 | } |
285 | } | 251 | } |
286 | 252 | ||
287 | // capture how much time was spent writing, this may seem silly | 253 | // capture how much time was spent writing, this may seem silly |
288 | // but with the number concurrent requests, this often blocks | 254 | // but with the number concurrent requests, this often blocks |
289 | tickdata = Util.EnvironmentTickCountSubtract(tickstart); | 255 | tickdata = Util.EnvironmentTickCountSubtract(tickstart); |
@@ -314,6 +280,7 @@ namespace OpenSim.Framework | |||
314 | catch (Exception ex) | 280 | catch (Exception ex) |
315 | { | 281 | { |
316 | errorMessage = ex.Message; | 282 | errorMessage = ex.Message; |
283 | m_log.Debug("[WEB UTIL]: Exception making request: " + ex.ToString()); | ||
317 | } | 284 | } |
318 | finally | 285 | finally |
319 | { | 286 | { |
@@ -321,8 +288,17 @@ namespace OpenSim.Framework | |||
321 | if (tickdiff > LongCallTime) | 288 | if (tickdiff > LongCallTime) |
322 | { | 289 | { |
323 | m_log.InfoFormat( | 290 | m_log.InfoFormat( |
324 | "[LOGHTTP]: Slow JSON-RPC request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", | 291 | "[WEB UTIL]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing({5} at Json; {6} at comp), {7} bytes ({8} uncomp): {9}", |
325 | reqnum, method, url, tickdiff, tickdata, | 292 | reqnum, |
293 | method, | ||
294 | url, | ||
295 | tickdiff, | ||
296 | tickdata, | ||
297 | tickJsondata, | ||
298 | tickcompressdata, | ||
299 | compsize, | ||
300 | strBuffer != null ? strBuffer.Length : 0, | ||
301 | |||
326 | strBuffer != null | 302 | strBuffer != null |
327 | ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) | 303 | ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) |
328 | : ""); | 304 | : ""); |
@@ -333,7 +309,7 @@ namespace OpenSim.Framework | |||
333 | reqnum, tickdiff, tickdata); | 309 | reqnum, tickdiff, tickdata); |
334 | } | 310 | } |
335 | } | 311 | } |
336 | 312 | ||
337 | m_log.DebugFormat( | 313 | m_log.DebugFormat( |
338 | "[LOGHTTP]: JSON-RPC request {0} {1} to {2} FAILED: {3}", reqnum, method, url, errorMessage); | 314 | "[LOGHTTP]: JSON-RPC request {0} {1} to {2} FAILED: {3}", reqnum, method, url, errorMessage); |
339 | 315 | ||
@@ -357,7 +333,7 @@ namespace OpenSim.Framework | |||
357 | result["success"] = OSD.FromBoolean(true); | 333 | result["success"] = OSD.FromBoolean(true); |
358 | result["_RawResult"] = OSD.FromString(response); | 334 | result["_RawResult"] = OSD.FromString(response); |
359 | result["_Result"] = new OSDMap(); | 335 | result["_Result"] = new OSDMap(); |
360 | 336 | ||
361 | if (response.Equals("true",System.StringComparison.OrdinalIgnoreCase)) | 337 | if (response.Equals("true",System.StringComparison.OrdinalIgnoreCase)) |
362 | return result; | 338 | return result; |
363 | 339 | ||
@@ -368,7 +344,7 @@ namespace OpenSim.Framework | |||
368 | return result; | 344 | return result; |
369 | } | 345 | } |
370 | 346 | ||
371 | try | 347 | try |
372 | { | 348 | { |
373 | OSD responseOSD = OSDParser.Deserialize(response); | 349 | OSD responseOSD = OSDParser.Deserialize(response); |
374 | if (responseOSD.Type == OSDType.Map) | 350 | if (responseOSD.Type == OSDType.Map) |
@@ -382,10 +358,10 @@ namespace OpenSim.Framework | |||
382 | // don't need to treat this as an error... we're just guessing anyway | 358 | // don't need to treat this as an error... we're just guessing anyway |
383 | // m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message); | 359 | // m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message); |
384 | } | 360 | } |
385 | 361 | ||
386 | return result; | 362 | return result; |
387 | } | 363 | } |
388 | 364 | ||
389 | #endregion JSONRequest | 365 | #endregion JSONRequest |
390 | 366 | ||
391 | #region FormRequest | 367 | #region FormRequest |
@@ -396,18 +372,10 @@ namespace OpenSim.Framework | |||
396 | /// </summary> | 372 | /// </summary> |
397 | public static OSDMap PostToService(string url, NameValueCollection data) | 373 | public static OSDMap PostToService(string url, NameValueCollection data) |
398 | { | 374 | { |
399 | return ServiceFormRequest(url,data,10000); | 375 | return ServiceFormRequest(url,data, 30000); |
400 | } | ||
401 | |||
402 | public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) | ||
403 | { | ||
404 | lock (EndPointLock(url)) | ||
405 | { | ||
406 | return ServiceFormRequestWorker(url,data,timeout); | ||
407 | } | ||
408 | } | 376 | } |
409 | 377 | ||
410 | private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout) | 378 | public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) |
411 | { | 379 | { |
412 | int reqnum = RequestNumber++; | 380 | int reqnum = RequestNumber++; |
413 | string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; | 381 | string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; |
@@ -415,7 +383,7 @@ namespace OpenSim.Framework | |||
415 | if (DebugLevel >= 3) | 383 | if (DebugLevel >= 3) |
416 | m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} ServiceForm '{1}' to {2}", | 384 | m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} ServiceForm '{1}' to {2}", |
417 | reqnum, method, url); | 385 | reqnum, method, url); |
418 | 386 | ||
419 | string errorMessage = "unknown error"; | 387 | string errorMessage = "unknown error"; |
420 | int tickstart = Util.EnvironmentTickCount(); | 388 | int tickstart = Util.EnvironmentTickCount(); |
421 | int tickdata = 0; | 389 | int tickdata = 0; |
@@ -428,9 +396,9 @@ namespace OpenSim.Framework | |||
428 | request.Timeout = timeout; | 396 | request.Timeout = timeout; |
429 | request.KeepAlive = false; | 397 | request.KeepAlive = false; |
430 | request.MaximumAutomaticRedirections = 10; | 398 | request.MaximumAutomaticRedirections = 10; |
431 | request.ReadWriteTimeout = timeout / 4; | 399 | request.ReadWriteTimeout = timeout / 2; |
432 | request.Headers[OSHeaderRequestID] = reqnum.ToString(); | 400 | request.Headers[OSHeaderRequestID] = reqnum.ToString(); |
433 | 401 | ||
434 | if (data != null) | 402 | if (data != null) |
435 | { | 403 | { |
436 | queryString = BuildQueryString(data); | 404 | queryString = BuildQueryString(data); |
@@ -439,7 +407,7 @@ namespace OpenSim.Framework | |||
439 | LogOutgoingDetail("SEND", reqnum, queryString); | 407 | LogOutgoingDetail("SEND", reqnum, queryString); |
440 | 408 | ||
441 | byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); | 409 | byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); |
442 | 410 | ||
443 | request.ContentLength = buffer.Length; | 411 | request.ContentLength = buffer.Length; |
444 | request.ContentType = "application/x-www-form-urlencoded"; | 412 | request.ContentType = "application/x-www-form-urlencoded"; |
445 | using (Stream requestStream = request.GetRequestStream()) | 413 | using (Stream requestStream = request.GetRequestStream()) |
@@ -517,7 +485,7 @@ namespace OpenSim.Framework | |||
517 | } | 485 | } |
518 | 486 | ||
519 | #endregion FormRequest | 487 | #endregion FormRequest |
520 | 488 | ||
521 | #region Uri | 489 | #region Uri |
522 | 490 | ||
523 | /// <summary> | 491 | /// <summary> |
@@ -570,7 +538,7 @@ namespace OpenSim.Framework | |||
570 | } | 538 | } |
571 | 539 | ||
572 | /// <summary> | 540 | /// <summary> |
573 | /// Appends a query string to a Uri that may or may not have existing | 541 | /// Appends a query string to a Uri that may or may not have existing |
574 | /// query parameters | 542 | /// query parameters |
575 | /// </summary> | 543 | /// </summary> |
576 | /// <param name="uri">Uri to append the query to</param> | 544 | /// <param name="uri">Uri to append the query to</param> |
@@ -622,7 +590,7 @@ namespace OpenSim.Framework | |||
622 | } | 590 | } |
623 | 591 | ||
624 | /// <summary> | 592 | /// <summary> |
625 | /// | 593 | /// |
626 | /// </summary> | 594 | /// </summary> |
627 | /// <param name="collection"></param> | 595 | /// <param name="collection"></param> |
628 | /// <param name="key"></param> | 596 | /// <param name="key"></param> |
@@ -641,12 +609,12 @@ namespace OpenSim.Framework | |||
641 | #region Stream | 609 | #region Stream |
642 | 610 | ||
643 | /// <summary> | 611 | /// <summary> |
644 | /// Copies the contents of one stream to another, starting at the | 612 | /// Copies the contents of one stream to another, starting at the |
645 | /// current position of each stream | 613 | /// current position of each stream |
646 | /// </summary> | 614 | /// </summary> |
647 | /// <param name="copyFrom">The stream to copy from, at the position | 615 | /// <param name="copyFrom">The stream to copy from, at the position |
648 | /// where copying should begin</param> | 616 | /// where copying should begin</param> |
649 | /// <param name="copyTo">The stream to copy to, at the position where | 617 | /// <param name="copyTo">The stream to copy to, at the position where |
650 | /// bytes should be written</param> | 618 | /// bytes should be written</param> |
651 | /// <param name="maximumBytesToCopy">The maximum bytes to copy</param> | 619 | /// <param name="maximumBytesToCopy">The maximum bytes to copy</param> |
652 | /// <returns>The total number of bytes copied</returns> | 620 | /// <returns>The total number of bytes copied</returns> |
@@ -779,6 +747,20 @@ namespace OpenSim.Framework | |||
779 | MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, action, maxConnections, null); | 747 | MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, action, maxConnections, null); |
780 | } | 748 | } |
781 | 749 | ||
750 | /// <summary> | ||
751 | /// Perform a synchronous REST request. | ||
752 | /// </summary> | ||
753 | /// <param name="verb"></param> | ||
754 | /// <param name="requestUrl"></param> | ||
755 | /// <param name="obj"></param> | ||
756 | /// <param name="pTimeout"> | ||
757 | /// Request timeout in seconds. Timeout.Infinite indicates no timeout. If 0 is passed then the default HttpWebRequest timeout is used (100 seconds) | ||
758 | /// </param> | ||
759 | /// <param name="maxConnections"></param> | ||
760 | /// <returns> | ||
761 | /// The response. If there was an internal exception or the request timed out, | ||
762 | /// then the default(TResponse) is returned. | ||
763 | /// </returns> | ||
782 | public static void MakeRequest<TRequest, TResponse>(string verb, | 764 | public static void MakeRequest<TRequest, TResponse>(string verb, |
783 | string requestUrl, TRequest obj, Action<TResponse> action, | 765 | string requestUrl, TRequest obj, Action<TResponse> action, |
784 | int maxConnections, IServiceAuth auth) | 766 | int maxConnections, IServiceAuth auth) |
@@ -791,6 +773,7 @@ namespace OpenSim.Framework | |||
791 | 773 | ||
792 | int tickstart = Util.EnvironmentTickCount(); | 774 | int tickstart = Util.EnvironmentTickCount(); |
793 | int tickdata = 0; | 775 | int tickdata = 0; |
776 | int tickdiff = 0; | ||
794 | 777 | ||
795 | Type type = typeof(TRequest); | 778 | Type type = typeof(TRequest); |
796 | 779 | ||
@@ -873,7 +856,7 @@ namespace OpenSim.Framework | |||
873 | // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't | 856 | // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't |
874 | // documented in MSDN | 857 | // documented in MSDN |
875 | using (WebResponse response = request.EndGetResponse(res2)) | 858 | using (WebResponse response = request.EndGetResponse(res2)) |
876 | { | 859 | { |
877 | try | 860 | try |
878 | { | 861 | { |
879 | using (Stream respStream = response.GetResponseStream()) | 862 | using (Stream respStream = response.GetResponseStream()) |
@@ -894,7 +877,7 @@ namespace OpenSim.Framework | |||
894 | if (e.Response is HttpWebResponse) | 877 | if (e.Response is HttpWebResponse) |
895 | { | 878 | { |
896 | using (HttpWebResponse httpResponse = (HttpWebResponse)e.Response) | 879 | using (HttpWebResponse httpResponse = (HttpWebResponse)e.Response) |
897 | { | 880 | { |
898 | if (httpResponse.StatusCode != HttpStatusCode.NotFound) | 881 | if (httpResponse.StatusCode != HttpStatusCode.NotFound) |
899 | { | 882 | { |
900 | // We don't appear to be handling any other status codes, so log these feailures to that | 883 | // We don't appear to be handling any other status codes, so log these feailures to that |
@@ -919,7 +902,7 @@ namespace OpenSim.Framework | |||
919 | "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", | 902 | "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", |
920 | verb, requestUrl, e.Message, e.StackTrace); | 903 | verb, requestUrl, e.Message, e.StackTrace); |
921 | } | 904 | } |
922 | 905 | ||
923 | // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); | 906 | // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); |
924 | 907 | ||
925 | try | 908 | try |
@@ -932,11 +915,11 @@ namespace OpenSim.Framework | |||
932 | "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}", | 915 | "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}", |
933 | verb, requestUrl, e.Message, e.StackTrace); | 916 | verb, requestUrl, e.Message, e.StackTrace); |
934 | } | 917 | } |
935 | 918 | ||
936 | }, null); | 919 | }, null); |
937 | } | 920 | } |
938 | 921 | ||
939 | int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | 922 | tickdiff = Util.EnvironmentTickCountSubtract(tickstart); |
940 | if (tickdiff > WebUtil.LongCallTime) | 923 | if (tickdiff > WebUtil.LongCallTime) |
941 | { | 924 | { |
942 | string originalRequest = null; | 925 | string originalRequest = null; |
@@ -948,8 +931,7 @@ namespace OpenSim.Framework | |||
948 | if (originalRequest.Length > WebUtil.MaxRequestDiagLength) | 931 | if (originalRequest.Length > WebUtil.MaxRequestDiagLength) |
949 | originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); | 932 | originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); |
950 | } | 933 | } |
951 | 934 | m_log.InfoFormat( | |
952 | m_log.InfoFormat( | ||
953 | "[LOGHTTP]: Slow AsynchronousRequestObject request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", | 935 | "[LOGHTTP]: Slow AsynchronousRequestObject request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", |
954 | reqnum, verb, requestUrl, tickdiff, tickdata, | 936 | reqnum, verb, requestUrl, tickdiff, tickdata, |
955 | originalRequest); | 937 | originalRequest); |
@@ -957,11 +939,12 @@ namespace OpenSim.Framework | |||
957 | else if (WebUtil.DebugLevel >= 4) | 939 | else if (WebUtil.DebugLevel >= 4) |
958 | { | 940 | { |
959 | m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", | 941 | m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", |
942 | |||
960 | reqnum, tickdiff, tickdata); | 943 | reqnum, tickdiff, tickdata); |
961 | } | 944 | } |
962 | } | 945 | } |
963 | finally | 946 | finally |
964 | { | 947 | { |
965 | if (buffer != null) | 948 | if (buffer != null) |
966 | buffer.Dispose(); | 949 | buffer.Dispose(); |
967 | } | 950 | } |
@@ -983,7 +966,8 @@ namespace OpenSim.Framework | |||
983 | /// | 966 | /// |
984 | /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting | 967 | /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting |
985 | /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> | 968 | /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> |
986 | public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs, IServiceAuth auth) | 969 | public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs = -1, |
970 | IServiceAuth auth = null, bool keepalive = true) | ||
987 | { | 971 | { |
988 | int reqnum = WebUtil.RequestNumber++; | 972 | int reqnum = WebUtil.RequestNumber++; |
989 | 973 | ||
@@ -998,12 +982,16 @@ namespace OpenSim.Framework | |||
998 | request.Method = verb; | 982 | request.Method = verb; |
999 | if (timeoutsecs > 0) | 983 | if (timeoutsecs > 0) |
1000 | request.Timeout = timeoutsecs * 1000; | 984 | request.Timeout = timeoutsecs * 1000; |
985 | if(!keepalive && request is HttpWebRequest) | ||
986 | ((HttpWebRequest)request).KeepAlive = false; | ||
1001 | 987 | ||
1002 | if (auth != null) | 988 | if (auth != null) |
1003 | auth.AddAuthorization(request.Headers); | 989 | auth.AddAuthorization(request.Headers); |
1004 | 990 | ||
1005 | string respstring = String.Empty; | 991 | string respstring = String.Empty; |
1006 | 992 | ||
993 | int tickset = Util.EnvironmentTickCountSubtract(tickstart); | ||
994 | |||
1007 | using (MemoryStream buffer = new MemoryStream()) | 995 | using (MemoryStream buffer = new MemoryStream()) |
1008 | { | 996 | { |
1009 | if ((verb == "POST") || (verb == "PUT")) | 997 | if ((verb == "POST") || (verb == "PUT")) |
@@ -1024,11 +1012,10 @@ namespace OpenSim.Framework | |||
1024 | if (WebUtil.DebugLevel >= 5) | 1012 | if (WebUtil.DebugLevel >= 5) |
1025 | WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); | 1013 | WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); |
1026 | 1014 | ||
1027 | Stream requestStream = null; | ||
1028 | try | 1015 | try |
1029 | { | 1016 | { |
1030 | requestStream = request.GetRequestStream(); | 1017 | using(Stream requestStream = request.GetRequestStream()) |
1031 | requestStream.Write(data, 0, length); | 1018 | requestStream.Write(data,0,length); |
1032 | } | 1019 | } |
1033 | catch (Exception e) | 1020 | catch (Exception e) |
1034 | { | 1021 | { |
@@ -1038,9 +1025,6 @@ namespace OpenSim.Framework | |||
1038 | } | 1025 | } |
1039 | finally | 1026 | finally |
1040 | { | 1027 | { |
1041 | if (requestStream != null) | ||
1042 | requestStream.Dispose(); | ||
1043 | |||
1044 | // capture how much time was spent writing | 1028 | // capture how much time was spent writing |
1045 | tickdata = Util.EnvironmentTickCountSubtract(tickstart); | 1029 | tickdata = Util.EnvironmentTickCountSubtract(tickstart); |
1046 | } | 1030 | } |
@@ -1070,8 +1054,13 @@ namespace OpenSim.Framework | |||
1070 | if (tickdiff > WebUtil.LongCallTime) | 1054 | if (tickdiff > WebUtil.LongCallTime) |
1071 | { | 1055 | { |
1072 | m_log.InfoFormat( | 1056 | m_log.InfoFormat( |
1073 | "[LOGHTTP]: Slow SynchronousRestForms request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", | 1057 | "[FORMS]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}", |
1074 | reqnum, verb, requestUrl, tickdiff, tickdata, | 1058 | reqnum, |
1059 | verb, | ||
1060 | requestUrl, | ||
1061 | tickdiff, | ||
1062 | tickset, | ||
1063 | tickdata, | ||
1075 | obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj); | 1064 | obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj); |
1076 | } | 1065 | } |
1077 | else if (WebUtil.DebugLevel >= 4) | 1066 | else if (WebUtil.DebugLevel >= 4) |
@@ -1086,16 +1075,6 @@ namespace OpenSim.Framework | |||
1086 | return respstring; | 1075 | return respstring; |
1087 | } | 1076 | } |
1088 | 1077 | ||
1089 | public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs) | ||
1090 | { | ||
1091 | return MakeRequest(verb, requestUrl, obj, timeoutsecs, null); | ||
1092 | } | ||
1093 | |||
1094 | public static string MakeRequest(string verb, string requestUrl, string obj) | ||
1095 | { | ||
1096 | return MakeRequest(verb, requestUrl, obj, -1); | ||
1097 | } | ||
1098 | |||
1099 | public static string MakeRequest(string verb, string requestUrl, string obj, IServiceAuth auth) | 1078 | public static string MakeRequest(string verb, string requestUrl, string obj, IServiceAuth auth) |
1100 | { | 1079 | { |
1101 | return MakeRequest(verb, requestUrl, obj, -1, auth); | 1080 | return MakeRequest(verb, requestUrl, obj, -1, auth); |
@@ -1136,7 +1115,7 @@ namespace OpenSim.Framework | |||
1136 | /// Request timeout in milliseconds. Timeout.Infinite indicates no timeout. If 0 is passed then the default HttpWebRequest timeout is used (100 seconds) | 1115 | /// Request timeout in milliseconds. Timeout.Infinite indicates no timeout. If 0 is passed then the default HttpWebRequest timeout is used (100 seconds) |
1137 | /// </param> | 1116 | /// </param> |
1138 | /// <returns> | 1117 | /// <returns> |
1139 | /// The response. If there was an internal exception or the request timed out, | 1118 | /// The response. If there was an internal exception or the request timed out, |
1140 | /// then the default(TResponse) is returned. | 1119 | /// then the default(TResponse) is returned. |
1141 | /// </returns> | 1120 | /// </returns> |
1142 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout) | 1121 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout) |
@@ -1159,7 +1138,7 @@ namespace OpenSim.Framework | |||
1159 | /// </param> | 1138 | /// </param> |
1160 | /// <param name="maxConnections"></param> | 1139 | /// <param name="maxConnections"></param> |
1161 | /// <returns> | 1140 | /// <returns> |
1162 | /// The response. If there was an internal exception or the request timed out, | 1141 | /// The response. If there was an internal exception or the request timed out, |
1163 | /// then the default(TResponse) is returned. | 1142 | /// then the default(TResponse) is returned. |
1164 | /// </returns> | 1143 | /// </returns> |
1165 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections) | 1144 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections) |
@@ -1178,7 +1157,7 @@ namespace OpenSim.Framework | |||
1178 | /// </param> | 1157 | /// </param> |
1179 | /// <param name="maxConnections"></param> | 1158 | /// <param name="maxConnections"></param> |
1180 | /// <returns> | 1159 | /// <returns> |
1181 | /// The response. If there was an internal exception or the request timed out, | 1160 | /// The response. If there was an internal exception or the request timed out, |
1182 | /// then the default(TResponse) is returned. | 1161 | /// then the default(TResponse) is returned. |
1183 | /// </returns> | 1162 | /// </returns> |
1184 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections, IServiceAuth auth) | 1163 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections, IServiceAuth auth) |
@@ -1202,7 +1181,7 @@ namespace OpenSim.Framework | |||
1202 | auth.AddAuthorization(ht.Headers); | 1181 | auth.AddAuthorization(ht.Headers); |
1203 | 1182 | ||
1204 | if (pTimeout != 0) | 1183 | if (pTimeout != 0) |
1205 | ht.Timeout = pTimeout; | 1184 | request.Timeout = pTimeout; |
1206 | 1185 | ||
1207 | if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections) | 1186 | if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections) |
1208 | ht.ServicePoint.ConnectionLimit = maxConnections; | 1187 | ht.ServicePoint.ConnectionLimit = maxConnections; |
@@ -1283,18 +1262,24 @@ namespace OpenSim.Framework | |||
1283 | { | 1262 | { |
1284 | if (hwr.StatusCode == HttpStatusCode.NotFound) | 1263 | if (hwr.StatusCode == HttpStatusCode.NotFound) |
1285 | return deserial; | 1264 | return deserial; |
1265 | |||
1286 | if (hwr.StatusCode == HttpStatusCode.Unauthorized) | 1266 | if (hwr.StatusCode == HttpStatusCode.Unauthorized) |
1287 | { | 1267 | { |
1288 | m_log.Error(string.Format( | 1268 | m_log.ErrorFormat("[SynchronousRestObjectRequester]: Web request {0} requires authentication", |
1289 | "[SynchronousRestObjectRequester]: Web request {0} requires authentication ", | 1269 | requestUrl); |
1290 | requestUrl)); | 1270 | } |
1291 | return deserial; | 1271 | else |
1272 | { | ||
1273 | m_log.WarnFormat("[SynchronousRestObjectRequester]: Web request {0} returned error: {1}", | ||
1274 | requestUrl, hwr.StatusCode); | ||
1292 | } | 1275 | } |
1293 | } | 1276 | } |
1294 | else | 1277 | else |
1295 | m_log.Error(string.Format( | 1278 | m_log.ErrorFormat( |
1296 | "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} ", | 1279 | "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} {3}", |
1297 | verb, requestUrl, typeof(TResponse).ToString()), e); | 1280 | verb, requestUrl, typeof(TResponse).ToString(), e.Message); |
1281 | |||
1282 | return deserial; | ||
1298 | } | 1283 | } |
1299 | } | 1284 | } |
1300 | catch (System.InvalidOperationException) | 1285 | catch (System.InvalidOperationException) |
@@ -1344,7 +1329,6 @@ namespace OpenSim.Framework | |||
1344 | return deserial; | 1329 | return deserial; |
1345 | } | 1330 | } |
1346 | 1331 | ||
1347 | |||
1348 | public static class XMLResponseHelper | 1332 | public static class XMLResponseHelper |
1349 | { | 1333 | { |
1350 | public static TResponse LogAndDeserialize<TRequest, TResponse>(int reqnum, Stream respStream, long contentLength) | 1334 | public static TResponse LogAndDeserialize<TRequest, TResponse>(int reqnum, Stream respStream, long contentLength) |
@@ -1369,7 +1353,7 @@ namespace OpenSim.Framework | |||
1369 | } | 1353 | } |
1370 | } | 1354 | } |
1371 | 1355 | ||
1372 | 1356 | ||
1373 | public static class XMLRPCRequester | 1357 | public static class XMLRPCRequester |
1374 | { | 1358 | { |
1375 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 1359 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -1413,7 +1397,7 @@ namespace OpenSim.Framework | |||
1413 | { | 1397 | { |
1414 | m_log.Error("Error parsing XML-RPC response", e); | 1398 | m_log.Error("Error parsing XML-RPC response", e); |
1415 | } | 1399 | } |
1416 | 1400 | ||
1417 | if (Resp.IsFault) | 1401 | if (Resp.IsFault) |
1418 | { | 1402 | { |
1419 | m_log.DebugFormat( | 1403 | m_log.DebugFormat( |