ืึทื•ื•ืึทื ืกื™ืจื˜ืข ื•ื•ืขืœืึธืกื™ืคึผืขื“ ื‘ื ื™ืŸ ืึธื“ืขืจ ืงืœื™ืขื ื˜-ืกืขืจื•ื•ืขืจ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ื‘ืื–ื™ืจื˜ ืื•ื™ืฃ C #. ื ืขื˜ ืคืจื™ื™ืžื•ื•ืขืจืง

ืคึผืึธื–ื™ืฆื™ืข

ืขืก ืึทืœืข ืื ื’ืขื”ื•ื™ื‘ืŸ ื•ื•ืขืŸ ืึท ืงืึธืœืขื’ืข ืกืึทื’ื“ื–ืฉืขืกื˜ื™ื“ ืึทื– ืื™ืš ืžืึทื›ืŸ ืึท ืงืœื™ื™ืŸ ื•ื•ืขื‘ ื“ื™ื ืกื˜. ืขืก ืื™ื– ื’ืขื•ื•ืขืŸ ื’ืขืžื™ื™ื ื˜ ืฆื• ื–ื™ื™ืŸ ืขืคึผืขืก ื•ื•ื™ ื˜ื™ื ื“ืขืจ, ืึธื‘ืขืจ ืคึฟืึทืจ ื“ื™ IT ืžืึทืกืข. ื“ื™ ืคืึทื ื’ืงืฉืึทื ืึทืœื™ื˜ื™ ืื™ื– ื’ืึธืจ ืคึผืฉื•ื˜, ืื™ืจ ืคืึทืจืฉืจื™ื™ึทื‘ืŸ, ืคึผืœืึธืžื‘ื™ืจืŸ ืึท ืคึผืจืึธืคื™ืœ ืื•ืŸ ื’ื™ื™ืŸ ืฆื• ื“ื™ ื”ื•ื™ืคึผื˜ ืคื•ื ื˜, ื ื™ื™ืžืœื™ ื’ืขืคึฟื™ื ืขืŸ ืึท ืžืขื ื˜ืฉ ืฆื• ืจืขื“ืŸ ืฆื• ืื•ืŸ ื™ืงืกืคึผืึทื ื“ ื“ื™ื™ืŸ ืงืึทื ืขืงืฉืึทื ื– ืื•ืŸ ืžืึทื›ืŸ ื ื™ื™ึทืข ืึทืงื•ื•ื™ื™ื ื˜ืึทื ืกื™ื–.

ื“ ื ืžื• ื– ืื™ ืš ืžืื› ืŸ ื ืจืขื˜ืจืข ื˜ ืื• ืŸ ื ื‘ื™ืก ืœ ื“ืขืจืฆืฒืœ ืŸ ืฐืขื’ ืŸ ื–ื™ืš , ื›ื“ ื™ ืื™ ืŸ ื“ืข ืจ ืฆื•ืงื•ื ืคื˜ , ืฐืข ื˜ ืžืข ืจ ืฐืขืจ ืŸ ืงืœืืจ , ืฐื ื ืื™ ืš ื”ื ื‘ ื’ืขื ื•ืžืข ืŸ ืื–ืขืœื› ืข ื˜ืจื™ื˜ , ืื™ ืŸ ื“ืข ืจ ืื ื˜ื•ื•ื™ืงืœื•ื ื’ .

ืื™ืŸ ื“ืขื ืžืึธืžืขื ื˜ ืื™ืš ื”ืึทืœื˜ืŸ ื“ื™ ืฉื˜ืขืœืข ืคื•ืŸ โ€‹โ€‹ื˜ืขื›ื ื™ืฉ ืึทืจื˜ื™ืกื˜ ืื™ืŸ ืื™ื™ืŸ ืฉืคึผื™ืœ ืกื˜ื•ื“ื™ืข, ืžื™ื™ืŸ ืคึผืจืึธื’ืจืึทืžืžื™ื ื’ ื“ืขืจืคืึทืจื•ื ื’ ืื™ืŸ C # ืื™ื– ื’ืขื•ื•ืขืŸ ื’ืขื‘ื•ื™ื˜ ื‘ืœื•ื™ื– ืื•ื™ืฃ ืฉืจื™ื™ื‘ืŸ ืกืงืจื™ืคึผืก ืื•ืŸ ื™ื•ื˜ื™ืœืึทื˜ื™ื– ืคึฟืึทืจ ื•ื ื™ื˜ื™ ืื•ืŸ, ืื™ืŸ ืึทื“ื™ืฉืึทืŸ ืฆื• ื“ืขื, ืฉืึทืคึฟืŸ ืคึผืœื•ื’ื™ื ืก ืคึฟืึทืจ ื ื™ื“ืขืจื™ืง-ืžื“ืจื’ื” ืึทืจื‘ืขื˜ ืžื™ื˜ ืึทื ื“ืจื•ื™ื“ ื“ืขื•ื•ื™ืกืขืก. ืื™ ืš ื”ื ื‘ ื ื ืš ื ื™ืฉ ื˜ ื’ืขืฐืืœ ื˜ ืืจื•ื™ ืก ืคื• ืŸ ื“ืข ืจ ืงืœืฒื ืข ืจ ืฐืขืœื˜ , ืื• ืŸ ื“ื ืŸ ื”ื ื˜ ื–ื™ ืš ื’ืขืคื•ื ืข ืŸ ืื– ื ื’ืขืœืขื’ื ื”ืฒื˜ .

ื˜ื™ื™ืœ 1. ืจืึทื ืคึผืจืึธื•ื˜ืึทื˜ื™ื™ืคึผ

ืื™ืš ื”ืึธื‘ ื‘ืึทืฉืœืึธืกืŸ ื•ื•ืึธืก ื“ื™ ื“ื™ื ืกื˜ ื•ื•ืึธืœื˜ ื–ื™ื™ืŸ, ืื™ืš ืื ื’ืขื”ื•ื™ื‘ืŸ ืฆื• ืงื•ืงืŸ ืคึฟืึทืจ ืึธืคึผืฆื™ืขืก ืคึฟืึทืจ ื™ืžืคึผืœืึทืžืขื ื˜ื™ื™ืฉืึทืŸ. ื“ืืก ื’ืจื™ื ื’ืกื˜ืข ื•ื•ืืœื˜ ื’ืขื•ื•ืขืŸ ืฆื• ื’ืขืคื™ื ืขืŸ ืขืคืขืก ื ืคืืจื˜ื™ืงืข ืœื™ื™ื–ื•ื ื’, ืื•ื™ืฃ ื•ื•ืขืœื›ืŸ ืžืขืŸ ืงืขืŸ, ื•ื•ื™ ื ืกืื•ื•ืข ืื•ื™ืฃ ื ื’ืœืึธื‘ื•ืก, ืฉืœืขืคึผืŸ ืื•ื ื“ื–ืขืจ ืžืขื›ืึทื ื™ืงืขืจ ืื•ืŸ ื“ื™ ื’ืึทื ืฆืข ื–ืึทืš ืงืึธืŸ ืื•ื™ืกื’ืขืฉื˜ืขืœื˜ ื•ื•ืขืจืŸ ืฆื• ื“ืขืจ ืขืคื ื˜ืœืขื›ืขืจ ืฆืขื ื–ื•ืจ.
ืึธื‘ืขืจ ื“ืึธืก ืื™ื– ื ื™ืฉื˜ ื˜ืฉื™ืงืึทื•ื•ืข, ืื™ืš ื”ืึธื‘ ื ื™ืฉื˜ ื–ืขืŸ ืงื™ื™ืŸ ืึทืจื•ื™ืกืจื•ืคืŸ ืึธื“ืขืจ ื–ื™ื ืขืŸ ืื™ืŸ ืขืก, ืื•ืŸ ื“ืขืจื™ื‘ืขืจ ืื™ืš ืกื˜ืึทืจื˜ืขื“ ืœืขืจื ืขืŸ ื•ื•ืขื‘ ื˜ืขืงื ืึทืœืึทื“ื–ืฉื™ื– ืื•ืŸ ืžืขื˜ื”ืึธื“ืก ืคื•ืŸ ื™ื ื˜ืขืจืึทืงื˜ื™ื ื’ ืžื™ื˜ ื–ื™ื™.

ืื™ืš ืื ื’ืขื”ื•ื™ื‘ืŸ ืœืขืจื ืขืŸ ื“ื•ืจืš ืงื•ืงืŸ ืื™ืŸ ืึทืจื˜ื™ืงืœืขืŸ ืื•ืŸ ื“ืึทืงื™ื•ืžืขื ื˜ื™ื™ืฉืึทืŸ ืื•ื™ืฃ C # .ื ืขื˜. ื“ืึธ ืื™ืš ื’ืขืคึฟื•ื ืขืŸ ืคืึทืจืฉื™ื“ืŸ ื•ื•ืขื’ืŸ ืฆื• ืคืึทืจืขื ื“ื™ืงืŸ ื“ื™ ืึทืจื‘ืขื˜. ืขืก ื–ืขื ืขืŸ ืคื™ืœืข ืžืขืงืึทื ื™ื–ืึทืžื– ืคึฟืึทืจ ื™ื ื˜ืขืจืึทืงื˜ื™ื ื’ ืžื™ื˜ ื“ื™ ื ืขืฅ, ืคึฟื•ืŸ ืคื•ืœ-ืคืœืขื“ื–ืฉื“ ืกืึทืœื•ืฉืึทื ื– ื•ื•ื™ ASP.Net ืึธื“ืขืจ Azure ื‘ืึทื“ื™ื ื•ื ื’ืก, ืฆื• ื“ื™ืจืขืงื˜ ื™ื ื˜ืขืจืึทืงืฉืึทืŸ ืžื™ื˜ TcpHttp ืงืึทื ืขืงืฉืึทื ื–.

ืื™ืš ื”ืึธื‘ ื’ืขืžืื›ื˜ ืžื™ื™ืŸ ืขืจืฉื˜ืขืจ ืคึผืจื•ื•ื•ืŸ ืžื™ื˜ ASP, ืื™ืš ืžื™ื“ ืคืืจื•ื•ืืจืคืŸ ืขืก; ืื™ืŸ ืžื™ื™ืŸ ืžื™ื™ื ื•ื ื’, ื“ืึธืก ืื™ื– ื’ืขื•ื•ืขืŸ ืึท ืฆื• ืฉื•ื•ืขืจ ื‘ืึทืฉืœื•ืก ืคึฟืึทืจ ืื•ื ื“ื–ืขืจ ื“ื™ื ืกื˜. ืžื™ืจ ื•ื•ืึธืœื˜ ื ื™ืฉื˜ ื ื•ืฆืŸ ืืคื™ืœื• ืึท ื“ืจื™ื˜ ืคื•ืŸ ื“ื™ ืงื™ื™ืคึผืึทื‘ื™ืœืึทื˜ื™ื– ืคื•ืŸ ื“ืขื ืคึผืœืึทื˜ืคืึธืจืžืข, ืึทื–ื•ื™ ืื™ืš ืคืืจื‘ืœื™ื‘ืŸ ืžื™ื™ืŸ ื–ื•ื›ืŸ. ื“ื™ ื‘ืจื™ืจื” ืื™ื– ื’ืขื•ื•ืขืŸ ืฆื•ื•ื™ืฉืŸ ื˜ืงืคึผ ืื•ืŸ ื”ื˜ื˜ืคึผ ืงืœื™ืขื ื˜-ืกืขืจื•ื•ืขืจ. ื“ืึธ, ืื•ื™ืฃ Habrรฉ, ืื™ืš ื’ืขืคึฟื•ื ืขืŸ ืึทืŸ ืึทืจื˜ื™ืงืœ ื•ื•ืขื’ืŸ ืžื•ืœื˜ื™ื˜ื”ืจืขืึทื“ืขื“ ืกืขืจื•ื•ืขืจ, ื•ื•ื™ื™ืœ ื’ืขื–ืืžืœื˜ ืื•ืŸ ื˜ืขืกื˜ืขื“ ืขืก, ืื™ืš ื‘ืึทืฉืœืึธืกืŸ ืฆื• ืคืึธืงื•ืก ืกืคึผืึทืกื™ืคื™ืงืœื™ ืื•ื™ืฃ ื™ื ื˜ืขืจืึทืงืฉืึทืŸ ืžื™ื˜ ื˜ืงืคึผ ืงืึทื ืขืงืฉืึทื ื–, ืคึฟืึทืจ ืขื˜ืœืขื›ืข ืกื™ื‘ื” ืื™ืš ื’ืขื“ืึทื ืง ืึทื– http ื•ื•ืึธืœื˜ ื ื™ืฉื˜ ืœืึธื–ืŸ ืžื™ืจ ืฆื• ืฉืึทืคึฟืŸ ืึท ืงืจื™ื™ึทื–-ืคึผืœืึทื˜ืคืึธืจืžืข ืœื™ื™ื–ื•ื ื’.

ื“ืขืจ ืขืจืฉื˜ืขืจ ื•ื•ืขืจืกื™ืข ืคื•ืŸ โ€‹โ€‹โ€‹โ€‹ื“ื™ ืกืขืจื•ื•ืขืจ ื™ื ืงืœื•ื“ืขื“ ืคึฟืึทืจื‘ื™ื ื“ื•ื ื’ ืคึผืจืึทืกืขืกื™ื ื’, ืกืขืจื•ื•ื™ืจื˜ ืกื˜ืึทื˜ื™ืง ื•ื•ืขื‘ ื‘ืœืึทื˜ ืื™ื ื”ืึทืœื˜ ืื•ืŸ ืึทืจื™ื™ึทื ื’ืขืจืขื›ื ื˜ ืึท ื‘ืึทื ื™ืฆืขืจ ื“ืึทื˜ืึทื‘ื™ื™ืก. ืื•ืŸ ืฆื• ืึธื ื”ื™ื™ื‘ืŸ ืžื™ื˜, ืื™ืš ื‘ืึทืฉืœืึธืกืŸ ืฆื• ื‘ื•ื™ืขืŸ ืคืึทื ื’ืงืฉืึทื ืึทืœื™ื˜ื™ ืคึฟืึทืจ ืืจื‘ืขื˜ืŸ ืžื™ื˜ ื“ืขื ืคึผืœืึทืฅ, ืึทื–ื•ื™ ืึทื– ืื™ืš ืงืขืŸ ืฉืคึผืขื˜ืขืจ ืœื™ื™ื’ืŸ ืคึผืจืึทืกืขืกื™ื ื’ ืคื•ืŸ ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืื•ื™ืฃ ืึทื ื“ืจื•ื™ื“ ืื•ืŸ ื™ืึธืก.

ื“ืึธ ืก ืขื˜ืœืขื›ืข ืงืึธื“
ื“ืขืจ ื”ื•ื™ืคึผื˜ ืคืึธื“ืขื ื‘ืืงื•ืžืขืŸ ืงืœื™ื™ืึทื ืฅ ืื™ืŸ ืึท ืกืึธืฃ ืฉืœื™ื™ืฃ:

using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace ClearServer
{

    class Server
    {
        TcpListener Listener;
        public Server(int Port)
        {
            Listener = new TcpListener(IPAddress.Any, Port);
            Listener.Start();

            while (true)
            {
                TcpClient Client = Listener.AcceptTcpClient();
                Thread Thread = new Thread(new ParameterizedThreadStart(ClientThread));
                Thread.Start(Client);
            }
        }

        static void ClientThread(Object StateInfo)
        {
            new Client((TcpClient)StateInfo);
        }

        ~Server()
        {
            if (Listener != null)
            {
                Listener.Stop();
            }
        }

        static void Main(string[] args)
        {
            DatabaseWorker sqlBase = DatabaseWorker.GetInstance;

            new Server(80);
        }
    }
}

ื“ืขืจ ืงืœื™ืขื ื˜ ื”ืึทื ื“ืœืขืจ ื–ื™ืš:

using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace ClearServer
{
    class Client
    {


        public Client(TcpClient Client)
        {

            string Message = "";
            byte[] Buffer = new byte[1024];
            int Count;
            while ((Count = Client.GetStream().Read(Buffer, 0, Buffer.Length)) > 0)
            {
                Message += Encoding.UTF8.GetString(Buffer, 0, Count);

                if (Message.IndexOf("rnrn") >= 0 || Message.Length > 4096)
                {
                    Console.WriteLine(Message);
                    break;
                }
            }

            Match ReqMatch = Regex.Match(Message, @"^w+s+([^s?]+)[^s]*s+HTTP/.*|");
            if (ReqMatch == Match.Empty)
            {
                ErrorWorker.SendError(Client, 400);
                return;
            }
            string RequestUri = ReqMatch.Groups[1].Value;
            RequestUri = Uri.UnescapeDataString(RequestUri);
            if (RequestUri.IndexOf("..") >= 0)
            {
                ErrorWorker.SendError(Client, 400);
                return;
            }
            if (RequestUri.EndsWith("/"))
            {
                RequestUri += "index.html";
            }

            string FilePath =

quot;D:/Web/TestSite{RequestUri}";

if (!File.Exists(FilePath))
{
ErrorWorker.SendError(Client, 404);
return;
}

string Extension = RequestUri.Substring(RequestUri.LastIndexOf('.'));

string ContentType = "";

switch (Extension)
{
case ".htm":
case ".html":
ContentType = "text/html";
break;
case ".css":
ContentType = "text/css";
break;
case ".js":
ContentType = "text/javascript";
break;
case ".jpg":
ContentType = "image/jpeg";
break;
case ".jpeg":
case ".png":
case ".gif":
ContentType =


quot;image/{Extension.Substring(1)}";
break;
default:
if (Extension.Length > 1)
{
ContentType =


quot;application/{Extension.Substring(1)}";
}
else
{
ContentType = "application/unknown";
}
break;
}

FileStream FS;
try
{
FS = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
catch (Exception)
{
ErrorWorker.SendError(Client, 500);
return;
}

string Headers =


quot;HTTP/1.1 200 OKnContent-Type: {ContentType}nContent-Length: {FS.Length}nn";
byte[] HeadersBuffer = Encoding.ASCII.GetBytes(Headers);
Client.GetStream().Write(HeadersBuffer, 0, HeadersBuffer.Length);

while (FS.Position < FS.Length)
{
Count = FS.Read(Buffer, 0, Buffer.Length);
Client.GetStream().Write(Buffer, 0, Count);
}

FS.Close();
Client.Close();
}
}
}

ืื•ืŸ ื“ืขืจ ืขืจืฉื˜ืขืจ ื“ืึทื˜ืึทื‘ื™ื™ืก ื’ืขื‘ื•ื™ื˜ ืื•ื™ืฃ ื”ื™ื’ืข SQL:

using System;
using System.Data.Linq;
namespace ClearServer
{
    class DatabaseWorker
    {

        private static DatabaseWorker instance;

        public static DatabaseWorker GetInstance
        {
            get
            {
                if (instance == null)
                    instance = new DatabaseWorker();
                return instance;
            }
        }


        private DatabaseWorker()
        {
            string connectionStr = databasePath;
            using (DataContext db = new DataContext(connectionStr))
            {
                Table<User> users = db.GetTable<User>();
                foreach (var item in users)
                {
                    Console.WriteLine(

quot;{item.login} {item.password}");
}
}
}
}
}

ื•ื•ื™ ืื™ืจ ืงืขื ืขืŸ ื–ืขืŸ, ื“ื™ ื•ื•ืขืจืกื™ืข ืื™ื– ืึท ื‘ื™ืกืœ ืึทื ื“ืขืจืฉ ืคื•ืŸ ื“ื™ ืื™ืŸ ื“ืขื ืึทืจื˜ื™ืงืœ. ืื™ืŸ ืคืึทืงื˜, ื“ืึธ ืžื™ืจ ื ืึธืจ ืฆื•ื’ืขื’ืขื‘ืŸ ืœืึธื•ื“ื™ื ื’ ืคื•ืŸ ื‘ืœืขื˜ืขืจ ืคื•ืŸ ืึท ื˜ืขืงืข ืื•ื™ืฃ ื“ื™ ืงืึธืžืคึผื™ื•ื˜ืขืจ ืื•ืŸ ืึท ื“ืึทื˜ืึทื‘ื™ื™ืก (ื•ื•ืึธืก, ื“ื•ืจืš ื“ืขื ื•ื•ืขื’, ื”ืื˜ ื ื™ืฉื˜ ืึทืจื‘ืขื˜ืŸ ืื™ืŸ ื“ืขื ื•ื•ืขืจืกื™ืข ืจืขื›ื˜ ืฆื• ื“ืขืจ ืคืึทืœืฉ ืงืึทื ืขืงืฉืึทืŸ ืึทืจืงืึทื˜ืขืงื˜ืฉืขืจ).

ื˜ืฉืึทืคึผื˜ืขืจ 2. ืกืงืจื•ื™ื ื’ ื“ื™ ื•ื•ื™ืœื–

ื ืึธืš ื˜ืขืกื˜ื™ื ื’ ื“ื™ ืกืขืจื•ื•ืขืจ, ืื™ืš ื’ืขืงื•ืžืขืŸ ืฆื• ื“ื™ ืžืกืงื ื ืึทื– ื“ืึธืก ื•ื•ืึธืœื˜ ื–ื™ื™ืŸ ืึท ื•ื™ืกื’ืขืฆื™ื™ื›ื ื˜ ืœื™ื™ื–ื•ื ื’ (ืกืคึผื•ื™ืœืขืจ: ื ื™ื˜), ืคึฟืึทืจ ืื•ื ื“ื–ืขืจ ื“ื™ื ืกื˜, ืึทื–ื•ื™ ื“ื™ ืคึผืจื•ื™ืขืงื˜ ืื ื’ืขื”ื•ื™ื‘ืŸ ืฆื• ืงืจื™ื’ืŸ ืœืึธื’ื™ืง.
ืฉืจื™ื˜ ื“ื•ืจืš ืฉืจื™ื˜, ื ื™ื™ึท ืžืึทื“ื–ืฉื•ืœื– ืื ื’ืขื”ื•ื™ื‘ืŸ ืฆื• ื“ืขืจืฉื™ื™ึทื ืขืŸ ืื•ืŸ ื“ื™ ืคืึทื ื’ืงืฉืึทื ืึทืœื™ื˜ื™ ืคื•ืŸ ื“ื™ ืกืขืจื•ื•ืขืจ ืื™ื– ื™ืงืกืคึผืึทื ื“ื™ื“. ื“ืขืจ ืกืขืจื•ื•ืขืจ ื”ืื˜ ืงื•ื ื” ืึท ืคึผืจืึธื‘ืข ืคืขืœื“ ืื•ืŸ ืกืกืœ ืคึฟืึทืจื‘ื™ื ื“ื•ื ื’ ืขื ืงืจื™ืคึผืฉืึทืŸ.

ื ื‘ื™ืกืœ ืžืขืจ ืงืึธื“ ื“ื™ืกืงืจื™ื™ื‘ื™ื ื’ ื“ื™ ืœืึธื’ื™ืง ืคื•ืŸ ื“ื™ ืกืขืจื•ื•ืขืจ ืื•ืŸ ืงืœื™ืขื ื˜ ืคึผืจืึทืกืขืกื™ื ื’
ืึท ื“ืขืจื”ื™ื™ึทื ื˜ื™ืงื˜ ื•ื•ืขืจืกื™ืข ืคื•ืŸ โ€‹โ€‹โ€‹โ€‹ื“ื™ ืกืขืจื•ื•ืขืจ ื•ื•ืึธืก ื›ื•ืœืœ ื“ื™ ื ื•ืฆืŸ ืคื•ืŸ ืึท ื‘ืึทื•ื•ื™ื™ึทื–ืŸ.

using System;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Security.Policy;
using System.Threading;


namespace ClearServer
{

    sealed class Server
    {
        readonly bool ServerRunning = true;
        readonly TcpListener sslListner;
        public static X509Certificate serverCertificate = null;
        Server()
        {
            serverCertificate = X509Certificate.CreateFromSignedFile(@"C:sslitinder.online.crt");
            sslListner = new TcpListener(IPAddress.Any, 443);
            sslListner.Start();
            Console.WriteLine("Starting server.." + serverCertificate.Subject + "n" + Assembly.GetExecutingAssembly().Location);
            while (ServerRunning)
            {
                TcpClient SslClient = sslListner.AcceptTcpClient();
                Thread SslThread = new Thread(new ParameterizedThreadStart(ClientThread));
                SslThread.Start(SslClient);
            }
            
        }
        static void ClientThread(Object StateInfo)
        {
            new Client((TcpClient)StateInfo);
        }

        ~Server()
        {
            if (sslListner != null)
            {
                sslListner.Stop();
            }
        }

        public static void Main(string[] args)
        {
            if (AppDomain.CurrentDomain.IsDefaultAppDomain())
            {
                Console.WriteLine("Switching another domain");
                new AppDomainSetup
                {
                    ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
                };
                var current = AppDomain.CurrentDomain;
                var strongNames = new StrongName[0];
                var domain = AppDomain.CreateDomain(
                    "ClearServer", null,
                    current.SetupInformation, new PermissionSet(PermissionState.Unrestricted),
                    strongNames);
                domain.ExecuteAssembly(Assembly.GetExecutingAssembly().Location);
            }
            new Server();
        }
    }
}

ืื•ืŸ ืื•ื™ืš ืึท ื ื™ื™ึทืข ืงืœื™ืขื ื˜ ื”ืึทื ื“ืœืขืจ ืžื™ื˜ SSL ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ:

using ClearServer.Core.Requester;
using System;
using System.Net.Security;
using System.Net.Sockets;

namespace ClearServer
{
    public class Client
    {
        public Client(TcpClient Client)
        {
            SslStream SSlClientStream = new SslStream(Client.GetStream(), false);
            try
            {
                SSlClientStream.AuthenticateAsServer(Server.serverCertificate, clientCertificateRequired: false, checkCertificateRevocation: true);
            }
            catch (Exception e)
            {
                Console.WriteLine(
                    "---------------------------------------------------------------------n" +


quot;|{DateTime.Now:g}n|------------n|{Client.Client.RemoteEndPoint}n|------------n|Exception: {e.Message}n|------------n|Authentication failed - closing the connection.n" +
"---------------------------------------------------------------------n");
SSlClientStream.Close();
Client.Close();
}
new RequestContext(SSlClientStream, Client);
}

}
}

ืึธื‘ืขืจ ื–ื™ื ื˜ ื“ืขืจ ืกืขืจื•ื•ืขืจ ืœื•ื™ืคื˜ ืื•ื™ืกืฉืœื™ืกืœืขืš ืื•ื™ืฃ ืึท ื˜ืงืคึผ ืงืฉืจ, ืขืก ืื™ื– ื ื™ื™ื˜ื™ืง ืฆื• ืฉืึทืคึฟืŸ ืึท ืžืึธื“ื•ืœืข ื•ื•ืึธืก ืงืขืŸ ื“ืขืจืงืขื ืขืŸ ื“ืขื ืงืึธื ื˜ืขืงืกื˜ ืคื•ืŸ ื“ื™ ื‘ืขื˜ืŸ. ืื™ืš ื”ืื‘ ื‘ืืฉืœืืกืŸ ืื– ื“ื ื•ื•ืขื˜ ื–ื™ื™ืŸ ืคืืกื™ื’ ื ืคืืจืคื™ืจืขืจ ื•ื•ืืก ื–ืืœ ืฆืขื‘ืจืขื›ืŸ ื“ื™ ื‘ืงืฉื” ืคื•ื ืขื ืงืœื™ืขื ื˜ ืื™ืŸ ื‘ืื–ื•ื ื“ืขืจืข ื˜ื™ื™ืœืŸ ืžื™ื˜ ื•ื•ืขืœื›ืข ืื™ืš ืงืขืŸ ื–ื™ืš ืื™ื ื˜ืขืจืืงืฆื™ืขืŸ ื›ื“ื™ ืฆื• ื’ืขื‘ืŸ ื“ืขื ืงืœื™ืขื ื˜ ื“ื™ ื ื•ื™ื˜ื™ื’ืข ืขื ื˜ืคึฟืขืจ.

ืคึผืึทืจืกืขืจ

using ClearServer.Core.UserController;
using ReServer.Core.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace ClearServer.Core.Requester
{
    public class RequestContext
    {
        public string Message = "";
        private readonly byte[] buffer = new byte[1024];
        public string RequestMethod;
        public string RequestUrl;
        public User RequestProfile;
        public User CurrentUser = null;
        public List<RequestValues> HeadersValues;
        public List<RequestValues> FormValues;
        private TcpClient TcpClient;

        private event Action<SslStream, RequestContext> OnRead = RequestHandler.OnHandle;

        DatabaseWorker databaseWorker = new DatabaseWorker();

        public RequestContext(SslStream ClientStream, TcpClient Client)
        {

            this.TcpClient = Client;
            try
            {
                ClientStream.BeginRead(buffer, 0, buffer.Length, ClientRead, ClientStream);
            }
            catch { return; }
        }
        private void ClientRead(IAsyncResult ar)
        {
            SslStream ClientStream = (SslStream)ar.AsyncState;

            if (ar.IsCompleted)
            {
                Message = Encoding.UTF8.GetString(buffer);
                Message = Uri.UnescapeDataString(Message);
                Console.WriteLine(

quot;n{DateTime.Now:g} Client IP:{TcpClient.Client.RemoteEndPoint}n{Message}");
RequestParse();
HeadersValues = HeaderValues();
FormValues = ContentValues();
UserParse();
ProfileParse();
OnRead?.Invoke(ClientStream, this);
}
}

private void RequestParse()
{
Match methodParse = Regex.Match(Message, @"(^w+)s+([^s?]+)[^s]*s+HTTP/.*|");
RequestMethod = methodParse.Groups[1].Value.Trim();
RequestUrl = methodParse.Groups[2].Value.Trim();
}
private void UserParse()
{
string cookie;
try
{
if (HeadersValues.Any(x => x.Name.Contains("Cookie")))
{
cookie = HeadersValues.FirstOrDefault(x => x.Name.Contains("Cookie")).Value;
try
{
CurrentUser = databaseWorker.CookieValidate(cookie);
}
catch { }
}
}
catch { }

}
private List<RequestValues> HeaderValues()
{
var values = new List<RequestValues>();
var parse = Regex.Matches(Message, @"(.*?): (.*?)n");
foreach (Match match in parse)
{
values.Add(new RequestValues()
{
Name = match.Groups[1].Value.Trim(),
Value = match.Groups[2].Value.Trim()
});
}
return values;
}

private void ProfileParse()
{
if (RequestUrl.Contains("@"))
{
RequestProfile = databaseWorker.FindUser(RequestUrl.Substring(2));
RequestUrl = "/profile";
}
}
private List<RequestValues> ContentValues()
{
var values = new List<RequestValues>();
var output = Message.Trim('n').Split().Last();
var parse = Regex.Matches(output, @"([^&].*?)=([^&]*b)");
foreach (Match match in parse)
{
values.Add(new RequestValues()
{
Name = match.Groups[1].Value.Trim(),
Value = match.Groups[2].Value.Trim().Replace('+', ' ')
});
}
return values;
}
}
}

ื–ื™ื™ึทืŸ ืขืกืึทื ืก ืื™ื– ืฆื• ื‘ืจืขื›ืŸ ื“ื™ ื‘ืงืฉื” ืื™ืŸ ืคึผืึทืจืฅ ืžื™ื˜ ืจืขื’ื•ืœืขืจ ืื•ื™ืกื“ืจื•ืงืŸ. ืžื™ืจ ื‘ืึทืงื•ืžืขืŸ ืึท ืึธื ื–ืึธื’ ืคื•ืŸ ื“ืขื ืงืœื™ืขื ื˜, ืื•ื™ืกืงืœื™ื™ึทื‘ืŸ ื“ื™ ืขืจืฉื˜ืขืจ ืฉื•ืจื”, ื•ื•ืึธืก ื›ึผื•ืœืœ ื“ืขื ืื•ืคึฟืŸ ืื•ืŸ ื‘ืขื˜ืŸ URL. ื“ืขืจื ืึธืš ืžื™ืจ ืœื™ื™ืขื ืขืŸ ื“ื™ ื›ืขื“ื™ื ื’ื–, ื•ื•ืึธืก ืžื™ืจ ืฉื˜ืขืœืŸ ืื™ืŸ ืึท ืžืขื ื’ืข ืคื•ืŸ โ€‹โ€‹โ€‹โ€‹ื“ื™ ืคืึธืจืขื HeaderName=Content, ืื•ืŸ ืžื™ืจ ื’ืขืคึฟื™ื ืขืŸ ืื•ื™ืš, ืื•ื™ื‘ ืขืก ืื™ื–, ืึทืงืึทืžืคึผืึทื ื™ื™ื ื’ ืื™ื ื”ืึทืœื˜ (ืœืžืฉืœ, querystring) ื•ื•ืึธืก ืžื™ืจ ืื•ื™ืš ืฉื˜ืขืœืŸ ืื™ืŸ ืึท ืขื ืœืขืš ืžืขื ื’ืข. ืื™ืŸ ืึทื“ื™ืฉืึทืŸ, ื“ืขืจ ืคึผืึทืจืกืขืจ ื’ืขืคื™ื ื˜ ืฆื™ ื“ืขืจ ืงืจืึทื ื˜ ืงืœื™ืขื ื˜ ืื™ื– ืึธื˜ืขืจื™ื™ื–ื“ ืื•ืŸ ืกื˜ืึธืจื– ื–ื™ื™ืŸ ื“ืึทื˜ืŸ. ืึทืœืข ืจื™ืงื•ื•ืขืก ืคื•ืŸ ืึธื˜ืขืจื™ื™ื–ื“ ืงืœื™ื™ืึทื ืฅ ืึทื ื˜ื”ืึทืœื˜ืŸ ืึท ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ื”ืึทืฉ, ื•ื•ืึธืก ืื™ื– ืกื˜ืึธืจื“ ืื™ืŸ ืงื™ื›ืœืขืš, ื“ืึทื ืง ืฆื• ื“ืขื ืขืก ืื™ื– ืžืขื’ืœืขืš ืฆื• ื‘ืึทื–ื•ื ื“ืขืจ ื•ื•ื™ื™ึทื˜ืขืจ ืึธืคึผืขืจื™ื™ื˜ื™ื ื’ ืœืึธื’ื™ืง ืคึฟืึทืจ ื“ื™ ืฆื•ื•ื™ื™ ื˜ื™ื™ืคึผืก ืคื•ืŸ ืงืœื™ื™ืึทื ืฅ ืื•ืŸ ื’ืขื‘ืŸ ื–ื™ื™ ื“ื™ ืจื™ื›ื˜ื™ืง ืขื ื˜ืคึฟืขืจืก.

ื ื•, ืึท ืงืœื™ื™ืŸ, ืคื™ื™ึทืŸ ืฉื˜ืจื™ืš ื•ื•ืึธืก ื•ื•ืึธืœื˜ ื–ื™ื™ืŸ ื•ื•ืขืจื˜ ืฆื• ืฉื˜ืขืœืŸ ืื™ืŸ ืึท ื‘ืึทื–ื•ื ื“ืขืจ ืžืึธื“ื•ืœืข, ื“ื™ ืงืึทื ื•ื•ืขืจื–ืฉืึทืŸ ืคื•ืŸ ืคึฟืจืื’ืŸ ื•ื•ื™ "site.com/@UserName" ืื™ืŸ ื“ื™ื ืึทืžื™ืงืึทืœืœื™ ื“ื–ืฉืขื ืขืจื™ื™ื˜ืึทื“ ื‘ืึทื ื™ืฆืขืจ ื‘ืœืขื˜ืขืจ. ื ืึธืš ืคึผืจืึทืกืขืกื™ื ื’ ื“ื™ ื‘ืงืฉื”, ื“ื™ ืคืืœื’ืขื ื“ืข ืžืึทื“ื–ืฉื•ืœื– ืงื•ืžืขืŸ ืื™ืŸ ืฉืคึผื™ืœ.

ื˜ืฉืึทืคึผื˜ืขืจ 3. ื™ื ืกื˜ืึธืœื™ื ื’ ื“ื™ ืกื˜ื™ืจื™ื ื’ ืจืึธื“, ืœื•ื‘ืจื™ืงื™ื™ืฉืึทืŸ ืคื•ืŸ ื“ื™ ืงื™ื™ื˜

ื•ื•ื™ ื‘ืึทืœื“ ื•ื•ื™ ื“ืขืจ ืคึผืึทืจืกืขืจ ื”ืื˜ ื’ืขืขื ื“ื™ืงื˜ ื–ื™ื™ืŸ ืึทืจื‘ืขื˜, ื“ืขืจ ื”ืึทื ื“ืœืขืจ ืงื•ืžื˜ ืื™ืŸ ืฉืคึผื™ืœ, ื’ืขื‘ืŸ ื•ื•ื™ื™ึทื˜ืขืจ ื™ื ืกื˜ืจืึทืงืฉืึทื ื– ืฆื• ื“ื™ ืกืขืจื•ื•ืขืจ ืื•ืŸ ื“ื™ื•ื•ื™ื™ื“ื™ื ื’ ืงืึธื ื˜ืจืึธืœ ืื™ืŸ ืฆื•ื•ื™ื™ ืคึผืึทืจืฅ.

ืคึผืฉื•ื˜ ื”ืึทื ื“ืœืขืจ

using ClearServer.Core.UserController;
using System.Net.Security;
namespace ClearServer.Core.Requester
{
    public class RequestHandler
    {
        public static void OnHandle(SslStream ClientStream, RequestContext context)
        {

            if (context.CurrentUser != null)
            {
                new AuthUserController(ClientStream, context);
            }
            else 
            {
                new NonAuthUserController(ClientStream, context);
            };
        }
    }
}

ืื™ืŸ ืคืึทืงื˜, ืขืก ืื™ื– ื‘ืœื•ื™ื– ืื™ื™ืŸ ื˜ืฉืขืง ืคึฟืึทืจ ื‘ืึทื ื™ืฆืขืจ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ, ื ืึธืš ื•ื•ืึธืก ื“ื™ ืคึผืจืึทืกืขืกื™ื ื’ ืคื•ืŸ ื“ื™ ื‘ืขื˜ืŸ ื”ื™ื™ื‘ื˜.

ืงืœื™ืขื ื˜ ืงืึทื ื˜ืจืึธื•ืœืขืจื–
ืื•ื™ื‘ ื“ืขืจ ื‘ืึทื ื™ืฆืขืจ ืื™ื– ื ื™ืฉื˜ ืึธื˜ืขืจื™ื™ื–ื“, ื“ื™ ืคืึทื ื’ืงืฉืึทื ืึทืœื™ื˜ื™ ืคึฟืึทืจ ืื™ื ืื™ื– ื‘ืื–ื™ืจื˜ ื‘ืœื•ื™ื– ืื•ื™ืฃ ื“ื™ ืึทืจื•ื™ืกื•ื•ื™ื™ึทื–ืŸ ืคื•ืŸ ื‘ืึทื ื™ืฆืขืจ ืคึผืจืึธื•ืคื™ื™ืœื– ืื•ืŸ ื“ื™ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืจืขื’ื™ืกื˜ืจืึทืฆื™ืข ืคึฟืขื ืฆื˜ืขืจ. ื“ืขืจ ืงืึธื“ ืคึฟืึทืจ ืึท ืึธื˜ืขืจื™ื™ื–ื“ ื‘ืึทื ื™ืฆืขืจ ืงื•ืงื˜ ื•ื•ืขื’ืŸ ื“ื™ ื–ืขืœื‘ืข, ืึทื–ื•ื™ ืื™ืš ื–ืขืŸ ืงื™ื™ืŸ ืกื™ื‘ื” ืฆื• ื“ื•ืคึผืœื™ืงืึทื˜ ืขืก.

ืึทื ืึธื˜ืขืจื™ื™ื–ื“ ื‘ืึทื ื™ืฆืขืจ

using ClearServer.Core.Requester;
using System.IO;
using System.Net.Security;

namespace ClearServer.Core.UserController
{
    internal class NonAuthUserController
    {
        private readonly SslStream ClientStream;
        private readonly RequestContext Context;
        private readonly WriteController WriteController;
        private readonly AuthorizationController AuthorizationController;

        private readonly string ViewPath = "C:/Users/drdre/source/repos/ClearServer/View";

        public NonAuthUserController(SslStream clientStream, RequestContext context)
        {
            this.ClientStream = clientStream;
            this.Context = context;
            this.WriteController = new WriteController(clientStream);
            this.AuthorizationController = new AuthorizationController(clientStream, context);
            ResourceLoad();
        }

        void ResourceLoad()
        {
            string[] blockextension = new string[] {"cshtml", "html", "htm"};
            bool block = false;
            foreach (var item in blockextension)
            {
                if (Context.RequestUrl.Contains(item))
                {
                    block = true;
                    break;
                }
            }
            string FilePath = "";
            string Header = "";
            var RazorController = new RazorController(Context, ClientStream);
            
            switch (Context.RequestMethod)
            {
                case "GET":
                    switch (Context.RequestUrl)
                    {
                        case "/":
                            FilePath = ViewPath + "/loginForm.html";
                            Header =

quot;HTTP/1.1 200 OKnContent-Type: text/html";
WriteController.DefaultWriter(Header, FilePath);
break;
case "/profile":
RazorController.ProfileLoader(ViewPath);
break;
default:
//ะฒ ะดะฐะฝะฝะพะผ ะฑะปะพะบะต ะบะพะดะฐ ะฟั€ะพะธัั…ะพะดะธั‚ ะพั‚ัะตั‡ะตะฝะธะต ะทะฐะฟั€ะพัะพะฒ ะบ ัะตั€ะฒะตั€ัƒ ะฟะพ ะฟั€ัะผะพะผัƒ ะฐะดั€ะตััƒ ัั‚ั€ะฐะฝะธั†ั‹ ะฒะธะดะฐ site.com/page.html
if (!File.Exists(ViewPath + Context.RequestUrl) | block)
{
RazorController.ErrorLoader(404);

}
else if (Path.HasExtension(Context.RequestUrl) && File.Exists(ViewPath + Context.RequestUrl))
{
Header = WriteController.ContentType(Context.RequestUrl);
FilePath = ViewPath + Context.RequestUrl;
WriteController.DefaultWriter(Header, FilePath);
}
break;
}
break;

case "POST":
AuthorizationController.MethodRecognizer();
break;

}

}

}
}

ืื•ืŸ ืคื•ืŸ ืงื•ืจืก, ื“ืขืจ ื‘ืึทื ื™ืฆืขืจ ืžื•ื–ืŸ ื‘ืึทืงื•ืžืขืŸ ืขื˜ืœืขื›ืข ืกืึธืจื˜ ืคื•ืŸ ื‘ืœืึทื˜ ืื™ื ื”ืึทืœื˜, ืึทื–ื•ื™ ืคึฟืึทืจ ืจืขืกืคึผืึธื ืกืขืก ืขืก ืื™ื– ื“ื™ ืคืืœื’ืขื ื“ืข ืžืึธื“ื•ืœืข, ื•ื•ืึธืก ืื™ื– ืคืึทืจืึทื ื˜ื•ื•ืึธืจื˜ืœืขืš ืคึฟืึทืจ ืจื™ืกืคึผืึทื ื“ื™ื ื’ ืฆื• ืžื™ื˜ืœ ืจื™ืงื•ื•ืขืก.

ืฉืจื™ื™ื‘ืขืจ ืงืึธื ื˜ืจืึธืœืœืขืจ

using System;
using System.IO;
using System.Net.Security;
using System.Text;

namespace ClearServer.Core.UserController
{
    public class WriteController
    {
        SslStream ClientStream;
        public WriteController(SslStream ClientStream)
        {
            this.ClientStream = ClientStream;
        }

        public void DefaultWriter(string Header, string FilePath)
        {
            FileStream fileStream;
            try
            {
                fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                Header =

quot;{Header}nContent-Length: {fileStream.Length}nn";
ClientStream.Write(Encoding.UTF8.GetBytes(Header));
byte[] response = new byte[fileStream.Length];
fileStream.BeginRead(response, 0, response.Length, OnFileRead, response);
}
catch { }
}

public string ContentType(string Uri)
{
string extension = Path.GetExtension(Uri);
string Header = "HTTP/1.1 200 OKnContent-Type:";
switch (extension)
{
case ".html":
case ".htm":
return


quot;{Header} text/html";
case ".css":
return


quot;{Header} text/css";
case ".js":
return


quot;{Header} text/javascript";
case ".jpg":
case ".jpeg":
case ".png":
case ".gif":
return


quot;{Header} image/{extension}";
default:
if (extension.Length > 1)
{
return


quot;{Header} application/" + extension.Substring(1);
}
else
{
return


quot;{Header} application/unknown";
}
}
}

public void OnFileRead(IAsyncResult ar)
{
if (ar.IsCompleted)
{
var file = (byte[])ar.AsyncState;
ClientStream.BeginWrite(file, 0, file.Length, OnClientSend, null);
}
}

public void OnClientSend(IAsyncResult ar)
{
if (ar.IsCompleted)
{
ClientStream.Close();
}
}
}

ืึธื‘ืขืจ ืื™ืŸ ืกื“ืจ ืฆื• ื•ื•ื™ื™ึทื–ืŸ ื“ืขื ื‘ืึทื ื™ืฆืขืจ ื–ื™ื™ืŸ ืคึผืจืึธืคื™ืœ ืื•ืŸ ื“ื™ ืคึผืจืึธื•ืคื™ื™ืœื– ืคื•ืŸ ืื ื“ืขืจืข ื™ื•ื–ืขืจื–, ืื™ืš ื‘ืึทืฉืœืึธืกืŸ ืฆื• ื ื•ืฆืŸ RazorEngine, ืึธื“ืขืจ ื’ืึทื ืฅ ื˜ื™ื™ืœ ืคื•ืŸ ืขืก. ืขืก ืื•ื™ืš ื›ื•ืœืœ ืคึผืจืึทืกืขืกื™ื ื’ ืคืึทืจืงืจื™ืคึผืœื˜ ืจื™ืงื•ื•ืขืก ืื•ืŸ ืึทืจื•ื™ืกื’ืขื‘ืŸ ืึท ืฆื•ื ืขืžืขืŸ ื˜ืขื•ืช ืงืึธื“.

ืจื™ื™ื–ืขืจ ืงืึธื ื˜ืจืึธืœืœืขืจ

using ClearServer.Core.Requester;
using RazorEngine;
using RazorEngine.Templating;
using System;
using System.IO;
using System.Net;
using System.Net.Security;

namespace ClearServer.Core.UserController
{
    internal class RazorController
    {
        private RequestContext Context;
        private SslStream ClientStream;
        dynamic PageContent;


        public RazorController(RequestContext context, SslStream clientStream)
        {
            this.Context = context;
            this.ClientStream = clientStream;

        }

        public void ProfileLoader(string ViewPath)
        {
            string Filepath = ViewPath + "/profile.cshtml";
            if (Context.RequestProfile != null)
            {
                if (Context.CurrentUser != null && Context.RequestProfile.login == Context.CurrentUser.login)
                {
                    try
                    {
                        PageContent = new { isAuth = true, Name = Context.CurrentUser.name, Login = Context.CurrentUser.login, Skills = Context.CurrentUser.skills };
                        ClientSend(Filepath, Context.CurrentUser.login);
                    }
                    catch (Exception e) { Console.WriteLine(e); }

                }
                else
                {
                    try
                    {
                        PageContent = new { isAuth = false, Name = Context.RequestProfile.name, Login = Context.RequestProfile.login, Skills = Context.RequestProfile.skills };
                        ClientSend(Filepath, "PublicProfile:"+ Context.RequestProfile.login);
                    }
                    catch (Exception e) { Console.WriteLine(e); }
                }
            }
            else
            {
                ErrorLoader(404);
            }


        }

        public void ErrorLoader(int Code)
        {
            try
            {
                PageContent = new { ErrorCode = Code, Message = ((HttpStatusCode)Code).ToString() };
                string ErrorPage = "C:/Users/drdre/source/repos/ClearServer/View/Errors/ErrorPage.cshtml";
                ClientSend(ErrorPage, Code.ToString());
            }
            catch { }

        }

        private void ClientSend(string FilePath, string Key)
        {
            var template = File.ReadAllText(FilePath);
            var result = Engine.Razor.RunCompile(template, Key, null, (object)PageContent);
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(result);
            ClientStream.BeginWrite(buffer, 0, buffer.Length, OnClientSend, ClientStream);
        }

        private void OnClientSend(IAsyncResult ar)
        {
            if (ar.IsCompleted)
            {
                ClientStream.Close();
            }
        }
    }
}

ืื•ืŸ ืคื•ืŸ ืงื•ืจืก, ืื™ืŸ ืกื“ืจ ืคึฟืึทืจ ื“ื™ ื•ื•ืขืจืึทืคืึทืงื™ื™ืฉืึทืŸ ืคื•ืŸ ืึธื˜ืขืจื™ื™ื–ื“ ื ื™ืฆืขืจืก ืฆื• ืึทืจื‘ืขื˜ืŸ, ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืื™ื– ื“ืืจืฃ. ื“ืขืจ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืžืึธื“ื•ืœืข ื™ื ื˜ืขืจืึทืงืฅ ืžื™ื˜ ื“ื™ ื“ืึทื˜ืึทื‘ื™ื™ืก. ื“ื™ ื‘ืืงื•ืžืขืŸ ื“ืึทื˜ืŸ ืคื•ืŸ ืคืืจืžืขืŸ ืื•ื™ืฃ ื“ืขื ืคึผืœืึทืฅ ื–ืขื ืขืŸ ืคึผืึทืจืกืขื“ ืคื•ืŸ ื“ืขื ืงืึธื ื˜ืขืงืกื˜, ื“ืขืจ ื‘ืึทื ื™ืฆืขืจ ืื™ื– ื’ืขืจืื˜ืขื•ื•ืขื˜ ืื•ืŸ ืื™ืŸ ืฆื•ืจื™ืงืงื•ืžืขืŸ ื ืขืžื˜ ืงื™ื›ืœืขืš ืื•ืŸ ืึทืงืกืขืก ืฆื• ื“ื™ ื“ื™ื ืกื˜.

ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืžืึธื“ื•ืœืข

using ClearServer.Core.Cookies;
using ClearServer.Core.Requester;
using ClearServer.Core.Security;
using System;
using System.Linq;
using System.Net.Security;
using System.Text;

namespace ClearServer.Core.UserController
{
    internal class AuthorizationController
    {
        private SslStream ClientStream;
        private RequestContext Context;
        private UserCookies cookies;
        private WriteController WriteController;
        DatabaseWorker DatabaseWorker;
        RazorController RazorController;
        PasswordHasher PasswordHasher;
        public AuthorizationController(SslStream clientStream, RequestContext context)
        {
            ClientStream = clientStream;
            Context = context;
            DatabaseWorker = new DatabaseWorker();
            WriteController = new WriteController(ClientStream);
            RazorController = new RazorController(context, clientStream);
            PasswordHasher = new PasswordHasher();
        }

        internal void MethodRecognizer()
        {
            if (Context.FormValues.Count == 2 && Context.FormValues.Any(x => x.Name == "password")) Authorize();
            else if (Context.FormValues.Count == 3 && Context.FormValues.Any(x => x.Name == "regPass")) Registration();
            else
            {
                RazorController.ErrorLoader(401);
            }
        }

        private void Authorize()
        {
            var values = Context.FormValues;
            var user = new User()
            {
                login = values[0].Value,
                password = PasswordHasher.PasswordHash(values[1].Value)
            };
            user = DatabaseWorker.UserAuth(user);
            if (user != null)
            {
                cookies = new UserCookies(user.login, user.password);
                user.cookie = cookies.AuthCookie;
                DatabaseWorker.UserUpdate(user);
                var response = Encoding.UTF8.GetBytes(

quot;HTTP/1.1 301 Moved PermanentlynLocation: /@{user.login}nSet-Cookie: {cookies.AuthCookie}; Expires={DateTime.Now.AddDays(2):R}; Secure; HttpOnlynn");
ClientStream.BeginWrite(response, 0, response.Length, WriteController.OnClientSend, null);

}
else
{
RazorController.ErrorLoader(401);

}
}

private void Registration()
{
var values = Context.FormValues;
var user = new User()
{
name = values[0].Value,
login = values[1].Value,
password = PasswordHasher.PasswordHash(values[2].Value),
};
cookies = new UserCookies(user.login, user.password);
user.cookie = cookies.AuthCookie;
if (DatabaseWorker.LoginValidate(user.login))
{
Console.WriteLine("User ready");
Console.WriteLine(


quot;{user.password} {user.password.Trim().Length}");
DatabaseWorker.UserRegister(user);
var response = Encoding.UTF8.GetBytes(


quot;HTTP/1.1 301 Moved PermanentlynLocation: /@{user.login}nSet-Cookie: {user.cookie}; Expires={DateTime.Now.AddDays(2):R}; Secure; HttpOnlynn");
ClientStream.BeginWrite(response, 0, response.Length, WriteController.OnClientSend, null);
}
else
{
RazorController.ErrorLoader(401);
}
}
}
}

ืื•ืŸ ื“ืึธืก ืื™ื– ื•ื•ื™ ื“ื™ ื“ืึทื˜ืึทื‘ื™ื™ืก ืคึผืจืึทืกืขืกื™ื ื’ ืงื•ืงื˜ ื•ื•ื™:

Database

using ClearServer.Core.UserController;
using System;
using System.Data.Linq;
using System.Linq;

namespace ClearServer
{
    class DatabaseWorker
    {

        private readonly Table<User> users = null;
        private readonly DataContext DataBase = null;
        private const string connectionStr = @"ะฟัƒั‚ัŒะบะฑะฐะทะต";

        public DatabaseWorker()
        {
            DataBase = new DataContext(connectionStr);
            users = DataBase.GetTable<User>();
        }

        public User UserAuth(User User)
        {
            try
            {
                var user = users.SingleOrDefault(t => t.login.ToLower() == User.login.ToLower() && t.password == User.password);
                if (user != null)
                    return user;
                else
                    return null;
            }
            catch (Exception)
            {
                return null;
            }

        }

        public void UserRegister(User user)
        {
            try
            {
                users.InsertOnSubmit(user);
                DataBase.SubmitChanges();
                Console.WriteLine(

quot;User{user.name} with id {user.uid} added");
foreach (var item in users)
{
Console.WriteLine(item.login + "n");
}
}
catch (Exception e)
{
Console.WriteLine(e);
}

}

public bool LoginValidate(string login)
{
if (users.Any(x => x.login.ToLower() == login.ToLower()))
{
Console.WriteLine("Login already exists");
return false;
}
return true;
}
public void UserUpdate(User user)
{
var UserToUpdate = users.FirstOrDefault(x => x.uid == user.uid);
UserToUpdate = user;
DataBase.SubmitChanges();
Console.WriteLine(


quot;User {UserToUpdate.name} with id {UserToUpdate.uid} updated");
foreach (var item in users)
{
Console.WriteLine(item.login + "n");
}
}
public User CookieValidate(string CookieInput)
{
User user = null;
try
{
user = users.SingleOrDefault(x => x.cookie == CookieInput);
}
catch
{
return null;
}
if (user != null) return user;
else return null;
}
public User FindUser(string login)
{
User user = null;
try
{
user = users.Single(x => x.login.ToLower() == login.ToLower());
if (user != null)
{
return user;
}
else
{
return null;
}
}
catch (Exception)
{
return null;
}
}
}
}


ืื•ืŸ ืึทืœืฅ ืึทืจื‘ืขื˜ ื•ื•ื™ ืงืœืึทืงื•ื•ืขืจืง, ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืื•ืŸ ืจืขื’ื™ืกื˜ืจืึทืฆื™ืข ืึทืจื‘ืขื˜, ื“ื™ ืžื™ื ื™ืžื•ื ืคืึทื ื’ืงืฉืึทื ืึทืœื™ื˜ื™ ืคึฟืึทืจ ืึทืงืกืขืกื™ื ื’ ื“ื™ ืกืขืจื•ื•ื™ืก ืื™ื– ืฉื•ื™ืŸ ื“ืึธืจื˜ ืื•ืŸ ื“ื™ ืฆื™ื™ื˜ ืื™ื– ื’ืขืงื•ืžืขืŸ ืฆื• ืฉืจื™ื™ึทื‘ืŸ ืึท ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืื•ืŸ ื‘ื™ื ื“ืŸ ื“ื™ ื’ืื ืฆืข ื–ืึทืš ืฆื•ื–ืึทืžืขืŸ ืžื™ื˜ ื“ื™ ื”ื•ื™ืคึผื˜ ืคืึทื ื’ืงืฉืึทื ื– ืคึฟืึทืจ ื•ื•ืึธืก ืึทืœืฅ ืื™ื– ื’ืขื˜ืืŸ.

ื˜ืฉืึทืคึผื˜ืขืจ 4. ืคืืจื•ื•ืืจืคืŸ ื“ื™ ื‘ื™ื™ืง

ืฆื• ืจืขื“ื•ืฆื™ืจืŸ ื“ื™ ืึทืจื‘ืขื˜ ืงืึธืก ืคื•ืŸ ืฉืจื™ื™ื‘ืŸ ืฆื•ื•ื™ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทื ื– ืคึฟืึทืจ ืฆื•ื•ื™ื™ ืคึผืœืึทื˜ืคืึธืจืžืก, ืื™ืš ื‘ืึทืฉืœืึธืกืŸ ืฆื• ืžืึทื›ืŸ ืึท ืงืจื™ื™ึทื–-ืคึผืœืึทื˜ืคืึธืจืžืข ืื•ื™ืฃ Xamarin.Forms. ื•ื•ื™ื“ืขืจ, ื“ืึทื ืง ืฆื• ื“ื™ ืคืึทืงื˜ ืึทื– ืขืก ืื™ื– ืื™ืŸ C #. ืื™ืš ื”ืึธื‘ ื’ืขืžืื›ื˜ ืึท ืคึผืจืึธื‘ืข ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืึทื– ืคืฉื•ื˜ ืกืขื ื“ื– ื“ืึทื˜ืŸ ืฆื• ื“ื™ ืกืขืจื•ื•ืขืจ, ืื™ืš ื’ืขืคึฟื•ื ืขืŸ ืึท ื˜ืฉื™ืงืึทื•ื•ืข ืคื•ื ื˜. ืคึฟืึทืจ ืึท ื‘ืงืฉื” ืคื•ืŸ ืึท ืžื™ื˜ืœ, ืคึฟืึทืจ ืฉืคึผืึทืก, ืื™ืš ื™ืžืคึผืœืึทืžืขื ืึทื“ ืขืก ืื•ื™ืฃ HttpClient ืื•ืŸ ื’ืขืฉื™ืงื˜ ืขืก ืฆื• ื“ื™ HttpRequestMessage ืกืขืจื•ื•ืขืจ, ื•ื•ืึธืก ื›ึผื•ืœืœ ื“ืึทื˜ืŸ ืคึฟื•ืŸ ื“ื™ ื“ืขืจืœื•ื™ื‘ืขื ื™ืฉ ืคืึธืจืขื ืื™ืŸ ื“ื–ืฉืกืึธืŸ ืคึฟืึธืจืžืึทื˜. ืึธืŸ ื“ืขืจ ื”ื•ื™ืคึผื˜ ื“ืขืจื•ื•ืึทืจื˜ืŸ ืขืคึผืขืก, ืื™ืš ื’ืขืขืคื ื˜ ื“ื™ ืกืขืจื•ื•ืขืจ ืงืœืึธืฅ ืื•ืŸ ื’ืขื–ืขืŸ ื“ืึธืจื˜ ืึท ื‘ืงืฉื” ืคื•ืŸ ื“ื™ ืžื™ื˜ืœ ืžื™ื˜ ืึทืœืข ื“ื™ ื“ืึทื˜ืŸ. ื ืงืœื™ื™ืŸ ืฉื˜ื•ืคึผ, ื•ื•ื™ืกื™ืงื™ื™ึทื˜ ืคื•ืŸ ืึทืœืฅ ื•ื•ืึธืก ืื™ื– ื’ืขื˜ืืŸ ืื™ืŸ ื“ื™ ืœืขืฆื˜ืข 3 ื•ื•ืึธื›ืŸ ืื™ืŸ ืึท ืœืึทื ื’ื–ืึทื ืึธื•ื•ื ื˜. ืฆื• ืงืึธื ื˜ืจืึธืœื™ืจืŸ ื“ื™ ืึทืงื™ืขืจืึทืกื™ ืคื•ืŸ ื“ื™ ื’ืขืฉื™ืงื˜ ื“ืึทื˜ืŸ, ืื™ืš ืคืืจื–ืืžืœื˜ ืึท ืคึผืจืึธื‘ืข ืกืขืจื•ื•ืขืจ ืื•ื™ืฃ HttpListner. ื ืึธืš ื‘ืืงื•ืžืขืŸ ืืŸ ืื ื“ืขืจ ื‘ืขื˜ืŸ ืฉื•ื™ืŸ ืื•ื™ืฃ ืขืก, ืื™ืš ื’ืขื ื•ืžืขืŸ ืขืก ื‘ืึทื–ื•ื ื“ืขืจ ืื™ืŸ ืึท ืคึผืึธืจ ืคื•ืŸ ืฉื•ืจื•ืช ืคื•ืŸ ืงืึธื“ ืื•ืŸ ื‘ืืงื•ืžืขืŸ ืึท KeyValuePair ืคื•ืŸ ื“ืึทื˜ืŸ ืคื•ืŸ ื“ื™ ืคืึธืจืขื. ืคึผืึทืจืกื™ื ื’ ื“ื™ ืึธื ืคึฟืจืขื’ ืื™ื– ืจื™ื“ื•ืกื˜ ืฆื• ืฆื•ื•ื™ื™ ืฉื•ืจื•ืช.

ืื™ืš ืกื˜ืึทืจื˜ืขื“ ื˜ืขืกื˜ื™ื ื’ ื•ื•ื™ื™ึทื˜ืขืจ, ืขืก ืื™ื– ื ื™ืฉื˜ ื“ืขืจืžืื ื˜ ืคืจื™ืขืจ, ืึธื‘ืขืจ ืื•ื™ืฃ ื“ื™ ืคืจื™ืขืจื“ื™ืงืข ืกืขืจื•ื•ืขืจ ืื™ืš ืื•ื™ืš ื™ืžืคึผืœืึทืžืขื ืึทื“ ืึท ืฉืžื•ืขืก ื’ืขื‘ื•ื™ื˜ ืื•ื™ืฃ ื•ื•ืขื‘ืกืึธืงืงืขืฅ. ืขืก ื’ืขืืจื‘ืขื˜ ื’ืึทื ืฅ ื’ื•ื˜, ืึธื‘ืขืจ ื“ืขืจ ืคึผืจื™ื ืฆื™ืคึผ ืคื•ืŸ ื™ื ื˜ืขืจืึทืงืฉืึทืŸ ื“ื•ืจืš Tcp ืื™ื– ื’ืขื•ื•ืขืŸ ื“ื™ืคึผืจืขืกื™ื ื’; ืฆื• ืคื™ืœ ื•ืžื ื™ื™ื˜ื™ืง ืึทืจื‘ืขื˜ ื”ืื˜ ืฆื• ื–ื™ื™ืŸ ื’ืขื˜ืืŸ ืฆื• ืงืึทืžืคึผืึทื˜ื™ื ื˜ืœื™ ื‘ื•ื™ืขืŸ ื“ื™ ื™ื ื˜ืขืจืึทืงืฉืึทืŸ ืคื•ืŸ ืฆื•ื•ื™ื™ ื™ื•ื–ืขืจื– ืžื™ื˜ ืึท ืงืึธืจืขืกืคึผืึธื ื“ืขื ืฅ ืงืœืึธืฅ. ื“ืึธืก ื›ื•ืœืœ ืคึผืึทืจืกื™ื ื’ ืึท ื‘ืงืฉื” ืฆื• ื‘ืึทืฉื˜ื™ืžืขืŸ ื“ื™ ืงืฉืจ ืื•ืŸ ืงืึทืœืขืงื˜ื™ื ื’ ืึท ืขื ื˜ืคืขืจ ื ื™ืฆืŸ ื“ื™ RFC 6455. ื“ืขืจื™ื‘ืขืจ, ืื™ืŸ ื“ื™ ืคึผืจื•ื‘ื™ืจืŸ ืกืขืจื•ื•ืขืจ, ืื™ืš ื‘ืึทืฉืœืึธืกืŸ ืฆื• ืฉืึทืคึฟืŸ ืึท ืคึผืฉื•ื˜ ื•ื•ืขื‘ืกืึธืงืงืขื˜ ืงืฉืจ. ื ืึธืจ ืคึฟืึทืจ ืฉืคึผืึทืก.

ืคืึทืจื‘ื™ื ื“ืŸ ืฆื• ืฉืžื•ืขืกืŸ

 private static async void HandleWebsocket(HttpListenerContext context)
        {
            var socketContext = await context.AcceptWebSocketAsync(null);
            var socket = socketContext.WebSocket;
            Locker.EnterWriteLock();
            try
            {
                Clients.Add(socket);
            }
            finally
            {
                Locker.ExitWriteLock();
            }

            while (true)
            {
                var buffer = new ArraySegment<byte>(new byte[1024]);
                var result = await socket.ReceiveAsync(buffer, CancellationToken.None);
                var str = Encoding.Default.GetString(buffer);
                Console.WriteLine(str);

                for (int i = 0; i < Clients.Count; i++)
                {
                    WebSocket client = Clients[i];

                    try
                    {
                        if (client.State == WebSocketState.Open)
                        {
                            
                            await client.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        Locker.EnterWriteLock();
                        try
                        {
                            Clients.Remove(client);
                            i--;
                        }
                        finally
                        {
                            Locker.ExitWriteLock();
                        }
                    }
                }
            }
        }

ืื•ืŸ ืขืก ื’ืขืืจื‘ืขื˜. ื“ืขืจ ืกืขืจื•ื•ืขืจ ื–ื™ืš ืงืึทื ืคื™ื’ื™ืขืจื“ ื“ื™ ืงืฉืจ ืื•ืŸ ื“ื–ืฉืขื ืขืจื™ื™ื˜ืึทื“ ืึท ืขื ื˜ืคืขืจ ืฉืœื™ืกืœ. ืื™ืš ื”ืื˜ ื ื™ืฉื˜ ืืคื™ืœื• ื”ืึธื‘ืŸ ืฆื• ืงืึทื ืคื™ื’ื™ืขืจ ืกืขืจื•ื•ืขืจ ืจืขื’ื™ืกื˜ืจืึทืฆื™ืข ืกืขืคึผืขืจืึทื˜ืœื™ ื“ื•ืจืš ืกืกืœ; ืขืก ืื™ื– ื’ืขื ื•ื’ ืึทื– ื“ื™ ืกื™ืกื˜ืขื ื”ืื˜ ืฉื•ื™ืŸ ืึท ื‘ืึทื•ื•ื™ื™ึทื–ืŸ ืื™ื ืกื˜ืึทืœื™ืจืŸ ืื•ื™ืฃ ื“ื™ ืคืืจืœืื ื’ื˜ ืคึผืึธืจื˜.

ืื•ื™ืฃ ื“ื™ ืžื™ื˜ืœ ื–ื™ื™ึทื˜ ืื•ืŸ ืื•ื™ืฃ ื“ื™ ืคึผืœืึทืฅ ื–ื™ื™ึทื˜, ืฆื•ื•ื™ื™ ืงืœื™ื™ืึทื ืฅ ืคืืจื‘ื™ื˜ืŸ ืึทืจื˜ื™ืงืœืขืŸ, ืึทืœืข ื“ืขื ืื™ื– ื’ืขื•ื•ืขืŸ ืœืึธื’ื“. ืงื™ื™ืŸ ืจื™ื–ื™ืง ืคึผืึทืจืกืขืจืก ืกืœืึธื•ื™ื ื’ ื“ื™ ืกืขืจื•ื•ืขืจ, ืงื™ื™ืŸ ืคื•ืŸ ื“ืขื ืื™ื– ืคืืจืœืื ื’ื˜. ืขื ื˜ืคืขืจ ืฆื™ื™ื˜ ืื™ื– ื“ื™ืงืจื™ืกื˜ ืคื•ืŸ 200ms ืฆื• 40-30ms. ืื•ืŸ ืื™ืš ื‘ื™ืŸ ื’ืขืงื•ืžืขืŸ ืฆื• ื“ืขืจ ืื™ื™ื ืฆื™ืงืขืจ ืจื™ื›ื˜ื™ื’ืขืจ ื‘ืึทืฉืœื•ืก.

ืึทื•ื•ืึทื ืกื™ืจื˜ืข ื•ื•ืขืœืึธืกื™ืคึผืขื“ ื‘ื ื™ืŸ ืึธื“ืขืจ ืงืœื™ืขื ื˜-ืกืขืจื•ื•ืขืจ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ื‘ืื–ื™ืจื˜ ืื•ื™ืฃ C #. ื ืขื˜ ืคืจื™ื™ืžื•ื•ืขืจืง

ื•ื•ืึทืจืคืŸ ื“ื™ ืงืจืึทื ื˜ ืกืขืจื•ื•ืขืจ ื™ืžืคึผืœืึทืžืขื ื˜ื™ื™ืฉืึทืŸ ืื•ื™ืฃ Tcp ืื•ืŸ ืจื™ืจื™ื™ื˜ ืึทืœืฅ ืื•ื ื˜ืขืจ ื”ื˜ื˜ืคึผ. ืื™ืฆื˜ ื“ื™ ืคึผืจื•ื™ืขืงื˜ ืื™ื– ืื™ืŸ ื“ื™ ืจื™ื“ื™ื–ื™ื™ืŸ ื‘ื™ื ืข, ืึธื‘ืขืจ ืœื•ื™ื˜ ื’ืึธืจ ืคืึทืจืฉื™ื“ืขื ืข ืคึผืจื™ื ืกืึทืคึผืึทืœื– ืคื•ืŸ ื™ื ื˜ืขืจืึทืงืฉืึทืŸ. ื“ื™ ืึธืคึผืขืจืึทืฆื™ืข ืคื•ืŸ โ€‹โ€‹ื“ืขื•ื•ื™ืกืขืก ืื•ืŸ ื“ื™ ืคึผืœืึทืฅ ืื™ื– ืกื™ื ื’ืงืจืึทื ื™ื™ื–ื“ ืื•ืŸ ื“ื™ื‘ืึทื’ื“ ืื•ืŸ ื”ืื˜ ืึท ืคึผืจืึธืกื˜ ื‘ืึทื’ืจื™ืฃ, ืžื™ื˜ ื“ืขืจ ื‘ืœื•ื™ื– ื—ื™ืœื•ืง ืื™ื– ืึทื– ืขืก ืื™ื– ื ื™ื˜ ื“ืึทืจืคึฟืŸ ืฆื• ื“ื–ืฉืขื ืขืจื™ื™ื˜ HTML ื‘ืœืขื˜ืขืจ ืคึฟืึทืจ ื“ืขื•ื•ื™ืกืขืก.

ืจืขื–ื•ืœื˜ืึทื˜

"ืื•ื™ื‘ ืื™ืจ ื˜ืึธืŸ ื ื™ื˜ ื•ื•ื™ืกืŸ ื“ืขื ืคืืจื“, ื˜ืึธืŸ ื ื™ื˜ ื’ื™ื™ืŸ ืื™ืŸ ื“ื™ ื•ื•ืึทืกืขืจ" ืื™ืš ื˜ืจืึทื›ื˜ืŸ ืึทื– ืื™ื™ื“ืขืจ ืื™ืš ืึธื ื”ื™ื™ื‘ืŸ ืึทืจื‘ืขื˜, ืื™ืš ื–ืึธืœ ื”ืึธื‘ืŸ ืžืขืจ ืงืœืืจ ื“ื™ืคื™ื™ื ื“ ืฆื™ืœืŸ ืื•ืŸ ืึทื‘ื“ื–ืฉืขืงื˜ื™ื•ื•ื–, ื•ื•ื™ ื’ืขื–ื•ื ื˜ ื•ื•ื™ ื“ื™ืœื•ื•ื•ื“ ืื™ืŸ ื“ื™ ืœืขืจื ืขืŸ ืคื•ืŸ ื“ื™ ื ื™ื™ื˜ื™ืง ื˜ืขืงื ืึทืœืึทื“ื–ืฉื™ื– ืื•ืŸ ืžืขื˜ื”ืึธื“ืก ืคึฟืึทืจ ื–ื™ื™ืขืจ ื™ืžืคึผืœืึทืžืขื ื˜ื™ื™ืฉืึทืŸ ืื•ื™ืฃ ืคืึทืจืฉื™ื“ืŸ ืงืœื™ื™ืึทื ืฅ. ื“ืขืจ ืคึผืจื•ื™ืขืงื˜ ืื™ื– ืฉื•ื™ืŸ ื ืึธืขื ื˜ ืฆื• ืคืึทืจืขื ื“ื™ืงืŸ, ืึธื‘ืขืจ ืืคึฟืฉืจ ืื™ืš ื•ื•ืขื˜ ืงื•ืžืขืŸ ืฆื•ืจื™ืง ืฆื• ืจืขื“ืŸ ื•ื•ืขื’ืŸ ื•ื•ื™ ืื™ืš ื’ืขืจืื˜ืขื•ื•ืขื˜ ื–ื™ื›ืขืจ ื˜ื™ื ื’ื– ื•ื•ื™ื“ืขืจ. ืื™ืš ื’ืขืœืขืจื ื˜ ืึท ืคึผืœืึทืฅ ื‘ืขืฉืึทืก ื“ื™ ืึทื ื˜ื•ื•ื™ืงืœื•ื ื’ ืคึผืจืึธืฆืขืก, ืึธื‘ืขืจ ืขืก ืื™ื– ืืคื™ืœื• ืžืขืจ ืฆื• ืœืขืจื ืขืŸ ืื™ืŸ ื“ืขืจ ืฆื•ืงื•ื ืคึฟื˜. ืื•ื™ื‘ ืื™ืจ ื”ืึธื˜ ืœื™ื™ืขื ืขืŸ ืึทื–ื•ื™ ื•ื•ื™ื™ึทื˜, ื“ืึทื ืงืขืŸ ื“ื™ืจ ืคึฟืึทืจ ื˜ืืŸ ืึทื–ื•ื™.

ืžืงื•ืจ: www.habr.com