protected virtual ValueTask <bool> LoadContent(WebProgressTask task, NetworkReader reader)
        {
            if (!task.Request.HeaderParameter.TryGetValue("Content-Length", out string?strLength))
            {
                return(new ValueTask <bool>(true));
            }

            if (!int.TryParse(strLength, out int length) || length < 0)
            {
                WebServerLog.Add(ServerLogType.Error, GetType(), "Header", "Bad Request, invalid content length");
                task.Response.StatusCode = HttpStateCode.BadRequest;
                task.NextStage           = ServerStage.CreateResponse;
                return(new ValueTask <bool>(false));
            }

            var content = new IO.ContentStream(reader, length);

            task.Request.Post.SetPost(
                task,
                content,
                task.Request.HeaderParameter.TryGetValue("Content-Type", out string?contentType)
                    ? contentType : null
                );

            return(new ValueTask <bool>(true));
        }
예제 #2
0
        protected virtual void SecureMainTask()
        {
            WebServerLog.Add(ServerLogType.Information, GetType(), "StartUp", "Secure Server succesfuly started");
            var watch = new Stopwatch();

            while (ServerExecution)
            {
                watch.Restart();
                //pending connection
                int step = 0;
                for (; step < 10; step++)
                {
                    if (!SecureListener !.Pending())
                    {
                        break;
                    }
                    SecureClientConnected(SecureListener.AcceptTcpClient());
                }
                //wait
                if (SecureListener !.Pending())
                {
                    continue;
                }
                var time = watch.ElapsedMilliseconds % 20;
                Thread.Sleep(20 - (int)time);
            }
            watch.Stop();
            SecureListener !.Stop();
            WebServerLog.Add(ServerLogType.Information, GetType(), "StartUp", "Secure Server succesfuly stopped");
        }
        protected virtual async ValueTask <string?> ReadLine(WebProgressTask task,
                                                             NetworkReader reader, long limit, HttpStateCode exceedState
                                                             )
        {
            string?line;

            try { line = await reader.ReadLineAsync(limit).ConfigureAwait(false); }
            catch (IO.ReadLineOverflowException e)
            {
                e.State = exceedState;
                throw;
            }
            catch
            {
                WebServerLog.Add(ServerLogType.Error, GetType(), "Header", "Connection closed by remote host");
                task.Response.StatusCode = HttpStateCode.RequestTimeOut;
                task.NextStage           = ServerStage.FINAL_STAGE;
                return(null);
            }
            if (line == null)
            {
                WebServerLog.Add(ServerLogType.Error, GetType(), "Header", "Can't read Header line");
                task.Response.StatusCode = HttpStateCode.BadRequest;
                task.NextStage           = ServerStage.CreateResponse;
            }
            return(line);
        }
        protected virtual async ValueTask <bool> WaitForData(WebProgressTask task)
        {
            try
            {
                if (task.NetworkStream is NetworkStream ns && !ns.DataAvailable)
                {
                    var maxDelay = MaxConnectionDelay;
                    var maxSlice = TimeSpan.FromMilliseconds(10);
                    while (maxDelay > TimeSpan.Zero && !ns.DataAvailable)
                    {
                        var slice = maxSlice < maxDelay ? maxSlice : maxDelay;
                        await Task.Delay(slice).ConfigureAwait(false);

                        maxDelay -= slice;
                    }
                    if (!ns.DataAvailable)
                    {
                        WebServerLog.Add(ServerLogType.Error, GetType(), "Header", "Request Timeout");
                        task.Request.FieldConnection = HttpConnectionType.KeepAlive;
                        task.Response.StatusCode     = HttpStateCode.RequestTimeOut;
                        task.NextStage = ServerStage.CreateResponse;
                        return(false);
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                WebServerLog.Add(ServerLogType.Error, GetType(), "Header", "Connection closed by remote host");
                task.Response.StatusCode = HttpStateCode.RequestTimeOut;
                task.NextStage           = ServerStage.FINAL_STAGE;
                return(false);
            }
            return(true);
        }
        private void HandleCreateConnection(WebProgressTask task, string responseKey,
                                            IWebSocketEndpoint endpoint, WebSocketConnection connection)
        {
            task.Response.StatusCode = HttpStateCode.SwitchingProtocols;
            task.Response.SetHeader(
                ("Access-Control-Allow-Origin", "*"),
                ("Upgrade", "websocket"),
                ("Connection", "Upgrade"),
                ("Sec-WebSocket-Accept", responseKey),
                ("Sec-WebSocket-Protocol", endpoint.Protocol)
                );

            task.SwitchProtocols(async() =>
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    await connection.HandshakeFinished().ConfigureAwait(false);
                }
                else
                {
                    try
                    {
                        await connection.HandshakeFinished().ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        WebServerLog.Add(ServerLogType.Error, GetType(), "handshake", $"handshake error: {e}");
                    }
                }
            });
            task.NextStage = ServerStage.SendResponse;
        }
예제 #6
0
 protected override async Task ReceiveClose(CloseReason?reason, string?info)
 {
     WebServerLog.Add(ServerLogType.Information, GetType(), "WebSocket", $"client close websocket ({reason}): {info}");
     if (!SendCloseSignal)
     {
         await Close().ConfigureAwait(false);
     }
 }
예제 #7
0
 public override void Stop()
 {
     if (SecureSettings.EnableUnsafePort)
     {
         base.Stop();
     }
     WebServerLog.Add(ServerLogType.Information, GetType(), "StartUp", "Stopped Secure Server");
     ServerExecution = false;
 }
예제 #8
0
        protected override async Task <long> WriteStreamInternal(Stream stream, long start, long?stop)
        {
            long total = 0;
            int  readed;

            byte[] buffer = new byte[ReadBufferLength];
            do
            {
                readed = await BaseStream.ReadAsync(
                    buffer,
                    0,
                    (int)Math.Min(buffer.Length, start - total)
                    ).ConfigureAwait(false);

                total += readed;
            }while (total < start && readed > 0);
            if (readed == 0 && start > 0)
            {
                return(0);
            }
            var ascii = Encoding.ASCII;
            var nl    = ascii.GetBytes("\r\n");

            do
            {
                var read = stop == null
                    ? buffer.Length
                    : (int)Math.Min(buffer.Length, stop.Value - total);
                readed = await BaseStream.ReadAsync(buffer, 0, read).ConfigureAwait(false);

                if (readed <= 0)
                {
                    return(total - start);
                }
                var length = ascii.GetBytes(readed.ToString("X"));
                try
                {
                    await stream.WriteAsync(length, 0, length.Length).ConfigureAwait(false);

                    await stream.WriteAsync(nl, 0, nl.Length).ConfigureAwait(false);

                    await stream.WriteAsync(buffer, 0, readed).ConfigureAwait(false);

                    await stream.WriteAsync(nl, 0, nl.Length).ConfigureAwait(false);

                    total += readed;
                    await stream.FlushAsync().ConfigureAwait(false);
                }
                catch (IOException)
                {
                    WebServerLog.Add(ServerLogType.Information, GetType(), "write", "connection closed");
                    return(total);
                }
            }while (readed > 0);
            return(total - start);
        }
예제 #9
0
 public virtual EventBase?ReadJson(JsonElement json)
 {
     try { ReadJsonContent(json); }
     catch (JsonException e)
     {
         WebServerLog.Add(ServerLogType.Error, GetType(), "read json", "error: {0}", e);
         return(null);
     }
     return(this);
 }
예제 #10
0
        private static void LogMethodNotPublic(MethodInfo method, bool set)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.MethodNotPublic;

            if ((LogBuildWarnings & code) == code && set)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Method {1} ignored because it's not public",
                    method
                    );
            }
        }
예제 #11
0
        public Task AddWebServerLogAsync(string author, WebServerLogType type, string message, int?itemId)
        {
            WebServerLog webServerLog = new WebServerLog();

            webServerLog.Author       = author;
            webServerLog.Message      = message;
            webServerLog.TvItemId     = itemId;
            webServerLog.TimeInserted = DateTime.Now;
            webServerLog.Type         = type;

            Context.Add(webServerLog);
            Context.SaveChanges();

            return(Task.CompletedTask);
        }
예제 #12
0
        private static void LogTypeGeneric(Type type, bool set)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.TypeGeneric;

            if ((LogBuildWarnings & code) == code && set)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Type {1} ignored because it's generic",
                    (int)code,
                    type
                    );
            }
        }
예제 #13
0
        private static void LogTypeNoConstructor(Type type)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.TypeNoConstructor;

            if ((LogBuildWarnings & code) == code)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Type {1} ignored because it has no parameterless constructor",
                    (int)code,
                    type
                    );
            }
        }
예제 #14
0
        private static void LogMethodAbstract(MethodInfo method, bool set)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.MethodAbstract;

            if ((LogBuildWarnings & code) == code && set)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Method {1} ignored because it's abstract",
                    (int)code,
                    method
                    );
            }
        }
예제 #15
0
 public void Set(FileInfo tempFile)
 {
     Content = null;
     if (TempFile != null && TempFile.FullName != tempFile.FullName)
     {
         try
         {
             TempFile.Delete();
         }
         catch (Exception)
         {
             WebServerLog.Add(ServerLogType.Information, GetType(), "POST", "Cannot delete temp file");
         }
     }
     TempFile = tempFile;
 }
예제 #16
0
 public void Set(ReadOnlyMemory <byte> content)
 {
     Content = content;
     if (TempFile != null && TempFile.Exists)
     {
         try
         {
             TempFile.Delete();
         }
         catch (Exception)
         {
             WebServerLog.Add(ServerLogType.Information, GetType(), "POST", "Cannot delete temp file");
         }
     }
     TempFile = null;
 }
예제 #17
0
        private static void LogResultNoConverter(MethodInfo method)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.ResultNoConverter;

            if ((LogBuildWarnings & code) == code)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Method {1} ignored because for the result type is no suitable converter found or set",
                    (int)code,
                    method
                    );
            }
        }
예제 #18
0
 public override void Start()
 {
     if (SecureSettings.EnableUnsafePort)
     {
         base.Start();
     }
     WebServerLog.Add(ServerLogType.Information, GetType(), "StartUp", "Start Secure Server on Port {0}", SecureSettings.SecurePort);
     ServerExecution = true;
     SecureListener  = new TcpListener(new IPEndPoint(Settings.IPFilter, SecureSettings.SecurePort));
     SecureListener.Start();
     SecureServerThread = new Thread(SecureMainTask)
     {
         Name = "SecureServerThread - Port: " + SecureSettings.SecurePort.ToString()
     };
     SecureServerThread.Start();
 }
예제 #19
0
        private static void LogResultInvalidConverterType(MethodInfo method, DataConverterAttribute attr)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.ResultInvalidConverterType;

            if ((LogBuildWarnings & code) == code)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Method {1} ignored because the result data converter {2} has an invalid type provided",
                    (int)code,
                    method,
                    attr
                    );
            }
        }
예제 #20
0
        private static void LogParamNoCoreConverterFound(MethodInfo method, ParameterInfo param)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.ParamNoCoreConverterFound;

            if ((LogBuildWarnings & code) == code)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Method {1} ignored because the core generator cannot convert the type of parameter {2}",
                    (int)code,
                    method,
                    param
                    );
            }
        }
예제 #21
0
        private static void LogResultCannotCreateConverterInstance(MethodInfo method, DataConverterAttribute attr)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.ResultCannotCreateConverterInstance;

            if ((LogBuildWarnings & code) == code)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Method {1} ignored because there cannot be created an instance for the result data converter {2}",
                    (int)code,
                    method,
                    attr.Converter
                    );
            }
        }
예제 #22
0
        private static void LogMethodDeclaredInObject(MethodInfo method)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.MethodDeclaredInObject;

            if ((LogBuildWarnings & code) == code)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Method {1} ignored because is was declared in {2} or {3}",
                    (int)code,
                    method,
                    typeof(object),
                    typeof(Service)
                    );
            }
        }
예제 #23
0
        private static void LogParamMissingConvInstance(MethodInfo method, ParameterInfo param, ConverterAttribute attr)
        {
            const GeneratorLogFlag code = GeneratorLogFlag.ParamMissingConverterInstance;

            if ((LogBuildWarnings & code) == code)
            {
                WebServerLog.Add(
                    ServerLogType.Information,
                    typeof(Generator),
                    "generate class",
                    "[{0:X4}] Method {1} ignored because parameter {2} has no converter instance set for attribute {3}",
                    (int)code,
                    method,
                    param,
                    attr
                    );
            }
        }
        protected virtual bool ParseOtherHeaderLine(WebProgressTask task, string line)
        {
            var ind = line.IndexOf(':');

            if (ind < 0)
            {
                WebServerLog.Add(ServerLogType.Error, GetType(), "Header", "Bad Request");
                task.Response.StatusCode = HttpStateCode.BadRequest;
                task.NextStage           = ServerStage.CreateResponse;
                return(false);
            }

            var key   = line.Remove(ind).Trim();
            var value = line.Substring(ind + 1).Trim();

            task.Request.HeaderParameter.Add(key, value);

            return(true);
        }
        protected virtual bool ParseFirstHeaderLine(WebProgressTask task, string line)
        {
            WebServerLog.Add(ServerLogType.Debug, GetType(), "Header", line);
            var parts = line.Split(' ');

            if (parts.Length != 3)
            {
                WebServerLog.Add(ServerLogType.Error, GetType(), "Header", "Bad Request");
                task.Response.StatusCode = HttpStateCode.BadRequest;
                task.NextStage           = ServerStage.CreateResponse;
                return(false);
            }

            task.Request.ProtocolMethod = parts[0];
            task.Request.Url            = parts[1];
            task.Request.HttpProtocol   = parts[2];

            return(true);
        }
예제 #26
0
        public virtual Frame?ToFrame()
        {
            using var m      = new System.IO.MemoryStream();
            using var writer = new Utf8JsonWriter(m);
            try { WriteJson(writer); }
            catch (JsonException e)
            {
                WebServerLog.Add(ServerLogType.Error, GetType(), "write json", "error: {0}", e);
                return(null);
            }
            writer.Flush();

            var frame = new Frame
            {
                OpCode     = OpCode.Text,
                Payload    = m.ToArray(),
                FinalFrame = true,
            };

            return(frame);
        }
예제 #27
0
        internal async Task Save(string path, DateTime started, WebProgressTask task)
        {
            var callName = SanitizePath(task.Request.Location.DocumentPath);

            if (callName.Length == 0)
            {
                callName = "_";
            }
            var date = started.ToString("yyyy-MM-dd_HH-mm-ss-fffffff");

            var dir = $"{path}/{callName}";

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            var inc  = 1;
            var file = $"{dir}/{date}.log";

            while (File.Exists(file))
            {
                inc++;
                file = $"{dir}/{date}.{inc}.log";
            }

            using var stream = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);
            using var writer = new StreamWriter(stream, Encoding.UTF8);
            try { WriteTo(writer); }
            catch (Exception e)
            {
                WebServerLog.Add(ServerLogType.FatalError, GetType(), "write logs", e.ToString());
                writer.WriteLine(e);
            }
            await writer.FlushAsync();

            writer.Flush();
            await stream.FlushAsync();
        }
예제 #28
0
        public async Task SetAsync(WebProgressTask task, IO.ContentStream content, string options)
        {
            var      match    = charsetRegex.Match(options);
            Encoding?encoding = null;

            if (match.Success)
            {
                try
                {
                    encoding = Encoding.GetEncoding(match.Groups["charset"].Value);
                }
                catch (Exception e)
                {
                    WebServerLog.Add(ServerLogType.Error, GetType(), "SetPost",
                                     $"invalid encoding {match.Groups["charset"].Value}: {e}");
                }
            }
            encoding ??= Encoding.UTF8;
            var buffer = new byte[content.UnreadData];
            await content.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);

            Set(encoding.GetString(buffer), options);
        }
예제 #29
0
 public DualSecureWebServer(DualSecureWebServerSettings settings) : base(settings)
 {
     WebServerLog.Add(ServerLogType.Information, GetType(), "StartUp", "The use of dual mode is critical");
 }
예제 #30
0
        public override async Task ProgressTask(WebProgressTask task)
        {
            var header = task.Response;
            var stream = task.NetworkStream;

            if (stream is null)
            {
                return;
            }
            var writer = new StreamWriter(stream);
            await writer.WriteAsync(header.HttpProtocol).ConfigureAwait(false);

            await writer.WriteAsync(" ").ConfigureAwait(false);

            await writer.WriteAsync(((int)header.StatusCode).ToString()).ConfigureAwait(false);

            await writer.WriteAsync(" ").ConfigureAwait(false);

            await writer.WriteLineAsync(StatusCodeText(header.StatusCode)).ConfigureAwait(false);

            for (int i = 0; i < header.HeaderParameter.Count; ++i) //Parameter
            {
                var e = header.HeaderParameter.ElementAt(i);
                if (e.Key == "Content-Length")
                {
                    continue;
                }
                await writer.WriteAsync(e.Key).ConfigureAwait(false);

                await writer.WriteAsync(": ").ConfigureAwait(false);

                await writer.WriteLineAsync(e.Value).ConfigureAwait(false);
            }
            foreach (var cookie in task.Request.Cookie.AddedCookies) //Cookies
            {
                await writer.WriteAsync("Set-Cookie: ").ConfigureAwait(false);

                await writer.WriteLineAsync(cookie.ToString()).ConfigureAwait(false);
            }
            await writer.WriteLineAsync().ConfigureAwait(false);

            try { await writer.FlushAsync().ConfigureAwait(false); await stream.FlushAsync().ConfigureAwait(false); }
            catch (ObjectDisposedException)
            {
                WebServerLog.Add(ServerLogType.Information, GetType(), "Send", "Connection closed by remote host.");
                return;
            }
            catch (IOException)
            {
                WebServerLog.Add(ServerLogType.Information, GetType(), "Send", "Connection closed by remote host.");
                return;
            }
            //send data
            try
            {
                if (!(task.Document.Information.ContainsKey("Only Header") && (bool)task.Document.Information["Only Header"] !))
                {
                    foreach (var s in task.Document.DataSources)
                    {
                        await SendChunk(writer, stream, s).ConfigureAwait(false);
                    }
                    await writer.WriteLineAsync("0").ConfigureAwait(false);

                    await writer.WriteLineAsync().ConfigureAwait(false);

                    await writer.FlushAsync().ConfigureAwait(false);

                    await stream.FlushAsync().ConfigureAwait(false);
                }
            }
            catch (IOException)
            {
                WebServerLog.Add(ServerLogType.Information, GetType(), "Send", "Connection closed by remote host.");
                return;
            }
        }