Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WebData"/> class.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="stopWatch">The stopwatch.</param>
        internal WebData(WebRequest request, Stopwatch stopWatch)
        {
            StopWatch = stopWatch;
            Request   = request;
            Result    = new WebResultBuilder(request);

            // check for method call
            {
                string url = request.DecodedUrl.TrimEnd('/');
                if (url.Length == 0)
                {
                    url = "/";
                }
                Method = request.Server.FindMethod(url);
                if (Method != null)
                {
                    Trace.TraceInformation("Method Call: {0} Url: {1} {2}", Method, Request, Session);
                }
            }
        }
Example #2
0
        /// <summary>Handles a client stage1 (preparations).</summary>
        /// <remarks>Performs the firewall checks and enters stage2.</remarks>
        internal void HandleClient(WebServerClient client)
        {
            System.Globalization.CultureInfo threadCulture = Thread.CurrentThread.CurrentCulture;
            int threadId            = Thread.CurrentThread.ManagedThreadId;
            WebResultBuilder result = null;

            try
            {
                // callback for connected client
                ClientConnected?.Invoke(this, new WebClientEventArgs(client));

                // do request handling
                int requestNumber = 0;
                if (PerformanceChecks)
                {
                    Trace.TraceInformation(
                        $"HandleClient [{threadId}] <cyan>{client.RemoteEndPoint}<default> ready to receive request. " +
                        $"Elapsed <cyan>{client.StopWatch.Elapsed.FormatTime()}<default>.");
                }
                while (client.IsConnected)
                {
                    result = null;
                    if (PerformanceChecks && requestNumber > 0)
                    {
                        Trace.TraceInformation(
                            $"HandleClient [{threadId}] <cyan>{client.RemoteEndPoint}<default> request <green>{requestNumber}<default> handling completed. " +
                            $"Elapsed <cyan>{client.StopWatch.Elapsed.FormatTime()}<default>.");
                    }

                    // read first request line
                    string firstLine = client.Reader.ReadLine();
                    client.StopWatch.Reset();
                    if (PerformanceChecks)
                    {
                        Trace.TraceInformation(
                            $"HandleClient [{threadId}] <cyan>{client.RemoteEndPoint}<default> start handling request <cyan>{++requestNumber}<default>. " +
                            $"Elapsed <cyan>{client.StopWatch.Elapsed.FormatTime()}<default>.");
                    }

                    // load request
                    var request = WebRequest.Load(this, firstLine, client);

                    // prepare web data object
                    var data = new WebData(request, client.StopWatch);
                    result = data.Result;

                    // update thread culture
                    Thread.CurrentThread.CurrentCulture = data.Request.Culture;

                    // handle request but change some default exceptions to web exceptions
                    try { HandleRequest(client, data); }
                    catch (ObjectDisposedException)
                    {
                        Trace.TraceInformation($"HandleClient [{threadId}] <red>{client.RemoteEndPoint}<default> Connection closed");
                    }
                    catch (InvalidOperationException ex) { throw new WebServerException(ex, WebError.InvalidOperation, 0, ex.Message); }
                    catch (ArgumentException ex) { throw new WebServerException(ex, WebError.InvalidParameters, 0, ex.Message); }
                }
            }
            catch (WebServerException ex)
            {
                Trace.TraceInformation(ex.ToString());
                if (result == null)
                {
                    result = new WebResultBuilder(this);
                }

                result.AddMessage(WebMessage.Create(ex));
                if (ex.Error == WebError.AuthenticationRequired || ex.Error == WebError.InvalidTransactionKey)
                {
                    result.Headers["WWW-Authenticate"] = $"Basic realm=\"{AssemblyVersionInfo.Program.Company} - {AssemblyVersionInfo.Program.Product}\"";
                }
                result.CloseAfterAnswer = true;
                client.SendAnswer(result.ToAnswer());
            }
            catch (SocketException)
            {
                Trace.TraceInformation($"HandleClient [{threadId}] <red>{client.RemoteEndPoint}<default> Connection closed");
                /*client closed connection*/
            }
            catch (EndOfStreamException)
            {
                /*client closed connection*/
                Trace.TraceInformation($"HandleClient [{threadId}] <red>{client.RemoteEndPoint}<default> Connection closed");
            }
            catch (Exception ex)
            {
                if (ex.InnerException is SocketException)
                {
                    Trace.TraceInformation($"HandleClient [{threadId}] <red>{client.RemoteEndPoint}<default> Connection closed");
                    return;
                }

                string supportCode = Base32.Safe.Encode(Environment.TickCount);
                Trace.TraceError("<red>Unhandled Internal Server Error<default> Code {1}\n{0}", ex.ToString(), supportCode);

                if (result == null)
                {
                    result = new WebResultBuilder(this);
                }

                result.AddMessage(ex.Source, WebError.InternalServerError, $"Internal Server Error\nUnexpected result on request.\nPlease contact support!\nSupport Code = {supportCode}");
                result.CloseAfterAnswer = true;
                client.SendAnswer(result.ToAnswer());
            }
            finally
            {
                while (client.IsConnected && client.Reader.Available == 0)
                {
                    Thread.Sleep(1);
                }

                client.Close();
                if (client != null)
                {
                    ClientDisconnected?.Invoke(this, new WebClientEventArgs(client));
                }

                // reset thread culture
                if (Thread.CurrentThread.CurrentCulture != threadCulture)
                {
                    Thread.CurrentThread.CurrentCulture = threadCulture;
                }
            }
        }
Example #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WebData"/> class.
 /// </summary>
 /// <param name="server">The server.</param>
 /// <param name="stopWatch">The stop watch.</param>
 internal WebData(WebServer server, Stopwatch stopWatch)
 {
     StopWatch = stopWatch;
     Result    = new WebResultBuilder(server);
 }