C# .Net рдлреНрд░реЗрдорд╡рд░реНрдХрдорд╛ рдЖрдзрд╛рд░рд┐рдд рдЙрдиреНрдирдд рд╕рд╛рдЗрдХрд▓ рд╡рд╛ рдХреНрд▓рд╛рдЗрдиреНрдЯ-рд╕рд░реНрднрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ

рдкреНрд░рд╡реЗрд╢

рдпреЛ рд╕рдмреИ рд╕реБрд░реБ рднрдпреЛ рдЬрдм рдПрдХ рд╕рд╣рдХрд░реНрдореАрд▓реЗ рдорд▓рд╛рдИ рдПрдЙрдЯрд╛ рд╕рд╛рдиреЛ рд╡реЗрдм рд╕реЗрд╡рд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рд╕реБрдЭрд╛рд╡ рджрд┐рдПред рдпреЛ Tinder рдЬрд╕реНрддреИ рдХреЗрд╣рд┐ рд╣реБрдиреБ рдкрд░реНрдиреЗ рдерд┐рдпреЛ, рддрд░ IT рднреАрдб рдХреЛ рд▓рд╛рдЧреАред рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдПрдХрджрдореИ рд╕рд░рд▓ рдЫ, рддрдкрд╛рдИрдВрд▓реЗ рджрд░реНрддрд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН, рдкреНрд░реЛрдлрд╛рдЗрд▓ рднрд░реНрдиреБрд╣реЛрд╕реН рд░ рдореБрдЦреНрдп рдмрд┐рдиреНрджреБрдорд╛ рдЬрд╛рдиреБрд╣реЛрд╕реН, рдЕрд░реНрдерд╛рддреН рдХреБрд░рд╛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рд╡реНрдпрдХреНрддрд┐ рдЦреЛрдЬреНрдиреБрд╣реЛрд╕реН рд░ рддрдкрд╛рдИрдВрдХреЛ рдЬрдбрд╛рдирд╣рд░реВ рд╡рд┐рд╕реНрддрд╛рд░ рдЧрд░реНрдиреБрд╣реЛрд╕реН рд░ рдирдпрд╛рдБ рдкрд░рд┐рдЪрд┐рддрд╣рд░реВ рдмрдирд╛рдЙрдиреБрд╣реЛрд╕реНред

рдпрд╣рд╛рдБ рдореИрд▓реЗ рдПрдХ рдкрдЫрд┐ рд╣рдЯреНрдиреБ рдкрд░реНрдЫ рд░ рдореЗрд░реЛ рдмрд╛рд░реЗрдорд╛ рдЕрд▓рд┐рдХрддрд┐ рдмрддрд╛рдЙрдиреБрдкрд░реНрдЫ, рддрд╛рдХрд┐ рднрд╡рд┐рд╖реНрдпрдорд╛ рдореИрд▓реЗ рд╡рд┐рдХрд╛рд╕рдорд╛ рдпрд╕реНрддреЛ рдХрджрдо рдХрд┐рди рдЙрдард╛рдП рднрдиреНрдиреЗ рдХреБрд░рд╛ рдЕрдЭ рд╕реНрдкрд╖реНрдЯ рд╣реБрдиреЗрдЫред

рдпрд╕ рдХреНрд╖рдгрдорд╛ рдо рдПрдЙрдЯрд╛ рдЦреЗрд▓ рд╕реНрдЯреБрдбрд┐рдпреЛрдорд╛ рдкреНрд░рд╛рд╡рд┐рдзрд┐рдХ рдХрд▓рд╛рдХрд╛рд░рдХреЛ рд╕реНрдерд┐рддрд┐рдорд╛ рдЫреБ, C# рдорд╛ рдореЗрд░реЛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдЩ рдЕрдиреБрднрд╡ рдПрдХрддрд╛рдХреЛ рд▓рд╛рдЧрд┐ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд░ рдЙрдкрдпреЛрдЧрд┐рддрд╛рд╣рд░реВ рд▓реЗрдЦреНрдирдорд╛ рдорд╛рддреНрд░ рдмрдирд╛рдЗрдПрдХреЛ рдерд┐рдпреЛ рд░ рдпрд╕рдХрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд, рдПрдиреНрдбреНрд░реЛрдЗрдб рдЙрдкрдХрд░рдгрд╣рд░реВрд╕рдБрдЧ рдирд┐рдореНрди-рд╕реНрддрд░рдХреЛ рдХрд╛рдордХреЛ рд▓рд╛рдЧрд┐ рдкреНрд▓рдЧрдЗрдирд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиред рдо рдЕрдЭреИ рдпреЛ рд╕рд╛рдиреЛ рд╕рдВрд╕рд╛рд░рдмрд╛рдЯ рдмрд╛рд╣рд┐рд░ рдирд┐рд╕реНрдХреЗрдХреЛ рдерд┐рдЗрдирдБ, рд░ рддреНрдпрд╕рдкрдЫрд┐ рдпрд╕реНрддреЛ рдЕрд╡рд╕рд░ рдЖрдпреЛред

рднрд╛рдЧ рез: рдлреНрд░реЗрдо рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдкрд┐рдЩ

рдпреЛ рд╕реЗрд╡рд╛ рдХрд╕реНрддреЛ рд╣реБрдиреЗрдЫ рднрдиреНрдиреЗ рдирд┐рд░реНрдгрдп рдЧрд░реЗрдкрдЫрд┐, рдореИрд▓реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХрд╛ рд▓рд╛рдЧрд┐ рд╡рд┐рдХрд▓реНрдкрд╣рд░реВ рдЦреЛрдЬреНрди рдерд╛рд▓реЗред рд╕рдмреИ рднрдиреНрджрд╛ рд╕рдЬрд┐рд▓реЛ рдХреБрд░рд╛ рдХреБрдиреИ рдкреНрд░рдХрд╛рд░рдХреЛ рддрдпрд╛рд░ рд╕рдорд╛рдзрд╛рди рдЦреЛрдЬреНрдиреБ рд╣реЛ, рдЬрд╕рдорд╛, рд╡рд┐рд╢реНрд╡рдорд╛ рдЙрд▓реНрд▓реВ рдЬрд╕реНрддреИ, рд╣рд╛рдореНрд░реЛ рдореЗрдХрд╛рдирд┐рдХрд▓рд╛рдИ рддрд╛рдиреНрди рд╕рдХрд┐рдиреНрдЫ рд░ рд╕рдореНрдкреВрд░реНрдг рдХреБрд░рд╛рд▓рд╛рдИ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдирд┐рдиреНрджрд╛рдорд╛ рдкрд░реНрджрд╛рдлрд╛рд╕ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред
рддрд░ рдпреЛ рдЪрд╛рдЦрд▓рд╛рдЧреНрджреЛ рдЫреИрди, рдореИрд▓реЗ рдпрд╕рдорд╛ рдХреБрдиреИ рдЪреБрдиреМрддреА рд╡рд╛ рднрд╛рд╡рдирд╛ рджреЗрдЦреЗрдХреЛ рдЫреИрди, рд░ рддреНрдпрд╕реИрд▓реЗ рдореИрд▓реЗ рд╡реЗрдм рдкреНрд░рд╡рд┐рдзрд┐рд╣рд░реВ рд░ рддрд┐рдиреАрд╣рд░реВрд╕рдБрдЧ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрдиреЗ рддрд░рд┐рдХрд╛рд╣рд░реВ рдЕрдзреНрдпрдпрди рдЧрд░реНрди рдерд╛рд▓реЗрдВред

рдореИрд▓реЗ C# .Net рдорд╛ рд▓реЗрдЦ рд░ рдХрд╛рдЧрдЬрд╛рддрд╣рд░реВ рд╣реЗрд░реЗрд░ рдЕрдзреНрдпрдпрди рдЧрд░реНрди рдерд╛рд▓реЗрдВред рдпрд╣рд╛рдБ рдореИрд▓реЗ рдХрд╛рд░реНрдп рдкреВрд░рд╛ рдЧрд░реНрди рд╡рд┐рднрд┐рдиреНрди рддрд░рд┐рдХрд╛рд╣рд░реВ рдлреЗрд▓рд╛ рдкрд╛рд░реЗред ASP.Net рд╡рд╛ Azure рд╕реЗрд╡рд╛рд╣рд░реВ рдЬрд╕реНрддрд╛ рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рдирд╣рд░реВрджреЗрдЦрд┐ рд▓рд┐рдПрд░ TcpHttp рдЬрдбрд╛рдирд╣рд░реВрд╕рдБрдЧ рдкреНрд░рддреНрдпрдХреНрд╖ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрди рдиреЗрдЯрд╡рд░реНрдХрд╕рдБрдЧ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐ рдзреЗрд░реИ рд╕рдВрдпрдиреНрддреНрд░рд╣рд░реВ рдЫрдиреНред

ASP рд╕рдБрдЧ рдореЗрд░реЛ рдкрд╣рд┐рд▓реЛ рдкреНрд░рдпрд╛рд╕ рдЧрд░реЗрдкрдЫрд┐, рдореИрд▓реЗ рдпрд╕рд▓рд╛рдИ рддреБрд░реБрдиреНрддреИ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдЧрд░реЗрдВ; рдореЗрд░реЛ рд╡рд┐рдЪрд╛рд░рдорд╛, рдпреЛ рд╣рд╛рдореНрд░реЛ рд╕реЗрд╡рд╛рдХреЛ рд▓рд╛рдЧрд┐ рдзреЗрд░реИ рдЧрд╛рд╣реНрд░реЛ рдирд┐рд░реНрдгрдп рдерд┐рдпреЛред рд╣рд╛рдореАрд▓реЗ рдпрд╕ рдкреНрд▓реЗрдЯрдлрд░реНрдордХреЛ рдХреНрд╖рдорддрд╛рдХреЛ рдПрдХ рддрд┐рд╣рд╛рдЗ рдкрдирд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рдЫреИрдиреМрдВ, рддреНрдпрд╕реИрд▓реЗ рдореИрд▓реЗ рдореЗрд░реЛ рдЦреЛрдЬ рдЬрд╛рд░реА рд░рд╛рдЦреЗрдВред рдЫрдиреМрдЯ TCP рд░ Http рдЧреНрд░рд╛рд╣рдХ-рд╕рд░реНрднрд░ рдмреАрдЪ рдерд┐рдпреЛред рдпрд╣рд╛рдБ, Habr├й рдорд╛, рдореИрд▓реЗ рдПрдЙрдЯрд╛ рд▓реЗрдЦ рднреЗрдЯреЗрдВ multithreaded рд╕рд░реНрднрд░, рд╕рдЩреНрдХрд▓рди рд░ рдкрд░реАрдХреНрд╖рдг рдЧрд░рд┐рд╕рдХреЗрдкрдЫрд┐, рдореИрд▓реЗ TCP рдЬрдбрд╛рдирд╣рд░реВрд╕рдБрдЧрдХреЛ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛рдорд╛ рд╡рд┐рд╢реЗрд╖ рдзреНрдпрд╛рди рдХреЗрдиреНрджреНрд░рд┐рдд рдЧрд░реНрдиреЗ рдирд┐рд░реНрдгрдп рдЧрд░реЗрдВ, рдХреЗрд╣реА рдХрд╛рд░рдгрд▓реЗ рдореИрд▓реЗ рд╕реЛрдЪреЗ рдХрд┐ 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. рдкрд╛рдЩреНрдЧреНрд░рд╛рд╣рд░реВ рд╕реНрдХреНрд░рд┐рди рдЧрд░реНрджреИ

рд╕рд░реНрднрд░ рдкрд░реАрдХреНрд╖рдг рдЧрд░реЗрдкрдЫрд┐, рдо рдирд┐рд╖реНрдХрд░реНрд╖рдорд╛ рдкреБрдЧреЗрдВ рдХрд┐ рдпреЛ рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рд╕рдорд╛рдзрд╛рди рд╣реБрдиреЗрдЫ (рдмрд┐рдЧрд╛рд░реНрди: рдЫреИрди), рд╣рд╛рдореНрд░реЛ рд╕реЗрд╡рд╛рдХреЛ рд▓рд╛рдЧрд┐, рддреНрдпрд╕реИрд▓реЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рддрд░реНрдХ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрди рдерд╛рд▓реЗред
рдЪрд░рдгрдмрджреНрдз рд░реВрдкрдорд╛, рдирдпрд╛рдБ рдореЛрдбреНрдпреБрд▓рд╣рд░реВ рджреЗрдЦрд╛ рдкрд░реНрди рдерд╛рд▓реЗ рд░ рд╕рд░реНрднрд░рдХреЛ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рднрдпреЛред рд╕рд░реНрднрд░рд▓реЗ рдкрд░реАрдХреНрд╖рдг рдбреЛрдореЗрди рд░ SSL рдЬрдбрд╛рди рдЗрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдкреНрд░рд╛рдкреНрдд рдЧрд░реЗрдХреЛ рдЫред

рд╕рд░реНрднрд░ рд░ рдХреНрд▓рд╛рдЗрдиреНрдЯ рдкреНрд░рд╢реЛрдзрдирдХреЛ рддрд░реНрдХ рд╡рд░реНрдгрди рдЧрд░реНрдиреЗ рдЕрд▓рд┐ рдмрдвреА рдХреЛрдб
рд╕рд░реНрднрд░рдХреЛ рдЕрджреНрдпрд╛рд╡рдзрд┐рдХ рд╕рдВрд╕реНрдХрд░рдг рдЬрд╕рдорд╛ рдкреНрд░рдорд╛рдгрдкрддреНрд░рдХреЛ рдкреНрд░рдпреЛрдЧ рд╕рдорд╛рд╡реЗрд╢ рдЫред

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);
}

}
}

рддрд░ рд╕рд░реНрднрд░рд▓реЗ TCP рдЬрдбрд╛рдирдорд╛ рдорд╛рддреНрд░ рдЪрд▓реНрдиреЗ рднрдПрдХреЛрд▓реЗ, рдЕрдиреБрд░реЛрдзрдХреЛ рд╕рдиреНрджрд░реНрдн рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрди рд╕рдХреНрдиреЗ рдореЛрдбреНрдпреБрд▓ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫред рдореИрд▓реЗ рдирд┐рд░реНрдгрдп рдЧрд░реЗрдВ рдХрд┐ рдпрд╣рд╛рдБ рдПрдХ рдкрд╛рд░реНрд╕рд░ рдЙрдкрдпреБрдХреНрдд рд╣реБрдиреЗрдЫ рдЬрд╕рд▓реЗ рдХреНрд▓рд╛рдЗрдиреНрдЯрдХреЛ рдЕрдиреБрд░реЛрдзрд▓рд╛рдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рднрд╛рдЧрд╣рд░реВрдорд╛ рддреЛрдбреНрдиреЗрдЫ рдЬрд╕рд╕рдБрдЧ рдореИрд▓реЗ рдЧреНрд░рд╛рд╣рдХрд▓рд╛рдИ рдЖрд╡рд╢реНрдпрдХ рдЬрд╡рд╛рдлрд╣рд░реВ рджрд┐рдирдХреЛ рд▓рд╛рдЧрд┐ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрди рд╕рдХреНрдЫреБред

рдкрд╛рд░реНрд╕рд░

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);
}
}
}
}

рд░ рдпреЛ рдбрд╛рдЯрд╛рдмреЗрд╕ рдкреНрд░рд╢реЛрдзрди рдЬрд╕реНрддреЛ рджреЗрдЦрд┐рдиреНрдЫ:

рдбрд╛рдЯрд╛рдмреЗрд╕

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 рд╕рд░реНрднрд░рдорд╛ рдкрдард╛рдПрдБ, рдЬрд╕рдорд╛ json рдврд╛рдБрдЪрд╛рдорд╛ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдлрд╛рд░рдордмрд╛рдЯ рдбрд╛рдЯрд╛ рд╕рдорд╛рд╡реЗрд╢ рдЫред рд╡рд┐рд╢реЗрд╖ рдЧрд░реА рдХреЗрд╣рд┐ рдЕрдкреЗрдХреНрд╖рд╛ рдирдЧрд░реАрдХрди, рдореИрд▓реЗ рд╕рд░реНрднрд░ рд▓рдЧ рдЦреЛрд▓реЗрдВ рд░ рддреНрдпрд╣рд╛рдБ рд╕рдмреИ рдбрд╛рдЯрд╛рдХреЛ рд╕рд╛рде рдЙрдкрдХрд░рдгрдмрд╛рдЯ рдЕрдиреБрд░реЛрдз рджреЗрдЦреЗред рдЕрд▓рд┐рдХрддрд┐ рд╕реНрддрдмреНрдзрддрд╛, рд╡рд┐рдЧрдд 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();
                        }
                    }
                }
            }
        }

рд░ рдпрд╕рд▓реЗ рдХрд╛рдо рдЧрд░реНрдпреЛред рд╕рд░реНрднрд░рд▓реЗ рдЬрдбрд╛рди рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрдпреЛ рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреБрдЮреНрдЬреА рдЙрддреНрдкрдиреНрди рдЧрд░реНрдпреЛред рдореИрд▓реЗ SSL рдорд╛рд░реНрдлрдд рд╕рд░реНрднрд░ рджрд░реНрддрд╛рд▓рд╛рдИ рдЫреБрдЯреНрдЯреИ рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрдиреБрдкрд░реНрджреИрди; рдпреЛ рдкрд░реНрдпрд╛рдкреНрдд рдерд┐рдпреЛ рдХрд┐ рдкреНрд░рдгрд╛рд▓реАрд▓реЗ рдкрд╣рд┐рд▓реЗ рдиреИ рдЖрд╡рд╢реНрдпрдХ рдкреЛрд░реНрдЯрдорд╛ рдкреНрд░рдорд╛рдгрдкрддреНрд░ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реЗрдХреЛ рдерд┐рдпреЛред

рдЙрдкрдХрд░рдг рдЫреЗрдЙрдорд╛ рд░ рд╕рд╛рдЗрдЯ рдЫреЗрдЙрдорд╛, рджреБрдИ рдЧреНрд░рд╛рд╣рдХрд╣рд░реВрд▓реЗ рд╕рдиреНрджреЗрд╢рд╣рд░реВ рдЖрджрд╛рдирдкреНрд░рджрд╛рди рдЧрд░реЗ, рдпреЛ рд╕рдмреИ рд▓рдЧ рдЗрди рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛред рдХреБрдиреИ рдареВрд▓рд╛ рдкрд╛рд░реНрд╕рд░рд╣рд░реВрд▓реЗ рд╕рд░реНрднрд░рд▓рд╛рдИ рдврд┐рд▓реЛ рдЧрд░реНрджреИрди, рдпреЛ рдХреБрдиреИ рдкрдирд┐ рдЖрд╡рд╢реНрдпрдХ рдерд┐рдПрдиред рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп 200ms рдмрд╛рдЯ 40-30ms рдорд╛ рдШрдЯреЗрдХреЛ рдЫред рд░ рдо рдорд╛рддреНрд░ рд╕рд╣реА рдирд┐рд░реНрдгрдпрдорд╛ рдЖрдПрдХреЛ рдЫреБред

C# .Net рдлреНрд░реЗрдорд╡рд░реНрдХрдорд╛ рдЖрдзрд╛рд░рд┐рдд рдЙрдиреНрдирдд рд╕рд╛рдЗрдХрд▓ рд╡рд╛ рдХреНрд▓рд╛рдЗрдиреНрдЯ-рд╕рд░реНрднрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ

Tcp рдорд╛ рд╣рд╛рд▓рдХреЛ рд╕рд░реНрднрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдлреНрдпрд╛рдБрдХреНрдиреБрд╣реЛрд╕реН рд░ Http рдЕрдиреНрддрд░реНрдЧрдд рд╕рдмреИ рдХреБрд░рд╛ рдкреБрди: рд▓реЗрдЦреНрдиреБрд╣реЛрд╕реНред рдЕрдм рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкреБрди: рдбрд┐рдЬрд╛рдЗрди рдЪрд░рдгрдорд╛ рдЫ, рддрд░ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдкреВрд░реНрдг рдлрд░рдХ рд╕рд┐рджреНрдзрд╛рдиреНрдд рдЕрдиреБрд╕рд╛рд░ред рдпрдиреНрддреНрд░рд╣рд░реВ рд░ рд╕рд╛рдЗрдЯрдХреЛ рдЕрдкрд░реЗрд╢рди рд╕рд┐рдЩреНрдХреНрд░реЛрдирд╛рдЗрдЬ рд░ рдбрд┐рдмрдЧ рдЧрд░рд┐рдПрдХреЛ рдЫ рд░ рдПрдХ рд╕рд╛рдЭрд╛ рдЕрд╡рдзрд╛рд░рдгрд╛ рдЫ, рдХреЗрд╡рд▓ рдлрд░рдХ рдпреЛ рд╣реЛ рдХрд┐ рддреНрдпрд╣рд╛рдБ рдЙрдкрдХрд░рдгрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ HTML рдкреГрд╖реНрдард╣рд░реВ рдЙрддреНрдкрдиреНрди рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫреИрдиред

рдирд┐рд╖реНрдХрд░реНрд╖рдорд╛

"рдпрджрд┐ рддрдкрд╛рдИрд▓рд╛рдИ рдлреЛрд░реНрдб рдерд╛рд╣рд╛ рдЫреИрди рднрдиреЗ, рдкрд╛рдиреАрдорд╛ рдирдЬрд╛рдиреБрд╣реЛрд╕реН" рдорд▓рд╛рдИ рд▓рд╛рдЧреНрдЫ рдХрд┐ рдХрд╛рдо рд╕реБрд░реБ рдЧрд░реНрдиреБ рдЕрдШрд┐, рдорд╕рдБрдЧ рдЕрдЭ рд╕реНрдкрд╖реНрдЯ рд░реВрдкрдорд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд▓рдХреНрд╖реНрдпрд╣рд░реВ рд░ рдЙрджреНрджреЗрд╢реНрдпрд╣рд░реВ рд╣реБрдиреБрдкрд░реНрдЫ, рд╕рд╛рдереИ рдЖрд╡рд╢реНрдпрдХ рдкреНрд░рд╡рд┐рдзрд┐рд╣рд░реВ рд░ рд╡рд┐рднрд┐рдиреНрди рдЧреНрд░рд╛рд╣рдХрд╣рд░реВрдорд╛ рддрд┐рдиреАрд╣рд░реВрдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХреЛ рд▓рд╛рдЧрд┐ рд╡рд┐рдзрд┐рд╣рд░реВрдХреЛ рдЕрдзреНрдпрдпрдирдорд╛ рдзреНрдпрд╛рди рджрд┐рдиреБрдкрд░реНрдЫред рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд╣рд┐рд▓реЗ рдиреИ рд╕рдорд╛рдкреНрддрд┐рдХреЛ рдирдЬрд┐рдХ рдЫ, рддрд░ рд╣реБрдирд╕рдХреНрдЫ рдо рдлреЗрд░рд┐ рдХреЗрд╣рд┐ рдЪреАрдЬрд╣рд░реВ рдХрд╕рд░реА рдмрдЪрдд рдЧрд░реЗрдВ рднрдиреЗрд░ рдХреБрд░рд╛ рдЧрд░реНрди рдЖрдЙрдиреЗрдЫреБред рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдорд╛ рдореИрд▓реЗ рдзреЗрд░реИ рдХреБрд░рд╛ рд╕рд┐рдХреЗрдВ, рддрд░ рднрд╡рд┐рд╖реНрдпрдорд╛ рдЕрдЭ рдзреЗрд░реИ рд╕рд┐рдХреНрди рдмрд╛рдБрдХреА рдЫред рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдЕрд╣рд┐рд▓реЗ рд╕рдореНрдо рдкрдвреНрдиреБрднрдПрдХреЛ рдЫ рднрдиреЗ, рддреНрдпрд╕реЛ рдЧрд░реНрдиреБрднрдПрдХреЛрдорд╛ рдзрдиреНрдпрд╡рд╛рджред

рд╕реНрд░реЛрдд: www.habr.com