diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs index 0e96537b99..c59f614c92 100755 --- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs @@ -234,6 +234,7 @@ namespace OpenSim.Framework.Monitoring args["GeoPrims"] = OSD.FromString(String.Format("{0:0.#}", data[(int)StatsIndex.TotalGeoPrim])); args["Mesh Objects"] = OSD.FromString(String.Format("{0:0.##}", data[(int)StatsIndex.TotalMesh])); args["Script Engine Thread Count"] = OSD.FromString(String.Format("{0:0.#}", data[(int)StatsIndex.ScriptEngineThreadCount])); + args["RegionName"] = sdata.RegionName; } else args["Error"] = "No Region data"; @@ -246,7 +247,6 @@ namespace OpenSim.Framework.Monitoring args["Memory"] = OSD.FromString(base.XReport(uptime, version)); args["Uptime"] = OSD.FromString(uptime); args["Version"] = OSD.FromString(version); - args["RegionName"] = sdata.RegionName; return args; } diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs index 1b9928b838..4247b4ee21 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpClientContext.cs @@ -112,12 +112,12 @@ namespace OSHttpServer LocalIPEndPoint = remoteEndPoint; m_log = m_logWriter; m_isClosing = false; + m_currentRequest = new HttpRequest(this); m_parser = new HttpRequestParser(m_log); m_parser.RequestCompleted += OnRequestCompleted; m_parser.RequestLineReceived += OnRequestLine; m_parser.HeaderReceived += OnHeaderReceived; m_parser.BodyBytesReceived += OnBodyBytesReceived; - m_currentRequest = new HttpRequest(this); IsSecured = secured; m_stream = stream; m_sock = sock; @@ -215,7 +215,6 @@ namespace OSHttpServer { LogWriter.Write(this, LogPrio.Debug, err.ToString()); } - //Task.Run(async () => await ReceiveLoop()).ConfigureAwait(false); } /// @@ -248,9 +247,9 @@ namespace OSHttpServer HttpRequest req = m_requests.Dequeue(); req.Clear(); } + m_requests = null; } - m_requests.Clear(); - m_requests = null; + m_parser.Clear(); FirstRequestLineReceived = false; @@ -420,91 +419,12 @@ namespace OSHttpServer //Disconnect(SocketError.NoRecovery); Disconnect(SocketError.Success); // try to flush } - catch (IOException err) + catch (HttpException err) { - LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); - if (err.InnerException is SocketException) - Disconnect((SocketError)((SocketException)err.InnerException).ErrorCode); - else - Disconnect(SocketError.ConnectionReset); - } - catch (ObjectDisposedException err) - { - LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : " + err.Message); - Disconnect(SocketError.NotSocket); - } - catch (NullReferenceException err) - { - LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : NullRef: " + err.Message); - Disconnect(SocketError.NoRecovery); - } - catch (Exception err) - { - LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); - Disconnect(SocketError.NoRecovery); - } - } - - /* - private async Task ReceiveLoop() - { - m_ReceiveBytesLeft = 0; - try - { - while(true) - { - if (m_stream == null || !m_stream.CanRead) - return; - - int bytesRead = await m_stream.ReadAsync(m_ReceiveBuffer, m_ReceiveBytesLeft, m_ReceiveBuffer.Length - m_ReceiveBytesLeft).ConfigureAwait(false); - - if (bytesRead == 0) - { - Disconnect(SocketError.Success); - return; - } - - if(m_isClosing) - continue; - - m_ReceiveBytesLeft += bytesRead; - - int offset = m_parser.Parse(m_ReceiveBuffer, 0, m_ReceiveBytesLeft); - if (m_stream == null) - return; // "Connection: Close" in effect. - - while (offset != 0) - { - int nextBytesleft = m_ReceiveBytesLeft - offset; - if(nextBytesleft <= 0) - break; - - int nextOffset = m_parser.Parse(m_ReceiveBuffer, offset, nextBytesleft); - - if (m_stream == null) - return; // "Connection: Close" in effect. - - if (nextOffset == 0) - break; - - offset = nextOffset; - } - - // copy unused bytes to the beginning of the array - if (offset > 0 && m_ReceiveBytesLeft > offset) - Buffer.BlockCopy(m_ReceiveBuffer, offset, m_ReceiveBuffer, 0, m_ReceiveBytesLeft - offset); - - m_ReceiveBytesLeft -= offset; - if (StreamPassedOff) - return; //? - } - } - catch (BadRequestException err) - { - LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err); + LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err.Message); try { - Respond("HTTP/1.1", HttpStatusCode.BadRequest, err.Message); + Respond("HTTP/1.1", err.HttpStatusCode, err.Message); } catch (Exception err2) { @@ -537,7 +457,6 @@ namespace OSHttpServer Disconnect(SocketError.NoRecovery); } } - */ private void OnRequestCompleted(object source, EventArgs args) { @@ -546,7 +465,7 @@ namespace OSHttpServer FullRequestReceived = true; LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount(); - if (m_maxRequests == 0) + if (m_maxRequests <= 0 || RequestReceived == null) return; if (--m_maxRequests == 0) @@ -573,22 +492,20 @@ namespace OSHttpServer m_currentRequest.Body.Seek(0, SeekOrigin.Begin); - bool donow = true; + HttpRequest currentRequest = m_currentRequest; + m_currentRequest = new HttpRequest(this); + lock (m_requestsLock) { if(m_waitingResponse) { - m_requests.Enqueue(m_currentRequest); - donow = false; + m_requests.Enqueue(currentRequest); + return; } else m_waitingResponse = true; } - - if(donow) - RequestReceived?.Invoke(this, new RequestEventArgs(m_currentRequest)); - - m_currentRequest = new HttpRequest(this); + RequestReceived?.Invoke(this, new RequestEventArgs(currentRequest)); } public void StartSendResponse(HttpResponse response) diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpListener.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpListener.cs index 8f5916d07b..7ebadba9e7 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpListener.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpListener.cs @@ -146,6 +146,8 @@ namespace OSHttpServer return; } + socket.NoDelay = true; + if (!OnAcceptingSocket(socket)) { socket.Disconnect(true); @@ -154,9 +156,7 @@ namespace OSHttpServer if(socket.Connected) { - socket.NoDelay = true; - - m_logWriter.Write(this, LogPrio.Debug, "Accepted connection from: " + socket.RemoteEndPoint); + m_logWriter.Write(this, LogPrio.Debug, "Accepted connection from: " + socket.RemoteEndPoint); if (m_certificate != null) m_contextFactory.CreateSecureContext(socket, m_certificate, m_sslProtocol, m_clientCertValCallback); @@ -201,9 +201,13 @@ namespace OSHttpServer /// true if connection can be accepted; otherwise false. protected bool OnAcceptingSocket(Socket socket) { - ClientAcceptedEventArgs args = new ClientAcceptedEventArgs(socket); - Accepted?.Invoke(this, args); - return !args.Revoked; + if(Accepted!=null) + { + ClientAcceptedEventArgs args = new ClientAcceptedEventArgs(socket); + Accepted?.Invoke(this, args); + return !args.Revoked; + } + return true; } /// diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequest.cs index 28c97ffd6d..cfc886c4b7 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequest.cs @@ -31,7 +31,7 @@ namespace OSHttpServer private NameValueCollection m_queryString = null; private Uri m_uri = null; private string m_uriPath; - public readonly IHttpClientContext m_context; + public IHttpClientContext m_context; IPEndPoint m_remoteIPEndPoint = null; public HttpRequest(IHttpClientContext pContext) @@ -340,6 +340,8 @@ namespace OSHttpServer case "content-length": if (!int.TryParse(value, out int t)) throw new BadRequestException("Invalid content length."); + if (t > 250 * 1024 * 1024) + throw new OSHttpServer.Exceptions.HttpException(HttpStatusCode.RequestEntityTooLarge,"Request Entity Too Large"); ContentLength = t; break; //todo: maybe throw an exception case "host": @@ -458,9 +460,11 @@ namespace OSHttpServer /// public void Clear() { - if (m_body != null && m_body.CanRead) + if (m_body != null) + { m_body.Dispose(); - m_body = null; + m_body = null; + } m_contentLength = 0; m_method = string.Empty; m_uri = null; @@ -469,6 +473,7 @@ namespace OSHttpServer m_headers.Clear(); m_connection = ConnectionType.KeepAlive; IsAjax = false; + m_context = null; //_form.Clear(); } diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequestParser.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequestParser.cs index a339e2baec..470596e59d 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequestParser.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer/HttpRequestParser.cs @@ -10,8 +10,8 @@ namespace OSHttpServer.Parser public class HttpRequestParser : IHttpRequestParser { private ILogWriter m_log; - private readonly BodyEventArgs m_bodyArgs = new BodyEventArgs(); private readonly HeaderEventArgs m_headerArgs = new HeaderEventArgs(); + private readonly BodyEventArgs m_bodyEventArgs = new BodyEventArgs(); private readonly RequestLineEventArgs m_requestLineArgs = new RequestLineEventArgs(); private string m_curHeaderName = string.Empty; private string m_curHeaderValue = string.Empty; @@ -52,13 +52,18 @@ namespace OSHttpServer.Parser private int AddToBody(byte[] buffer, int offset, int count) { // got all bytes we need, or just a few of them? - int bytesUsed = count > m_bodyBytesLeft ? m_bodyBytesLeft : count; - m_bodyArgs.Buffer = buffer; - m_bodyArgs.Offset = offset; - m_bodyArgs.Count = bytesUsed; - BodyBytesReceived?.Invoke(this, m_bodyArgs); + int bytesCount = count > m_bodyBytesLeft ? m_bodyBytesLeft : count; - m_bodyBytesLeft -= bytesUsed; + if(BodyBytesReceived != null) + { + m_bodyEventArgs.Buffer = buffer; + m_bodyEventArgs.Offset = offset; + m_bodyEventArgs.Count = bytesCount; + BodyBytesReceived?.Invoke(this, m_bodyEventArgs); + m_bodyEventArgs.Buffer = null; + } + + m_bodyBytesLeft -= bytesCount; if (m_bodyBytesLeft == 0) { // got a complete request. @@ -67,7 +72,7 @@ namespace OSHttpServer.Parser Clear(); } - return offset + bytesUsed; + return offset + bytesCount; } /// @@ -139,10 +144,13 @@ namespace OSHttpServer.Parser throw new BadRequestException("Invalid HTTP version in Request line. Line: " + value); } - m_requestLineArgs.HttpMethod = method; - m_requestLineArgs.HttpVersion = version; - m_requestLineArgs.UriPath = path; - RequestLineReceived(this, m_requestLineArgs); + if(RequestLineReceived != null) + { + m_requestLineArgs.HttpMethod = method; + m_requestLineArgs.HttpVersion = version; + m_requestLineArgs.UriPath = path; + RequestLineReceived?.Invoke(this, m_requestLineArgs); + } } /// @@ -151,17 +159,23 @@ namespace OSHttpServer.Parser /// Name in lower case /// Value, unmodified. /// If content length cannot be parsed. - protected void OnHeader(string name, string value) + protected void OnHeader() { - m_headerArgs.Name = name; - m_headerArgs.Value = value; - if (string.Compare(name, "content-length", true) == 0) + if (string.Compare(m_curHeaderName, "content-length", true) == 0) { - if (!int.TryParse(value, out m_bodyBytesLeft)) + if (!int.TryParse(m_curHeaderValue, out m_bodyBytesLeft)) throw new BadRequestException("Content length is not a number."); } - HeaderReceived?.Invoke(this, m_headerArgs); + if (HeaderReceived != null) + { + m_headerArgs.Name = m_curHeaderName; + m_headerArgs.Value = m_curHeaderValue; + HeaderReceived?.Invoke(this, m_headerArgs); + } + + m_curHeaderName = string.Empty; + m_curHeaderValue = string.Empty; } private void OnRequestCompleted() @@ -372,12 +386,10 @@ namespace OSHttpServer.Parser { m_curHeaderValue += Encoding.UTF8.GetString(buffer, startPos, currentPos - startPos); m_log.Write(this, LogPrio.Trace, "Header [" + m_curHeaderName + ": " + m_curHeaderValue + "]"); - OnHeader(m_curHeaderName, m_curHeaderValue); + OnHeader(); startPos = -1; CurrentState = RequestParserState.HeaderName; - m_curHeaderValue = string.Empty; - m_curHeaderName = string.Empty; currentPos += newLineSize - 1; handledBytes = currentPos + 1; diff --git a/OpenSim/Framework/Servers/HttpServer/SimpleStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/SimpleStreamHandler.cs index cf32ce6158..18b282a82a 100644 --- a/OpenSim/Framework/Servers/HttpServer/SimpleStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/SimpleStreamHandler.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Net; using OpenSim.Framework.ServiceAuth;