ãšã³ããªãŒ
ãã¹ãŠã¯ãååãå°ã㪠Web ãµãŒãã¹ãäœæããããšãææ¡ãããšãã«å§ãŸããŸããã IT é¢ä¿è
åãã® Tinder ã®ãããªãã®ã«ãªãã¯ãã§ããã æ©èœã¯éåžžã«ã·ã³ãã«ã§ãç»é²ããŠãããã£ãŒã«ãèšå
¥ãã話ãã¹ã人ãèŠã€ããŠäººèãåºããæ°ããç¥ãåããäœããšããäž»èŠãªãã€ã³ãã«é²ã¿ãŸãã
ããã§ç§ã¯äžæŠéããŠãç§èªèº«ã«ã€ããŠå°ã話ããªããã°ãªããŸãããããããã°ããªãç§ãéçºã«ãããŠãã®ãããªæªçœ®ãè¬ããã®ããå°æ¥ããæ確ã«ãªãã§ãããã
çŸæç¹ã§ã¯ãç§ã¯ããã²ãŒã ã¹ã¿ãžãªã§ãã¯ãã«ã« ã¢ãŒãã£ã¹ãã®åœ¹è·ã«å°±ããŠããŸãããC# ã§ã®ããã°ã©ãã³ã°çµéšã¯ãUnity çšã®ã¹ã¯ãªãããšãŠãŒãã£ãªãã£ã®äœæãšãããã«å ã㊠Android ããã€ã¹ã§ã®äœã¬ãã«äœæ¥çšã®ãã©ã°ã€ã³ã®äœæã®ã¿ã«åºã¥ããŠæ§ç¯ãããŠããŸãã ç§ã¯ãŸã ãã®å°ããªäžçãè¶ ããŠåéºãããŠããŸããã§ãããããã®ãããªæ©äŒã蚪ããŸããã
ããŒã 1. ãã¬ãŒã ã®ãããã¿ã€ãã³ã°
ãã®ãµãŒãã¹ãã©ã®ãããªãã®ã§ãããã決ããã®ã§ãå®è£
ã®ãªãã·ã§ã³ãæ¢ãå§ããŸããã æãç°¡åãªã®ã¯ãå°çäžã®ãã¯ããŠã®ããã«ãç§ãã¡ã®ã¡ã«ããã¯ãåŒã£åŒµããããã¹ãŠãå
¬è¡ã®éé£ã«ãããããå¯èœæ§ããããããçš®ã®æ¢è£œã®è§£æ±ºçãèŠã€ããããšã§ãã
ããããããã¯é¢çœããªããäœã®ææŠãæå³ãæããããªãã£ãã®ã§ãWeb ãã¯ãããžãŒãš Web ãã¯ãããžãŒãšå¯Ÿè©±ããæ¹æ³ãå匷ãå§ããŸããã
ç§ã¯ C# .Net ã«é¢ããèšäºãããã¥ã¡ã³ããèŠãŠå匷ãå§ããŸããã ããã§ãã¿ã¹ã¯ãå®äºããããã®ããŸããŸãªæ¹æ³ãèŠã€ããŸããã ASP.Net ã Azure ãµãŒãã¹ã®ãããªæ¬æ Œçãªãœãªã¥ãŒã·ã§ã³ãããTcpHttp æ¥ç¶ãšã®çŽæ¥å¯Ÿè©±ãŸã§ããããã¯ãŒã¯ãšå¯Ÿè©±ããããã®ã¡ã«ããºã ã¯æ°å€ããããŸãã
åã㊠ASP ãå©çšããããšãããšããç§ã¯ããã«æåŠããŸããããç§ã®èãã§ã¯ãããã¯åœç€Ÿã®ãµãŒãã¹ã«ãšã£ãŠã¯é£ãããã決æã§ããã ãã®ãã©ãããã©ãŒã ã®æ©èœã® XNUMX åã® XNUMX ã䜿çšããªãã ãããšããããšã§ãæ€çŽ¢ãç¶ããŸããã éžæã¯ãTCP ãš Http ã¯ã©ã€ã¢ã³ããµãŒããŒã®éã§è¡ãããŸããã ããã§ãããã¬ã«ã€ããŠã®èšäºãèŠã€ããŸããã
ãµãŒããŒã®æåã®ããŒãžã§ã³ã«ã¯ãæ¥ç¶åŠçãéç㪠Web ããŒãž ã³ã³ãã³ãã®æäŸãããã³ãŠãŒã¶ãŒ ããŒã¿ããŒã¹ãå«ãŸããŠããŸããã ãããŠãŸããåŸã§ Android ãš iOS äžã§ã¢ããªã±ãŒã·ã§ã³ã®åŠçãè¿œå ã§ããããã«ããµã€ããšé£æºããããã®æ©èœãæ§ç¯ããããšã«ããŸããã
ããã«ã³ãŒãããããŸã
ç¡éã«ãŒãã§ã¯ã©ã€ã¢ã³ããåä¿¡ããã¡ã€ã³ã¹ã¬ãã:
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 圢åŒã®é åã«å ¥ããŸãããŸããå©çšå¯èœãªå Žåã¯ãä»éããã³ã³ãã³ã (ã¯ãšãªæååãªã©) ãèŠã€ããŠããããåæ§ã®é åã«å ¥ããŸãã ããã«ãããŒãµãŒã¯çŸåšã®ã¯ã©ã€ã¢ã³ããèªèšŒãããŠãããã©ããã調ã¹ããã®ããŒã¿ãä¿åããŸãã æ¿èªãããã¯ã©ã€ã¢ã³ãããã®ãã¹ãŠã®ãªã¯ãšã¹ãã«ã¯ãCookie ã«ä¿åãããæ¿èªããã·ã¥ãå«ãŸããŠããŸããããã«ãããXNUMX çš®é¡ã®ã¯ã©ã€ã¢ã³ãã®åäœããžãã¯ãããã«åé¢ããæ£ããåçãäžããããšãã§ããŸããããã§ããããsite.com/@UserNameãã®ãããªã¯ãšãªãåçã«çæããããŠãŒã¶ãŒ ããŒãžã«å€æãããšãããå¥ã®ã¢ãžã¥ãŒã«ã«çµã¿èŸŒã䟡å€ã®ããå°ãããŠåªããæ©èœã§ãã ãªã¯ãšã¹ãã®åŠçåŸã次ã®ã¢ãžã¥ãŒã«ãæ©èœããŸãã
第3ç« ã¹ãã¢ãªã³ã°ãã€ãŒã«ã®åãä»ãããã§ãŒã³ã®æ³šæ²¹
ããŒãµãŒãäœæ¥ãå®äºãããšããã«ãã³ãã©ãŒãåäœãããµãŒããŒã«ããã«æ瀺ãäžããå¶åŸ¡ã XNUMX ã€ã®éšåã«åå²ããŸãã
åçŽãªãã³ãã©ãŒ
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); }; } } }
å®éããŠãŒã¶ãŒèªèšŒã®ãã§ãã¯ã¯ XNUMX åã ãã§ããã®åŸãªã¯ãšã¹ãã®åŠçãéå§ãããŸãã
ã¯ã©ã€ã¢ã³ãã³ã³ãããŒã©ãŒ
ãŠãŒã¶ãŒãèªå¯ãããŠããªãå Žåããã®ãŠãŒã¶ãŒã®æ©èœã¯ãŠãŒã¶ãŒ ãããã¡ã€ã«ã®è¡šç€ºãšèªå¯ç»é²ãŠã£ã³ããŠã®ã¿ã«åºã¥ããŠããŸãã èš±å¯ããããŠãŒã¶ãŒã®ã³ãŒãã¯ã»ãŒåããªã®ã§ãè€è£œããçç±ã¯ãããŸãããäžæ£ãªãŠãŒã¶ãŒ
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":
returnquot;{Header} text/html";
case ".css":
returnquot;{Header} text/css";
case ".js":
returnquot;{Header} text/javascript";
case ".jpg":
case ".jpeg":
case ".png":
case ".gif":
returnquot;{Header} image/{extension}";
default:
if (extension.Length > 1)
{
returnquot;{Header} application/" + extension.Substring(1);
}
else
{
returnquot;{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(); } } } }
ãããŠãã¡ãããèš±å¯ããããŠãŒã¶ãŒã®æ€èšŒãæ©èœããã«ã¯ãèš±å¯ãå¿ èŠã§ãã èªå¯ã¢ãžã¥ãŒã«ã¯ããŒã¿ããŒã¹ãšå¯Ÿè©±ããŸãã ãµã€ãäžã®ãã©ãŒã ããåä¿¡ããããŒã¿ã¯ã³ã³ããã¹ããã解æããããŠãŒã¶ãŒã¯ä¿åããããã®ä»£ããã« Cookie ãåãåãããµãŒãã¹ã«ã¢ã¯ã»ã¹ããŸãã
èªå¯ã¢ãžã¥ãŒã«
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ç« èªè»¢è»ãæšãŠã
3 ã€ã®ãã©ãããã©ãŒã 㧠XNUMX ã€ã®ã¢ããªã±ãŒã·ã§ã³ãäœæãã人件費ãåæžããããã«ãXamarin.Forms ã§ã¯ãã¹ãã©ãããã©ãŒã ãäœæããããšã«ããŸããã ç¹°ãè¿ããŸãããC# ã§ãããšããäºå®ã®ãããã§ãã ãµãŒããŒã«ããŒã¿ãéä¿¡ããã ãã®ãã¹ã ã¢ããªã±ãŒã·ã§ã³ãäœæãããšãããèå³æ·±ãç¹ã«æ°ã¥ããŸããã ããã€ã¹ããã®ãªã¯ãšã¹ãã«ã€ããŠã¯ã楜ãã¿ã®ããã« HttpClient ã«å®è£ ããJSON 圢åŒã®èªèšŒãã©ãŒã ããã®ããŒã¿ãå«ã HttpRequestMessage ãµãŒããŒã«éä¿¡ããŸããã ç¹ã«äœãæåŸ ããã«ãµãŒã㌠ãã°ãéããšãããã€ã¹ããã®ãªã¯ãšã¹ããšãã¹ãŠã®ããŒã¿ãèšé²ãããŠããŸããã ããããªæè¿·ãæ°ã ããå€ã®äžã§éå»XNUMXé±éã«è¡ããããã¹ãŠã®ããšãæèããŸãã éä¿¡ãããããŒã¿ã®æ£ç¢ºæ§ã確èªããããã«ãHttpListneräžã«ãã¹ããµãŒããŒãæ§ç¯ããŸããã ãã§ã«å¥ã®ãªã¯ãšã¹ããåãåã£ãŠããã®ã§ããããæ°è¡ã®ã³ãŒãã§å解ãããã©ãŒã ããããŒã¿ã® KeyValuePair ãåãåããŸããã ã¯ãšãªã®è§£æ㯠XNUMX è¡ã«æžããŸããã
å ã»ã©ã¯è§ŠããŠããŸããã§ãããã以åã®ãµãŒããŒã§ã¯ WebSocket äžã«æ§ç¯ããããã£ãããå®è£ ããŠãããã«ãã¹ããéå§ããŸããã ããã¯éåžžã«ããŸãæ©èœããŸããããTcp ãä»ãã察話ã®åçèªäœãæ鬱ã§ãéä¿¡ãã°ã䜿çšã㊠6455 人ã®ãŠãŒã¶ãŒã®å¯Ÿè©±ãé©åã«æ§ç¯ããã«ã¯ãããŸãã«ãå€ãã®äžå¿ èŠãªäœæ¥ãè¡ãå¿ èŠããããŸããã ããã«ã¯ãæ¥ç¶ãåãæ¿ãããªã¯ãšã¹ãã®è§£æãš RFC XNUMX ãããã³ã«ã䜿çšããã¬ã¹ãã³ã¹ã®åéãå«ãŸããããããã¹ã ãµãŒããŒã§ã¯åçŽãª WebSocket æ¥ç¶ãäœæããããšã«ããŸããã ãã ã®æ¥œãã¿ã®ããã§ãã
ãã£ããã«æ¥ç¶ãã
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 çµç±ã§ãµãŒããŒç»é²ãåå¥ã«æ§æããå¿ èŠãããªããã·ã¹ãã ã®å¿ èŠãªããŒãã«èšŒææžããã§ã«ã€ã³ã¹ããŒã«ãããŠããã°ååã§ããã
ããã€ã¹åŽãšãµã€ãåŽã§ã200 ã€ã®ã¯ã©ã€ã¢ã³ããã¡ãã»ãŒãžã亀æããããããã¹ãŠèšé²ãããŸããã ãµãŒããŒã®é床ãäœäžããã巚倧ãªããŒãµãŒã¯ãªãããããã¯ã©ããå¿ èŠãããŸããã§ããã å¿çæé㯠40 ããªç§ãã 30 ïœ XNUMX ããªç§ã«ççž®ãããŸããã ãããŠç§ã¯å¯äžæ£ãã決æã«è³ããŸããã
Tcp äžã®çŸåšã®ãµãŒããŒå®è£ ãç Žæ£ããHttp ã®äžã«ãããã®ããã¹ãŠæžãæããŸãã çŸåšããããžã§ã¯ãã¯åèšèšæ®µéã«ãããŸããããŸã£ããç°ãªãçžäºäœçšã®ååã«åŸã£ãŠããŸãã ããã€ã¹ãšãµã€ãã®åäœã¯åæããŠãããã°ãããå ±éã®ã³ã³ã»ãããæã£ãŠããŸããå¯äžã®éãã¯ãããã€ã¹çšã® HTML ããŒãžãçæããå¿ èŠããªãããšã§ãã
åºå
ãæµ ç¬ãç¥ããªããªããæ°Žã«å ¥ããªãã§ãã ããã ä»äºãå§ããåã«ãç®æšãç®çããã£ãšæ確ã«å®çŸ©ããããŸããŸãªã¯ã©ã€ã¢ã³ãã«å®è£ ããããã«å¿ èŠãªæè¡ãææ³ã培åºçã«æ€èšããå¿ èŠããããšæããŸãã ãããžã§ã¯ãã¯ãã§ã«å®æã«è¿ã¥ããŠããŸãããç§ãã©ã®ããã«ããŠç¹å®ã®ãã®ãä¿åãããã«ã€ããŠã¯ãããäžåºŠã話ããããããããŸããã éçºããã»ã¹äžã«å€ãã®ããšãåŠã³ãŸããããå°æ¥çã«ã¯ããã«å€ãã®ããšãåŠã¶å¿ èŠããããŸãã ãããŸã§èªãã§ããã ããæ¹ãããããšãããããŸãã
åºæïŒ habr.com