using System; using System.Net; using System.Text; using System.Threading; using System.Net.Sockets; using System.Collections.Generic; namespace FilterRest.RestNetworking { internal class RestClient : IDisposable { private Socket ClientSocket; private IPEndPoint ClientEndPoint; private Byte[] ClientBuffer; private Int32 IsConnected; public RestClient(Socket AcceptedSocket, IPEndPoint AcceptedEndPoint) { ClientSocket = AcceptedSocket; ClientEndPoint = AcceptedEndPoint; ClientBuffer = new Byte[1024]; try { ClientSocket.BeginReceive(ClientBuffer, 0, ClientBuffer.Length, SocketFlags.None, new AsyncCallback(TokenReceived), null); } catch { ; Disconnect(); } } private void TokenReceived(IAsyncResult Result) { if (IsConnected != 0) { return; } Int32 ReceivedLength = 0; try { ReceivedLength = ClientSocket.EndReceive(Result); } catch { Disconnect(); return; } if (ReceivedLength >= 1) { Array.Resize(ref ClientBuffer, ReceivedLength); String HTTPRequest = Encoding.ASCII.GetString(ClientBuffer).Split(new String[] { " HTTP/1.1" }, StringSplitOptions.None)[0].Replace("GET /user/v1/", ""); String Type = HTTPRequest.Split('?')[0]; HTTPRequest = HTTPRequest.Replace(String.Format("{0}?", Type), ""); String[] HTTPRequestSplit = HTTPRequest.Split('&'); Dictionary HTTPParameters = new Dictionary(); foreach (String HTTPParameter in HTTPRequestSplit) { HTTPParameters.Add(HTTPParameter.Split('=')[0], HTTPParameter.Split('=')[1]); } if (Type == "getInfo") { String sRealm = HTTPParameters["realm"]; String sToken = HTTPParameters["token"]; String sSig = HTTPParameters["sig"]; Int32 nEMID; Boolean TokenExists = Program.SQL.GetnEMIDFromsToken(sToken, out nEMID); if (!TokenExists) { SendResponse01(); } else if (TokenExists) { Byte nUses = Program.SQL.GetnUsesFromsToken(sToken); String sUsername = Program.SQL.GetsUsernameFromnEMID(nEMID); switch (nUses) { case 0: nUses++; Program.SQL.SetnUsesForsToken(nUses, sToken); SendResponse02(nEMID, sUsername); break; case 1: nUses++; Program.SQL.SetnUsesForsToken(nUses, sToken); SendResponse02(nEMID, sUsername); break; case 2: SendResponse01(); Program.SQL.DeleteFromtTokensUsingsToken(sToken); break; default: nUses++; Program.SQL.SetnUsesForsToken(nUses, sToken); SendResponse02(nEMID, sUsername); break; } if (nUses >= 2) { Program.SQL.DeleteFromtTokensUsingsToken(sToken); } } //else //{ // Byte nUses = Program.SQL.GetnUsesFromsToken(sToken); // if (nUses == 2) // { // SendResponse01(); // if (Convert.ToBoolean(Program.Conf.GetConfigValue("RestTokenAutoDelete"))) // Program.SQL.DeleteFromtTokensUsingsToken(sToken); // } // else // { // nUses++; // String sUsername = Program.SQL.GetsUsernameFromnEMID(nEMID); // Program.SQL.SetnUsesForsToken(nUses, sToken); // SendResponse02(nEMID, sUsername); // if (Convert.ToBoolean(Program.Conf.GetConfigValue("RestTokenAutoDelete"))) // if (nUses >= 2) { Program.SQL.DeleteFromtTokensUsingsToken(sToken); } // } //} } else if (Type == "getPurchasedItems") { SendResponse03(""); } else if (Type == "setItemUsed") { SendResponse04(false); } Disconnect(); } else { Disconnect(); } } private void SendResponse01() { SendHTTPResponse("TokExp"); } private void SendResponse02(Int64 nEMID, String sUsername) { SendHTTPResponse(String.Concat("{\"token_age\":0,\"user_id\":", nEMID, ",\"login\":\"", sUsername, "\",\"user_role\":\"user\",\"blocked\":false}")); } private void SendResponse03(String ItemString) { SendHTTPResponse(String.Concat("{\"items\":[", ItemString, "]}")); } private void SendResponse04(Boolean Successful) { SendHTTPResponse(String.Concat("{\"result\":", Successful, "}")); } private void SendHTTPResponse(String Data) { String Response; Response = String.Format("HTTP/1.1 200 OK{0}", Environment.NewLine); Response = String.Format("{0}Server: Rest Server{1}", Response, Environment.NewLine); Response = String.Format("{0}Content-Type: application/json{1}", Response, Environment.NewLine); Response = String.Format("{0}Expires: Sat, 16 Mar 1991 08:30:00 GMT{1}", Response, Environment.NewLine); Response = String.Format("{0}Cache-Control: no-cache, no-store, must-revalidate{1}", Response, Environment.NewLine); Response = String.Format("{0}Pragma: no-cache{1}", Response, Environment.NewLine); Response = String.Format("{0}Content-Length: {1}{2}", Response, Data.Length, Environment.NewLine); Response = String.Format("{0}{1}{2}", Response, Environment.NewLine, Data); Byte[] ResponseBuffer = Encoding.ASCII.GetBytes(Response); ClientSocket.Send(ResponseBuffer, ResponseBuffer.Length, SocketFlags.None); ClientSocket.Send(ResponseBuffer, ResponseBuffer.Length, SocketFlags.None); } private void Disconnect() { if (IsConnected == 0 && Interlocked.CompareExchange(ref IsConnected, 1, 0) == 0) { try { ClientSocket.Dispose(); } catch { } ClientEndPoint = null; ClientBuffer = new Byte[0]; } } ~RestClient() { Dispose(); } public void Dispose() { Disconnect(); } } }