From 83d4fa98f0fad183859bba4a70b96733f86262bd Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 11 Sep 2012 21:48:02 +0100 Subject: [PATCH] Add levels 4 and 5 to "debug http" console command that will log a sample of incoming request data and the entire incoming data respectively. See "help debug http" for more details. --- .../Servers/HttpServer/BaseHttpServer.cs | 68 +++++++++++++++---- OpenSim/Framework/Servers/MainServer.cs | 2 + OpenSim/Framework/Util.cs | 32 +++++++++ 3 files changed, 90 insertions(+), 12 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index f57ea76b66..c81e2834c8 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -449,9 +449,7 @@ namespace OpenSim.Framework.Servers.HttpServer if (TryGetStreamHandler(handlerKey, out requestHandler)) { if (DebugLevel >= 3) - m_log.DebugFormat( - "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}", - request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description); + LogIncomingToStreamHandler(request, requestHandler); response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. @@ -563,9 +561,7 @@ namespace OpenSim.Framework.Servers.HttpServer if (DoWeHaveALLSDHandler(request.RawUrl)) { if (DebugLevel >= 3) - m_log.DebugFormat( - "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", - request.ContentType, request.HttpMethod, request.Url.PathAndQuery); + LogIncomingToContentTypeHandler(request); buffer = HandleLLSDRequests(request, response); } @@ -573,18 +569,14 @@ namespace OpenSim.Framework.Servers.HttpServer else if (DoWeHaveAHTTPHandler(request.RawUrl)) { if (DebugLevel >= 3) - m_log.DebugFormat( - "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", - request.ContentType, request.HttpMethod, request.Url.PathAndQuery); + LogIncomingToContentTypeHandler(request); buffer = HandleHTTPRequest(request, response); } else { if (DebugLevel >= 3) - m_log.DebugFormat( - "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}", - request.HttpMethod, request.Url.PathAndQuery); + LogIncomingToXmlRpcHandler(request); // generic login request. buffer = HandleXmlRpcRequests(request, response); @@ -654,6 +646,58 @@ namespace OpenSim.Framework.Servers.HttpServer } } + private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler) + { + m_log.DebugFormat( + "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}", + request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description); + + if (DebugLevel >= 4) + LogIncomingInDetail(request); + } + + private void LogIncomingToContentTypeHandler(OSHttpRequest request) + { + m_log.DebugFormat( + "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", + request.ContentType, request.HttpMethod, request.Url.PathAndQuery); + + if (DebugLevel >= 4) + LogIncomingInDetail(request); + } + + private void LogIncomingToXmlRpcHandler(OSHttpRequest request) + { + m_log.DebugFormat( + "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}", + request.HttpMethod, request.Url.PathAndQuery); + + if (DebugLevel >= 4) + LogIncomingInDetail(request); + } + + private void LogIncomingInDetail(OSHttpRequest request) + { + using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8)) + { + string output; + + if (DebugLevel == 4) + { + const int sampleLength = 80; + char[] sampleChars = new char[sampleLength]; + reader.Read(sampleChars, 0, sampleLength); + output = string.Format("[BASE HTTP SERVER]: {0}...", sampleChars); + } + else + { + output = string.Format("[BASE HTTP SERVER]: {0}", reader.ReadToEnd()); + } + + m_log.Debug(output); + } + } + private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler) { string bestMatch = null; diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index 8dc0e3a71d..1ac0953a64 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs @@ -111,6 +111,8 @@ namespace OpenSim.Framework.Servers + "If level >= 1, then short warnings are logged when receiving bad input data.\n" + "If level >= 2, then long warnings are logged when receiving bad input data.\n" + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n" + + "If level >= 4, then a sample from the beginning of the incoming data is logged.\n" + + "If level >= 5, then the entire incoming data is logged.\n" + "If no level is specified then the current level is returned.", HandleDebugHttpCommand); } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 38cb3a6380..1b9777f10b 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1007,6 +1007,38 @@ namespace OpenSim.Framework } } + /// + /// Copy data from one stream to another, leaving the read position of both streams at the beginning. + /// + /// + /// Input stream. Must be seekable. + /// + /// + /// Thrown if the input stream is not seekable. + /// + public static Stream Copy(Stream inputStream) + { + if (!inputStream.CanSeek) + throw new ArgumentException("Util.Copy(Stream inputStream) must receive an inputStream that can seek"); + + const int readSize = 256; + byte[] buffer = new byte[readSize]; + MemoryStream ms = new MemoryStream(); + + int count = inputStream.Read(buffer, 0, readSize); + + while (count > 0) + { + ms.Write(buffer, 0, count); + count = inputStream.Read(buffer, 0, readSize); + } + + ms.Position = 0; + inputStream.Position = 0; + + return ms; + } + public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args) { return SendXmlRpcCommand(url, methodName, args);