diff options
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs')
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 170 |
1 files changed, 120 insertions, 50 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 1363eab..616c673 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -46,6 +46,7 @@ using CoolHTTPListener = HttpServer.HttpListener; | |||
46 | using HttpListener=System.Net.HttpListener; | 46 | using HttpListener=System.Net.HttpListener; |
47 | using LogPrio=HttpServer.LogPrio; | 47 | using LogPrio=HttpServer.LogPrio; |
48 | using OpenSim.Framework.Monitoring; | 48 | using OpenSim.Framework.Monitoring; |
49 | using System.IO.Compression; | ||
49 | 50 | ||
50 | namespace OpenSim.Framework.Servers.HttpServer | 51 | namespace OpenSim.Framework.Servers.HttpServer |
51 | { | 52 | { |
@@ -53,6 +54,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
53 | { | 54 | { |
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 55 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
55 | private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); | 56 | private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); |
57 | private static Encoding UTF8NoBOM = new System.Text.UTF8Encoding(false); | ||
56 | 58 | ||
57 | /// <summary> | 59 | /// <summary> |
58 | /// This is a pending websocket request before it got an sucessful upgrade response. | 60 | /// This is a pending websocket request before it got an sucessful upgrade response. |
@@ -113,7 +115,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
113 | 115 | ||
114 | protected IPAddress m_listenIPAddress = IPAddress.Any; | 116 | protected IPAddress m_listenIPAddress = IPAddress.Any; |
115 | 117 | ||
116 | private PollServiceRequestManager m_PollServiceManager; | 118 | public PollServiceRequestManager PollServiceRequestManager { get; private set; } |
117 | 119 | ||
118 | public uint SSLPort | 120 | public uint SSLPort |
119 | { | 121 | { |
@@ -374,7 +376,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
374 | return true; | 376 | return true; |
375 | } | 377 | } |
376 | 378 | ||
377 | private void OnRequest(object source, RequestEventArgs args) | 379 | public void OnRequest(object source, RequestEventArgs args) |
378 | { | 380 | { |
379 | RequestNumber++; | 381 | RequestNumber++; |
380 | 382 | ||
@@ -430,7 +432,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
430 | psEvArgs.Request(psreq.RequestID, keysvals); | 432 | psEvArgs.Request(psreq.RequestID, keysvals); |
431 | } | 433 | } |
432 | 434 | ||
433 | m_PollServiceManager.Enqueue(psreq); | 435 | PollServiceRequestManager.Enqueue(psreq); |
434 | } | 436 | } |
435 | else | 437 | else |
436 | { | 438 | { |
@@ -492,8 +494,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
492 | try | 494 | try |
493 | { | 495 | { |
494 | byte[] buffer500 = SendHTML500(response); | 496 | byte[] buffer500 = SendHTML500(response); |
495 | response.Body.Write(buffer500,0,buffer500.Length); | 497 | response.OutputStream.Write(buffer500, 0, buffer500.Length); |
496 | response.Body.Close(); | 498 | response.Send(); |
497 | } | 499 | } |
498 | catch | 500 | catch |
499 | { | 501 | { |
@@ -691,6 +693,23 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
691 | 693 | ||
692 | if (buffer != null) | 694 | if (buffer != null) |
693 | { | 695 | { |
696 | if (WebUtil.DebugLevel >= 5) | ||
697 | { | ||
698 | string output = System.Text.Encoding.UTF8.GetString(buffer); | ||
699 | |||
700 | if (WebUtil.DebugLevel >= 6) | ||
701 | { | ||
702 | // Always truncate binary blobs. We don't have a ContentType, so detect them using the request name. | ||
703 | if ((requestHandler != null && requestHandler.Name == "GetMesh")) | ||
704 | { | ||
705 | if (output.Length > WebUtil.MaxRequestDiagLength) | ||
706 | output = output.Substring(0, WebUtil.MaxRequestDiagLength) + "..."; | ||
707 | } | ||
708 | } | ||
709 | |||
710 | WebUtil.LogResponseDetail(RequestNumber, output); | ||
711 | } | ||
712 | |||
694 | if (!response.SendChunked && response.ContentLength64 <= 0) | 713 | if (!response.SendChunked && response.ContentLength64 <= 0) |
695 | response.ContentLength64 = buffer.LongLength; | 714 | response.ContentLength64 = buffer.LongLength; |
696 | 715 | ||
@@ -721,16 +740,16 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
721 | } | 740 | } |
722 | catch (IOException e) | 741 | catch (IOException e) |
723 | { | 742 | { |
724 | m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e); | 743 | m_log.Error("[BASE HTTP SERVER]: HandleRequest() threw exception ", e); |
725 | } | 744 | } |
726 | catch (Exception e) | 745 | catch (Exception e) |
727 | { | 746 | { |
728 | m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e); | 747 | m_log.Error("[BASE HTTP SERVER]: HandleRequest() threw exception ", e); |
729 | try | 748 | try |
730 | { | 749 | { |
731 | byte[] buffer500 = SendHTML500(response); | 750 | byte[] buffer500 = SendHTML500(response); |
732 | response.Body.Write(buffer500, 0, buffer500.Length); | 751 | response.OutputStream.Write(buffer500, 0, buffer500.Length); |
733 | response.Body.Close(); | 752 | response.Send(); |
734 | } | 753 | } |
735 | catch | 754 | catch |
736 | { | 755 | { |
@@ -744,7 +763,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
744 | if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture")) | 763 | if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture")) |
745 | { | 764 | { |
746 | m_log.InfoFormat( | 765 | m_log.InfoFormat( |
747 | "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms", | 766 | "[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms", |
748 | RequestNumber, | 767 | RequestNumber, |
749 | requestMethod, | 768 | requestMethod, |
750 | uriString, | 769 | uriString, |
@@ -756,7 +775,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
756 | else if (DebugLevel >= 4) | 775 | else if (DebugLevel >= 4) |
757 | { | 776 | { |
758 | m_log.DebugFormat( | 777 | m_log.DebugFormat( |
759 | "[BASE HTTP SERVER]: HTTP IN {0} :{1} took {2}ms", | 778 | "[LOGHTTP] HTTP IN {0} :{1} took {2}ms", |
760 | RequestNumber, | 779 | RequestNumber, |
761 | Port, | 780 | Port, |
762 | tickdiff); | 781 | tickdiff); |
@@ -767,7 +786,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
767 | private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler) | 786 | private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler) |
768 | { | 787 | { |
769 | m_log.DebugFormat( | 788 | m_log.DebugFormat( |
770 | "[BASE HTTP SERVER]: HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}", | 789 | "[LOGHTTP] HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}", |
771 | RequestNumber, | 790 | RequestNumber, |
772 | Port, | 791 | Port, |
773 | request.HttpMethod, | 792 | request.HttpMethod, |
@@ -783,7 +802,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
783 | private void LogIncomingToContentTypeHandler(OSHttpRequest request) | 802 | private void LogIncomingToContentTypeHandler(OSHttpRequest request) |
784 | { | 803 | { |
785 | m_log.DebugFormat( | 804 | m_log.DebugFormat( |
786 | "[BASE HTTP SERVER]: HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}", | 805 | "[LOGHTTP] HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}", |
787 | RequestNumber, | 806 | RequestNumber, |
788 | Port, | 807 | Port, |
789 | string.IsNullOrEmpty(request.ContentType) ? "not set" : request.ContentType, | 808 | string.IsNullOrEmpty(request.ContentType) ? "not set" : request.ContentType, |
@@ -798,7 +817,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
798 | private void LogIncomingToXmlRpcHandler(OSHttpRequest request) | 817 | private void LogIncomingToXmlRpcHandler(OSHttpRequest request) |
799 | { | 818 | { |
800 | m_log.DebugFormat( | 819 | m_log.DebugFormat( |
801 | "[BASE HTTP SERVER]: HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}", | 820 | "[LOGHTTP] HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}", |
802 | RequestNumber, | 821 | RequestNumber, |
803 | Port, | 822 | Port, |
804 | request.HttpMethod, | 823 | request.HttpMethod, |
@@ -811,29 +830,49 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
811 | 830 | ||
812 | private void LogIncomingInDetail(OSHttpRequest request) | 831 | private void LogIncomingInDetail(OSHttpRequest request) |
813 | { | 832 | { |
814 | using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8)) | 833 | if (request.ContentType == "application/octet-stream") |
815 | { | 834 | return; // never log these; they're just binary data |
816 | string output; | ||
817 | 835 | ||
818 | if (DebugLevel == 5) | 836 | Stream inputStream = Util.Copy(request.InputStream); |
837 | Stream innerStream = null; | ||
838 | try | ||
839 | { | ||
840 | if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip")) | ||
819 | { | 841 | { |
820 | const int sampleLength = 80; | 842 | innerStream = inputStream; |
821 | char[] sampleChars = new char[sampleLength + 3]; | 843 | inputStream = new GZipStream(innerStream, System.IO.Compression.CompressionMode.Decompress); |
822 | reader.Read(sampleChars, 0, sampleLength); | ||
823 | sampleChars[80] = '.'; | ||
824 | sampleChars[81] = '.'; | ||
825 | sampleChars[82] = '.'; | ||
826 | output = new string(sampleChars); | ||
827 | } | 844 | } |
828 | else | 845 | |
846 | using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8)) | ||
829 | { | 847 | { |
830 | output = reader.ReadToEnd(); | 848 | string output; |
831 | } | 849 | |
850 | if (DebugLevel == 5) | ||
851 | { | ||
852 | char[] chars = new char[WebUtil.MaxRequestDiagLength + 1]; // +1 so we know to add "..." only if needed | ||
853 | int len = reader.Read(chars, 0, WebUtil.MaxRequestDiagLength + 1); | ||
854 | output = new string(chars, 0, Math.Min(len, WebUtil.MaxRequestDiagLength)); | ||
855 | if (len > WebUtil.MaxRequestDiagLength) | ||
856 | output += "..."; | ||
857 | } | ||
858 | else | ||
859 | { | ||
860 | output = reader.ReadToEnd(); | ||
861 | } | ||
832 | 862 | ||
833 | m_log.DebugFormat("[BASE HTTP SERVER]: {0}", output.Replace("\n", @"\n")); | 863 | m_log.DebugFormat("[LOGHTTP] {0}", Util.BinaryToASCII(output)); |
864 | } | ||
865 | } | ||
866 | finally | ||
867 | { | ||
868 | if (innerStream != null) | ||
869 | innerStream.Dispose(); | ||
870 | inputStream.Dispose(); | ||
834 | } | 871 | } |
835 | } | 872 | } |
836 | 873 | ||
874 | private readonly string HANDLER_SEPARATORS = "/?&#-"; | ||
875 | |||
837 | private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler) | 876 | private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler) |
838 | { | 877 | { |
839 | string bestMatch = null; | 878 | string bestMatch = null; |
@@ -842,7 +881,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
842 | { | 881 | { |
843 | foreach (string pattern in m_streamHandlers.Keys) | 882 | foreach (string pattern in m_streamHandlers.Keys) |
844 | { | 883 | { |
845 | if (handlerKey.StartsWith(pattern)) | 884 | if ((handlerKey == pattern) |
885 | || (handlerKey.StartsWith(pattern) && (HANDLER_SEPARATORS.IndexOf(handlerKey[pattern.Length]) >= 0))) | ||
846 | { | 886 | { |
847 | if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) | 887 | if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) |
848 | { | 888 | { |
@@ -872,7 +912,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
872 | { | 912 | { |
873 | foreach (string pattern in m_pollHandlers.Keys) | 913 | foreach (string pattern in m_pollHandlers.Keys) |
874 | { | 914 | { |
875 | if (handlerKey.StartsWith(pattern)) | 915 | if ((handlerKey == pattern) |
916 | || (handlerKey.StartsWith(pattern) && (HANDLER_SEPARATORS.IndexOf(handlerKey[pattern.Length]) >= 0))) | ||
876 | { | 917 | { |
877 | if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) | 918 | if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) |
878 | { | 919 | { |
@@ -904,7 +945,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
904 | { | 945 | { |
905 | foreach (string pattern in m_HTTPHandlers.Keys) | 946 | foreach (string pattern in m_HTTPHandlers.Keys) |
906 | { | 947 | { |
907 | if (handlerKey.StartsWith(pattern)) | 948 | if ((handlerKey == pattern) |
949 | || (handlerKey.StartsWith(pattern) && (HANDLER_SEPARATORS.IndexOf(handlerKey[pattern.Length]) >= 0))) | ||
908 | { | 950 | { |
909 | if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) | 951 | if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) |
910 | { | 952 | { |
@@ -953,16 +995,33 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
953 | /// <param name="response"></param> | 995 | /// <param name="response"></param> |
954 | private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) | 996 | private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) |
955 | { | 997 | { |
998 | String requestBody; | ||
999 | |||
956 | Stream requestStream = request.InputStream; | 1000 | Stream requestStream = request.InputStream; |
1001 | Stream innerStream = null; | ||
1002 | try | ||
1003 | { | ||
1004 | if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip")) | ||
1005 | { | ||
1006 | innerStream = requestStream; | ||
1007 | requestStream = new GZipStream(innerStream, System.IO.Compression.CompressionMode.Decompress); | ||
1008 | } | ||
957 | 1009 | ||
958 | Encoding encoding = Encoding.UTF8; | 1010 | using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8)) |
959 | StreamReader reader = new StreamReader(requestStream, encoding); | 1011 | { |
1012 | requestBody = reader.ReadToEnd(); | ||
1013 | } | ||
1014 | } | ||
1015 | finally | ||
1016 | { | ||
1017 | if (innerStream != null) | ||
1018 | innerStream.Dispose(); | ||
1019 | requestStream.Dispose(); | ||
1020 | } | ||
960 | 1021 | ||
961 | string requestBody = reader.ReadToEnd(); | ||
962 | reader.Close(); | ||
963 | requestStream.Close(); | ||
964 | //m_log.Debug(requestBody); | 1022 | //m_log.Debug(requestBody); |
965 | requestBody = requestBody.Replace("<base64></base64>", ""); | 1023 | requestBody = requestBody.Replace("<base64></base64>", ""); |
1024 | |||
966 | string responseString = String.Empty; | 1025 | string responseString = String.Empty; |
967 | XmlRpcRequest xmlRprcRequest = null; | 1026 | XmlRpcRequest xmlRprcRequest = null; |
968 | 1027 | ||
@@ -1073,18 +1132,16 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1073 | 1132 | ||
1074 | response.ContentType = "text/xml"; | 1133 | response.ContentType = "text/xml"; |
1075 | using (MemoryStream outs = new MemoryStream()) | 1134 | using (MemoryStream outs = new MemoryStream()) |
1135 | using (XmlTextWriter writer = new XmlTextWriter(outs, UTF8NoBOM)) | ||
1076 | { | 1136 | { |
1077 | using (XmlTextWriter writer = new XmlTextWriter(outs, Encoding.UTF8)) | 1137 | writer.Formatting = Formatting.None; |
1138 | XmlRpcResponseSerializer.Singleton.Serialize(writer, xmlRpcResponse); | ||
1139 | writer.Flush(); | ||
1140 | outs.Flush(); | ||
1141 | outs.Position = 0; | ||
1142 | using (StreamReader sr = new StreamReader(outs)) | ||
1078 | { | 1143 | { |
1079 | writer.Formatting = Formatting.None; | 1144 | responseString = sr.ReadToEnd(); |
1080 | XmlRpcResponseSerializer.Singleton.Serialize(writer, xmlRpcResponse); | ||
1081 | writer.Flush(); | ||
1082 | outs.Flush(); | ||
1083 | outs.Position = 0; | ||
1084 | using (StreamReader sr = new StreamReader(outs)) | ||
1085 | { | ||
1086 | responseString = sr.ReadToEnd(); | ||
1087 | } | ||
1088 | } | 1145 | } |
1089 | } | 1146 | } |
1090 | } | 1147 | } |
@@ -1842,10 +1899,17 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1842 | 1899 | ||
1843 | public void Start() | 1900 | public void Start() |
1844 | { | 1901 | { |
1845 | StartHTTP(); | 1902 | Start(true); |
1846 | } | 1903 | } |
1847 | 1904 | ||
1848 | private void StartHTTP() | 1905 | /// <summary> |
1906 | /// Start the http server | ||
1907 | /// </summary> | ||
1908 | /// <param name='processPollRequestsAsync'> | ||
1909 | /// If true then poll responses are performed asynchronsly. | ||
1910 | /// Option exists to allow regression tests to perform processing synchronously. | ||
1911 | /// </param> | ||
1912 | public void Start(bool performPollResponsesAsync) | ||
1849 | { | 1913 | { |
1850 | m_log.InfoFormat( | 1914 | m_log.InfoFormat( |
1851 | "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); | 1915 | "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); |
@@ -1883,8 +1947,14 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1883 | m_httpListener2.Start(64); | 1947 | m_httpListener2.Start(64); |
1884 | 1948 | ||
1885 | // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events | 1949 | // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events |
1950 | <<<<<<< HEAD | ||
1951 | PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000); | ||
1952 | PollServiceRequestManager.Start(); | ||
1953 | |||
1954 | ======= | ||
1886 | m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000); | 1955 | m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000); |
1887 | m_PollServiceManager.Start(); | 1956 | m_PollServiceManager.Start(); |
1957 | >>>>>>> avn/ubitvar | ||
1888 | HTTPDRunning = true; | 1958 | HTTPDRunning = true; |
1889 | 1959 | ||
1890 | //HttpListenerContext context; | 1960 | //HttpListenerContext context; |
@@ -1955,7 +2025,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1955 | 2025 | ||
1956 | try | 2026 | try |
1957 | { | 2027 | { |
1958 | m_PollServiceManager.Stop(); | 2028 | PollServiceRequestManager.Stop(); |
1959 | 2029 | ||
1960 | m_httpListener2.ExceptionThrown -= httpServerException; | 2030 | m_httpListener2.ExceptionThrown -= httpServerException; |
1961 | //m_httpListener2.DisconnectHandler = null; | 2031 | //m_httpListener2.DisconnectHandler = null; |