29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Collections.Specialized;
32 using System.Globalization;
34 using System.IO.Compression;
36 using System.Net.Security;
37 using System.Reflection;
41 using System.Xml.Serialization;
42 using System.Xml.Linq;
45 using OpenMetaverse.StructuredData;
48 using OpenSim.Framework.ServiceAuth;
50 namespace OpenSim.Framework
55 public static class WebUtil
57 private static readonly ILog m_log =
59 MethodBase.GetCurrentMethod().DeclaringType);
67 public static int DebugLevel {
get; set; }
72 public static int RequestNumber {
get; set; }
77 public static bool SerializeOSDRequestsPerEndpoint {
get; set; }
83 public const string OSHeaderRequestID =
"opensim-request-id";
89 public const int LongCallTime = 3000;
99 public const int MaxRequestDiagLength = 200;
104 private static Dictionary<string,object> m_endpointSerializer =
new Dictionary<string,object>();
106 private static object EndPointLock(
string url)
108 System.Uri uri =
new System.Uri(url);
109 string endpoint = string.Format(
"{0}:{1}",uri.Host,uri.Port);
111 lock (m_endpointSerializer)
113 object eplock = null;
115 if (! m_endpointSerializer.TryGetValue(endpoint,out eplock))
117 eplock =
new object();
118 m_endpointSerializer.Add(endpoint,eplock);
132 public static OSDMap PutToServiceCompressed(
string url,
OSDMap data,
int timeout)
134 return ServiceOSDRequest(url,data,
"PUT", timeout,
true,
false);
137 public static OSDMap PutToService(
string url,
OSDMap data,
int timeout)
139 return ServiceOSDRequest(url,data,
"PUT", timeout,
false,
false);
142 public static OSDMap PostToService(
string url,
OSDMap data,
int timeout,
bool rpc)
144 return ServiceOSDRequest(url, data,
"POST", timeout,
false, rpc);
147 public static OSDMap PostToServiceCompressed(
string url,
OSDMap data,
int timeout)
149 return ServiceOSDRequest(url, data,
"POST", timeout,
true,
false);
152 public static OSDMap GetFromService(
string url,
int timeout)
154 return ServiceOSDRequest(url, null,
"GET", timeout,
false,
false);
157 public static OSDMap ServiceOSDRequest(
string url,
OSDMap data,
string method,
int timeout,
bool compressed,
bool rpc)
159 if (SerializeOSDRequestsPerEndpoint)
161 lock (EndPointLock(url))
163 return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc);
168 return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc);
172 public static void LogOutgoingDetail(Stream outputStream)
174 LogOutgoingDetail(
"", outputStream);
177 public static void LogOutgoingDetail(
string context, Stream outputStream)
179 using (Stream stream = Util.Copy(outputStream))
180 using (StreamReader reader =
new StreamReader(stream, Encoding.UTF8))
186 char[] chars =
new char[WebUtil.MaxRequestDiagLength + 1];
187 int len = reader.Read(chars, 0, WebUtil.MaxRequestDiagLength + 1);
188 output =
new string(chars, 0, len);
192 output = reader.ReadToEnd();
195 LogOutgoingDetail(context, output);
199 public static void LogOutgoingDetail(
string type,
int reqnum,
string output)
201 LogOutgoingDetail(
string.Format(
"{0} {1}: ", type, reqnum), output);
204 public static void LogOutgoingDetail(
string context,
string output)
208 if (output.Length > MaxRequestDiagLength)
209 output = output.Substring(0, MaxRequestDiagLength) +
"...";
212 m_log.DebugFormat(
"[LOGHTTP]: {0}{1}", context, Util.BinaryToASCII(output));
215 public static void LogResponseDetail(
int reqnum, Stream inputStream)
217 LogOutgoingDetail(
string.Format(
"RESPONSE {0}: ", reqnum), inputStream);
220 public static void LogResponseDetail(
int reqnum,
string input)
222 LogOutgoingDetail(
string.Format(
"RESPONSE {0}: ", reqnum), input);
225 private static OSDMap ServiceOSDRequestWorker(
string url,
OSDMap data,
string method,
int timeout,
bool compressed,
bool rpc)
227 int reqnum = RequestNumber++;
230 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} JSON-RPC {1} to {2}",
231 reqnum, method, url);
233 string errorMessage =
"unknown error";
234 int tickstart = Util.EnvironmentTickCount();
236 int tickcompressdata = 0;
237 int tickJsondata = 0;
239 string strBuffer = null;
243 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
244 request.Method = method;
245 request.Timeout = timeout;
246 request.KeepAlive =
false;
247 request.MaximumAutomaticRedirections = 10;
248 request.ReadWriteTimeout = timeout / 4;
249 request.Headers[OSHeaderRequestID] = reqnum.ToString();
254 strBuffer = OSDParser.SerializeJsonString(data);
256 tickJsondata = Util.EnvironmentTickCountSubtract(tickstart);
259 LogOutgoingDetail(
"SEND", reqnum, strBuffer);
261 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
263 request.ContentType = rpc ?
"application/json-rpc" :
"application/json";
267 request.Headers[
"X-Content-Encoding"] =
"gzip";
269 using (MemoryStream ms =
new MemoryStream())
273 comp.Write(buffer, 0, buffer.Length);
278 byte[] buf = ms.ToArray();
280 tickcompressdata = Util.EnvironmentTickCountSubtract(tickstart);
282 request.ContentLength = buf.Length;
283 compsize = buf.Length;
284 using (Stream requestStream = request.GetRequestStream())
285 requestStream.Write(buf, 0, (int)buf.Length);
290 compsize = buffer.Length;
292 request.ContentLength = buffer.Length;
293 using (Stream requestStream = request.GetRequestStream())
294 requestStream.Write(buffer, 0, buffer.Length);
300 tickdata = Util.EnvironmentTickCountSubtract(tickstart);
302 using (WebResponse response = request.GetResponse())
304 using (Stream responseStream = response.GetResponseStream())
306 using (StreamReader reader =
new StreamReader(responseStream))
308 string responseStr = reader.ReadToEnd();
309 if (WebUtil.DebugLevel >= 5)
310 WebUtil.LogResponseDetail(reqnum, responseStr);
311 return CanonicalizeResults(responseStr);
316 catch (WebException we)
318 errorMessage = we.Message;
319 if (we.Status == WebExceptionStatus.ProtocolError)
321 using (HttpWebResponse webResponse = (HttpWebResponse)we.Response)
322 errorMessage = String.Format(
"[{0}] {1}", webResponse.StatusCode, webResponse.StatusDescription);
327 errorMessage = ex.Message;
328 m_log.Debug(
"[WEB UTIL]: Exception making request: " + ex.ToString());
332 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
333 if (tickdiff > LongCallTime)
336 "[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}",
345 strBuffer != null ? strBuffer.Length : 0,
348 ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
351 else if (DebugLevel >= 4)
353 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing",
354 reqnum, tickdiff, tickdata);
359 "[LOGHTTP]: JSON-RPC request {0} {1} to {2} FAILED: {3}", reqnum, method, url, errorMessage);
361 return ErrorResponseMap(errorMessage);
372 private static OSDMap CanonicalizeResults(
string response)
377 result[
"Success"] = OSD.FromBoolean(
true);
378 result[
"success"] = OSD.FromBoolean(
true);
379 result[
"_RawResult"] = OSD.FromString(response);
380 result[
"_Result"] =
new OSDMap();
382 if (response.Equals(
"true",System.StringComparison.OrdinalIgnoreCase))
385 if (response.Equals(
"false",System.StringComparison.OrdinalIgnoreCase))
387 result[
"Success"] = OSD.FromBoolean(
false);
388 result[
"success"] = OSD.FromBoolean(
false);
394 OSD responseOSD = OSDParser.Deserialize(response);
395 if (responseOSD.Type == OSDType.Map)
397 result[
"_Result"] = (
OSDMap)responseOSD;
410 #endregion JSONRequest
418 public static OSDMap PostToService(
string url, NameValueCollection data)
420 return ServiceFormRequest(url,data, 30000);
423 public static OSDMap ServiceFormRequest(
string url, NameValueCollection data,
int timeout)
425 lock (EndPointLock(url))
427 return ServiceFormRequestWorker(url,data,timeout);
431 private static OSDMap ServiceFormRequestWorker(
string url, NameValueCollection data,
int timeout)
433 int reqnum = RequestNumber++;
434 string method = (data != null && data[
"RequestMethod"] != null) ? data[
"RequestMethod"] :
"unknown";
437 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} ServiceForm '{1}' to {2}",
438 reqnum, method, url);
440 string errorMessage =
"unknown error";
441 int tickstart = Util.EnvironmentTickCount();
443 string queryString = null;
447 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
448 request.Method =
"POST";
449 request.Timeout = timeout;
450 request.KeepAlive =
false;
451 request.MaximumAutomaticRedirections = 10;
452 request.ReadWriteTimeout = timeout / 4;
453 request.Headers[OSHeaderRequestID] = reqnum.ToString();
457 queryString = BuildQueryString(data);
460 LogOutgoingDetail(
"SEND", reqnum, queryString);
462 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
464 request.ContentLength = buffer.Length;
465 request.ContentType =
"application/x-www-form-urlencoded";
466 using (Stream requestStream = request.GetRequestStream())
467 requestStream.Write(buffer, 0, buffer.Length);
472 tickdata = Util.EnvironmentTickCountSubtract(tickstart);
474 using (WebResponse response = request.GetResponse())
476 using (Stream responseStream = response.GetResponseStream())
478 using (StreamReader reader =
new StreamReader(responseStream))
480 string responseStr = reader.ReadToEnd();
481 if (WebUtil.DebugLevel >= 5)
482 WebUtil.LogResponseDetail(reqnum, responseStr);
483 OSD responseOSD = OSDParser.Deserialize(responseStr);
485 if (responseOSD.Type == OSDType.Map)
486 return (
OSDMap)responseOSD;
491 catch (WebException we)
493 errorMessage = we.Message;
494 if (we.Status == WebExceptionStatus.ProtocolError)
496 using (HttpWebResponse webResponse = (HttpWebResponse)we.Response)
497 errorMessage = String.Format(
"[{0}] {1}",webResponse.StatusCode,webResponse.StatusDescription);
502 errorMessage = ex.Message;
506 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
507 if (tickdiff > LongCallTime)
510 "[LOGHTTP]: Slow ServiceForm request {0} '{1}' to {2} took {3}ms, {4}ms writing, {5}",
511 reqnum, method, url, tickdiff, tickdata,
513 ? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString
516 else if (DebugLevel >= 4)
518 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing",
519 reqnum, tickdiff, tickdata);
523 m_log.WarnFormat(
"[LOGHTTP]: ServiceForm request {0} '{1}' to {2} failed: {3}", reqnum, method, url, errorMessage);
525 return ErrorResponseMap(errorMessage);
532 private static OSDMap ErrorResponseMap(
string msg)
535 result[
"Success"] =
"False";
536 result[
"Message"] = OSD.FromString(
"Service request failed: " + msg);
540 #endregion FormRequest
555 public static Uri Combine(
this Uri uri,
string fragment)
557 string fragment1 = uri.Fragment;
558 string fragment2 = fragment;
560 if (!fragment1.EndsWith(
"/"))
561 fragment1 = fragment1 +
'/';
562 if (fragment2.StartsWith(
"/"))
563 fragment2 = fragment2.Substring(1);
565 return new Uri(uri, fragment1 + fragment2);
577 public static Uri Combine(
this Uri uri, Uri fragment)
579 if (fragment.IsAbsoluteUri)
582 string fragment1 = uri.Fragment;
583 string fragment2 = fragment.ToString();
585 if (!fragment1.EndsWith(
"/"))
586 fragment1 = fragment1 +
'/';
587 if (fragment2.StartsWith(
"/"))
588 fragment2 = fragment2.Substring(1);
590 return new Uri(uri, fragment1 + fragment2);
602 public static string AppendQuery(
this Uri uri,
string query)
604 if (String.IsNullOrEmpty(query))
605 return uri.ToString();
607 if (query[0] ==
'?' || query[0] ==
'&')
608 query = query.Substring(1);
610 string uriStr = uri.ToString();
612 if (uriStr.Contains(
"?"))
613 return uriStr +
'&' + query;
615 return uriStr +
'?' + query;
620 #region NameValueCollection
628 public static string BuildQueryString(NameValueCollection parameters)
630 List<string> items =
new List<string>(parameters.Count);
632 foreach (
string key in parameters.Keys)
634 string[] values = parameters.GetValues(
key);
637 foreach (
string value
in values)
638 items.Add(String.Concat(
key,
"=", HttpUtility.UrlEncode(value ?? String.Empty)));
642 return String.Join(
"&", items.ToArray());
651 public static string GetOne(
this NameValueCollection collection,
string key)
653 string[] values = collection.GetValues(
key);
654 if (values != null && values.Length > 0)
660 #endregion NameValueCollection
683 public static int CopyStream(
this Stream copyFrom, Stream copyTo,
int maximumBytesToCopy)
685 byte[] buffer =
new byte[4096];
687 int totalCopiedBytes = 0;
689 while ((readBytes = copyFrom.Read(buffer, 0, Math.Min(4096, maximumBytesToCopy))) > 0)
691 int writeBytes = Math.Min(maximumBytesToCopy, readBytes);
692 copyTo.Write(buffer, 0, writeBytes);
693 totalCopiedBytes += writeBytes;
694 maximumBytesToCopy -= writeBytes;
697 return totalCopiedBytes;
708 return qy.CompareTo(qx);
711 private float GetQ(Object o)
718 string mime = (string)o;
719 string[] parts = mime.Split(
';');
720 if (parts.Length > 1)
722 string[] kvp = parts[1].Split(
'=');
723 if (kvp.Length == 2 && kvp[0] ==
"q")
724 float.TryParse(kvp[1], NumberStyles.Number, CultureInfo.InvariantCulture, out qvalue);
741 public static string[] GetPreferredImageTypes(
string accept)
743 if (
string.IsNullOrEmpty(accept))
744 return new string[0];
746 string[] types = accept.Split(
new char[] {
',' });
747 if (types.Length > 0)
749 List<string> list =
new List<string>(types);
750 list.RemoveAll(delegate(
string s) {
return !s.ToLower().StartsWith(
"image"); });
751 ArrayList tlist =
new ArrayList(list);
752 tlist.Sort(
new QBasedComparer());
754 string[] result =
new string[tlist.Count];
755 for (
int i = 0; i < tlist.Count; i++)
757 string mime = (string)tlist[i];
758 string[] parts = mime.Split(
new char[] {
';' });
759 string[] pair = parts[0].Split(
new char[] {
'/' });
760 if (pair.Length == 2)
761 result[i] = pair[1].ToLower();
769 return new string[0];
773 public static class AsynchronousRestObjectRequester
775 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
790 public static void MakeRequest<TRequest, TResponse>(
string verb,
791 string requestUrl, TRequest obj, Action<TResponse> action)
793 MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, action, 0);
796 public static void MakeRequest<TRequest, TResponse>(
string verb,
797 string requestUrl, TRequest obj, Action<TResponse> action,
800 MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, action, maxConnections, null);
817 public static void MakeRequest<TRequest, TResponse>(
string verb,
818 string requestUrl, TRequest obj, Action<TResponse> action,
821 int reqnum = WebUtil.RequestNumber++;
823 if (WebUtil.DebugLevel >= 3)
824 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} AsynchronousRequestObject {1} to {2}",
825 reqnum, verb, requestUrl);
827 int tickstart = Util.EnvironmentTickCount();
831 Type type = typeof(TRequest);
833 WebRequest request = WebRequest.Create(requestUrl);
834 HttpWebRequest ht = (HttpWebRequest)request;
837 auth.AddAuthorization(ht.Headers);
839 if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections)
840 ht.ServicePoint.ConnectionLimit = maxConnections;
842 TResponse deserial =
default(TResponse);
844 request.Method = verb;
846 MemoryStream buffer = null;
852 request.ContentType =
"text/xml";
854 buffer =
new MemoryStream();
856 XmlWriterSettings settings =
new XmlWriterSettings();
857 settings.Encoding = Encoding.UTF8;
859 using (XmlWriter writer = XmlWriter.Create(buffer, settings))
861 XmlSerializer serializer =
new XmlSerializer(type);
862 serializer.Serialize(writer, obj);
866 int length = (int)buffer.Length;
867 request.ContentLength = length;
868 byte[] data = buffer.ToArray();
870 if (WebUtil.DebugLevel >= 5)
871 WebUtil.LogOutgoingDetail(
"SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
873 request.BeginGetRequestStream(delegate(IAsyncResult res)
875 using (Stream requestStream = request.EndGetRequestStream(res))
876 requestStream.Write(data, 0, length);
879 tickdata = Util.EnvironmentTickCountSubtract(tickstart);
881 request.BeginGetResponse(delegate(IAsyncResult ar)
883 using (WebResponse response = request.EndGetResponse(ar))
887 using (Stream respStream = response.GetResponseStream())
889 deserial = XMLResponseHelper.LogAndDeserialize<TRequest, TResponse>(
890 reqnum, respStream, response.ContentLength);
893 catch (System.InvalidOperationException)
905 request.BeginGetResponse(delegate(IAsyncResult res2)
911 using (WebResponse response = request.EndGetResponse(res2))
915 using (Stream respStream = response.GetResponseStream())
917 deserial = XMLResponseHelper.LogAndDeserialize<TRequest, TResponse>(
918 reqnum, respStream, response.ContentLength);
921 catch (System.InvalidOperationException)
926 catch (WebException e)
928 if (e.Status == WebExceptionStatus.ProtocolError)
930 if (e.Response is HttpWebResponse)
932 using (HttpWebResponse httpResponse = (HttpWebResponse)e.Response)
934 if (httpResponse.StatusCode != HttpStatusCode.NotFound)
939 "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}",
940 verb, requestUrl, httpResponse.StatusCode);
948 "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}",
949 verb, requestUrl, e.Status, e.Message);
955 "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
956 verb, requestUrl, e.Message, e.StackTrace);
968 "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}",
969 verb, requestUrl, e.Message, e.StackTrace);
975 tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
976 if (tickdiff > WebUtil.LongCallTime)
978 string originalRequest = null;
982 originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
984 if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
985 originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
988 "[LOGHTTP]: Slow AsynchronousRequestObject request {0} {1} to {2} took {3}ms, {4}ms writing, {5}",
989 reqnum, verb, requestUrl, tickdiff, tickdata,
992 else if (WebUtil.DebugLevel >= 4)
994 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing",
996 reqnum, tickdiff, tickdata);
1007 public static class SynchronousRestFormsRequester
1009 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1022 public static string MakeRequest(
string verb,
string requestUrl,
string obj,
int timeoutsecs,
IServiceAuth auth)
1024 int reqnum = WebUtil.RequestNumber++;
1026 if (WebUtil.DebugLevel >= 3)
1027 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} SynchronousRestForms {1} to {2}",
1028 reqnum, verb, requestUrl);
1030 int tickstart = Util.EnvironmentTickCount();
1033 WebRequest request = WebRequest.Create(requestUrl);
1034 request.Method = verb;
1035 if (timeoutsecs > 0)
1036 request.Timeout = timeoutsecs * 1000;
1039 auth.AddAuthorization(request.Headers);
1041 string respstring = String.Empty;
1043 int tickset = Util.EnvironmentTickCountSubtract(tickstart);
1045 using (MemoryStream buffer =
new MemoryStream())
1047 if ((verb ==
"POST") || (verb ==
"PUT"))
1049 request.ContentType =
"application/x-www-form-urlencoded";
1052 using (StreamWriter writer =
new StreamWriter(buffer))
1058 length = (int)obj.Length;
1059 request.ContentLength = length;
1060 byte[] data = buffer.ToArray();
1062 if (WebUtil.DebugLevel >= 5)
1063 WebUtil.LogOutgoingDetail(
"SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
1065 Stream requestStream = null;
1068 requestStream = request.GetRequestStream();
1069 requestStream.Write(data, 0, length);
1073 m_log.InfoFormat(
"[FORMS]: Error sending request to {0}: {1}. Request: {2}", requestUrl, e.Message,
1074 obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
1079 if (requestStream != null)
1080 requestStream.Dispose();
1083 tickdata = Util.EnvironmentTickCountSubtract(tickstart);
1089 using (WebResponse resp = request.GetResponse())
1091 if (resp.ContentLength != 0)
1093 using (Stream respStream = resp.GetResponseStream())
1094 using (StreamReader reader =
new StreamReader(respStream))
1095 respstring = reader.ReadToEnd();
1101 m_log.InfoFormat(
"[FORMS]: Error receiving response from {0}: {1}. Request: {2}", requestUrl, e.Message,
1102 obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
1107 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
1108 if (tickdiff > WebUtil.LongCallTime)
1111 "[FORMS]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}",
1118 obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
1120 else if (WebUtil.DebugLevel >= 4)
1122 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing",
1123 reqnum, tickdiff, tickdata);
1126 if (WebUtil.DebugLevel >= 5)
1127 WebUtil.LogResponseDetail(reqnum, respstring);
1132 public static string MakeRequest(
string verb,
string requestUrl,
string obj,
int timeoutsecs)
1134 return MakeRequest(verb, requestUrl, obj, timeoutsecs, null);
1137 public static string MakeRequest(
string verb,
string requestUrl,
string obj)
1139 return MakeRequest(verb, requestUrl, obj, -1);
1142 public static string MakeRequest(
string verb,
string requestUrl,
string obj,
IServiceAuth auth)
1144 return MakeRequest(verb, requestUrl, obj, -1, auth);
1150 private static readonly ILog m_log =
1151 LogManager.GetLogger(
1152 MethodBase.GetCurrentMethod().DeclaringType);
1163 public static TResponse MakeRequest<TRequest, TResponse>(
string verb,
string requestUrl, TRequest obj)
1165 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, 0);
1168 public static TResponse MakeRequest<TRequest, TResponse>(
string verb,
string requestUrl, TRequest obj,
IServiceAuth auth)
1170 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, 0, auth);
1185 public static TResponse MakeRequest<TRequest, TResponse>(
string verb,
string requestUrl, TRequest obj,
int pTimeout)
1187 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, pTimeout, 0);
1190 public static TResponse MakeRequest<TRequest, TResponse>(
string verb,
string requestUrl, TRequest obj,
int pTimeout,
IServiceAuth auth)
1192 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, pTimeout, 0, auth);
1208 public static TResponse MakeRequest<TRequest, TResponse>(
string verb,
string requestUrl, TRequest obj,
int pTimeout,
int maxConnections)
1210 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, pTimeout, maxConnections, null);
1227 public static TResponse MakeRequest<TRequest, TResponse>(
string verb,
string requestUrl, TRequest obj,
int pTimeout,
int maxConnections,
IServiceAuth auth)
1229 int reqnum = WebUtil.RequestNumber++;
1231 if (WebUtil.DebugLevel >= 3)
1232 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} SynchronousRestObject {1} to {2}",
1233 reqnum, verb, requestUrl);
1235 int tickstart = Util.EnvironmentTickCount();
1238 Type type = typeof(TRequest);
1239 TResponse deserial =
default(TResponse);
1241 WebRequest request = WebRequest.Create(requestUrl);
1242 HttpWebRequest ht = (HttpWebRequest)request;
1245 auth.AddAuthorization(ht.Headers);
1248 request.Timeout = pTimeout;
1250 if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections)
1251 ht.ServicePoint.ConnectionLimit = maxConnections;
1253 request.Method = verb;
1254 MemoryStream buffer = null;
1258 if ((verb ==
"POST") || (verb ==
"PUT"))
1260 request.ContentType =
"text/xml";
1262 buffer =
new MemoryStream();
1264 XmlWriterSettings settings =
new XmlWriterSettings();
1265 settings.Encoding = Encoding.UTF8;
1267 using (XmlWriter writer = XmlWriter.Create(buffer, settings))
1269 XmlSerializer serializer =
new XmlSerializer(type);
1270 serializer.Serialize(writer, obj);
1274 int length = (int)buffer.Length;
1275 request.ContentLength = length;
1276 byte[] data = buffer.ToArray();
1278 if (WebUtil.DebugLevel >= 5)
1279 WebUtil.LogOutgoingDetail(
"SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
1283 using (Stream requestStream = request.GetRequestStream())
1284 requestStream.Write(data, 0, length);
1289 "[SynchronousRestObjectRequester]: Exception in making request {0} {1}: {2}{3}",
1290 verb, requestUrl, e.Message, e.StackTrace);
1297 tickdata = Util.EnvironmentTickCountSubtract(tickstart);
1303 using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
1305 if (resp.ContentLength != 0)
1307 using (Stream respStream = resp.GetResponseStream())
1309 deserial = XMLResponseHelper.LogAndDeserialize<TRequest, TResponse>(
1310 reqnum, respStream, resp.ContentLength);
1316 "[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}",
1321 catch (WebException e)
1323 using (HttpWebResponse hwr = (HttpWebResponse)e.Response)
1327 if (hwr.StatusCode == HttpStatusCode.NotFound)
1329 if (hwr.StatusCode == HttpStatusCode.Unauthorized)
1331 m_log.Error(string.Format(
1332 "[SynchronousRestObjectRequester]: Web request {0} requires authentication ",
1338 m_log.Error(string.Format(
1339 "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} ",
1340 verb, requestUrl, typeof(TResponse).ToString()), e);
1343 catch (System.InvalidOperationException)
1347 "[SynchronousRestObjectRequester]: Invalid XML from {0} {1} {2}",
1348 verb, requestUrl, typeof(TResponse).ToString());
1352 m_log.Debug(string.Format(
1353 "[SynchronousRestObjectRequester]: Exception on response from {0} {1} ",
1354 verb, requestUrl), e);
1357 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
1358 if (tickdiff > WebUtil.LongCallTime)
1360 string originalRequest = null;
1364 originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
1366 if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
1367 originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
1371 "[LOGHTTP]: Slow SynchronousRestObject request {0} {1} to {2} took {3}ms, {4}ms writing, {5}",
1372 reqnum, verb, requestUrl, tickdiff, tickdata,
1375 else if (WebUtil.DebugLevel >= 4)
1377 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing",
1378 reqnum, tickdiff, tickdata);
1392 public static TResponse LogAndDeserialize<TRequest, TResponse>(
int reqnum, Stream respStream,
long contentLength)
1394 XmlSerializer deserializer =
new XmlSerializer(typeof(TResponse));
1396 if (WebUtil.DebugLevel >= 5)
1398 byte[] data =
new byte[contentLength];
1399 Util.ReadStream(respStream, data);
1401 WebUtil.LogResponseDetail(reqnum, System.Text.Encoding.UTF8.GetString(data));
1403 using (MemoryStream temp =
new MemoryStream(data))
1404 return (TResponse)deserializer.Deserialize(temp);
1408 return (TResponse)deserializer.Deserialize(respStream);
1415 public static class XMLRPCRequester
1417 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1419 public static Hashtable SendRequest(Hashtable ReqParams,
string method,
string url)
1421 int reqnum = WebUtil.RequestNumber++;
1423 if (WebUtil.DebugLevel >= 3)
1424 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} XML-RPC '{1}' to {2}",
1425 reqnum, method, url);
1427 int tickstart = Util.EnvironmentTickCount();
1428 string responseStr = null;
1432 ArrayList SendParams =
new ArrayList();
1433 SendParams.Add(ReqParams);
1435 XmlRpcRequest Req =
new XmlRpcRequest(method, SendParams);
1437 if (WebUtil.DebugLevel >= 5)
1439 string str = Req.ToString();
1440 str = XElement.Parse(str).ToString(SaveOptions.DisableFormatting);
1441 WebUtil.LogOutgoingDetail(
"SEND", reqnum, str);
1444 XmlRpcResponse Resp = Req.Send(url, 30000);
1448 responseStr = Resp.ToString();
1449 responseStr = XElement.Parse(responseStr).ToString(SaveOptions.DisableFormatting);
1451 if (WebUtil.DebugLevel >= 5)
1452 WebUtil.LogResponseDetail(reqnum, responseStr);
1456 m_log.Error(
"Error parsing XML-RPC response", e);
1462 "[LOGHTTP]: XML-RPC request {0} '{1}' to {2} FAILED: FaultCode={3}, FaultMessage={4}",
1463 reqnum, method, url, Resp.FaultCode, Resp.FaultString);
1467 Hashtable RespData = (Hashtable)Resp.Value;
1472 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
1473 if (tickdiff > WebUtil.LongCallTime)
1476 "[LOGHTTP]: Slow XML-RPC request {0} '{1}' to {2} took {3}ms, {4}",
1477 reqnum, method, url, tickdiff,
1479 ? (responseStr.Length > WebUtil.MaxRequestDiagLength ? responseStr.Remove(WebUtil.MaxRequestDiagLength) : responseStr)
1482 else if (WebUtil.DebugLevel >= 4)
1484 m_log.DebugFormat(
"[LOGHTTP]: HTTP OUT {0} took {1}ms", reqnum, tickdiff);
OpenMetaverse.StructuredData.OSDMap OSDMap
OpenSim.Framework.SynchronousRestObjectRequester.XMLResponseHelper XMLResponseHelper
Ionic.Zlib.GZipStream GZipStream
OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString key
int Compare(Object x, Object y)
OpenMetaverse.StructuredData.OSD OSD
Ionic.Zlib.CompressionMode CompressionMode