From 80a732a3718b700311d3c6393a527923f265c265 Mon Sep 17 00:00:00 2001 From: Malloc of Kuzkycyziklistan Date: Tue, 9 May 2017 16:08:39 -0500 Subject: [PATCH] can't think of a good name some things --- server/Libraries/Kneesocks/Connection.cs | 51 ++++++++++-- server/Libraries/Kneesocks/Handshake.cs | 23 +++--- server/Libraries/Square/ArrayExtensions.cs | 81 +++++++++++++++++++ .../Libraries/Square/ByteArrayExtensions.cs | 17 ---- server/Libraries/Square/CryptoExtensions.cs | 12 --- server/Libraries/Square/NumericExtensions.cs | 30 +++++++ server/Libraries/Square/Square.csproj | 2 +- 7 files changed, 170 insertions(+), 46 deletions(-) create mode 100644 server/Libraries/Square/ArrayExtensions.cs delete mode 100644 server/Libraries/Square/ByteArrayExtensions.cs diff --git a/server/Libraries/Kneesocks/Connection.cs b/server/Libraries/Kneesocks/Connection.cs index 11e7baf..dab49b4 100644 --- a/server/Libraries/Kneesocks/Connection.cs +++ b/server/Libraries/Kneesocks/Connection.cs @@ -26,7 +26,9 @@ namespace Kneesocks { private NetworkStream Stream; ReadBuffer Buffer; - private Frame PartialFrame = null; + private byte[] FirstTwoBytes = null; + private int ExtraHeaderSize = 2; + private byte[] FrameHeader = null; private List FrameBuffer = new List(); public bool Disconnected { get; private set; } = false; @@ -54,7 +56,9 @@ namespace Kneesocks { Stream = conn.Stream; Buffer = conn.Buffer; - PartialFrame = conn.PartialFrame; + FirstTwoBytes = conn.FirstTwoBytes; + ExtraHeaderSize = conn.ExtraHeaderSize; + FrameHeader = conn.FrameHeader; FrameBuffer = conn.FrameBuffer; Disconnected = conn.Disconnected; @@ -63,13 +67,13 @@ namespace Kneesocks { Handshaked = conn.Handshaked; ClientHandshake = conn.ClientHandshake; } - + public byte[] Parse() { byte[] readBuffer = null; if(Buffer.IsReading) { readBuffer = Buffer.AttemptRead(); if(readBuffer == null) { - if(Buffer.ElapsedReadTime.Seconds > 30) + if(Buffer.ElapsedReadTime.Seconds > (Handshaked ? 300 : 30)) Disconnect(Frame.kClosingReason.ProtocolError, "Timed out waiting for a full response"); return null; @@ -77,7 +81,7 @@ namespace Kneesocks { } if(!Handshaked) { - if(!Buffer.IsReading) { + if(readBuffer == null) { readBuffer = Buffer.AttemptRead("\r\n\r\n"); if(readBuffer == null) return null; @@ -98,13 +102,48 @@ namespace Kneesocks { return null; } + OnParse(); + + if(FirstTwoBytes == null) { + if(readBuffer == null) { + readBuffer = Buffer.AttemptRead(2); + if(readBuffer == null) + return null; + } + + FirstTwoBytes = readBuffer; + ExtraHeaderSize = Frame.HeaderSizeFromBytes(FirstTwoBytes) - 2; + readBuffer = null; + } + + if(FrameHeader == null) { + if(ExtraHeaderSize == 0) + FrameHeader = FirstTwoBytes; + else { + if(readBuffer == null) { + readBuffer = Buffer.AttemptRead(ExtraHeaderSize); + if(readBuffer == null) + return null; + } + + FrameHeader = FirstTwoBytes.Concat(readBuffer).ToArray(); + } + + readBuffer = null; + } + + if(FrameHeader != null) { + var check = Frame.HeaderFromBytes() + + if() + } + /*if(!Buffer.IsReading) { readBuffer = Buffer.AttemptRead("\r\n\r\n"); if(readBuffer == null) return null; }*/ - OnParse(); return null; } diff --git a/server/Libraries/Kneesocks/Handshake.cs b/server/Libraries/Kneesocks/Handshake.cs index 35871ba..0efd5a9 100644 --- a/server/Libraries/Kneesocks/Handshake.cs +++ b/server/Libraries/Kneesocks/Handshake.cs @@ -8,6 +8,7 @@ using Square; namespace Kneesocks { public class Handshake { private const string HttpVersion = "1.1"; + public bool IsRequest = false; public enum kStatusCode { Switching_Protocols = 101, @@ -28,18 +29,20 @@ namespace Kneesocks { Service_Unavailable = 503, Gateway_Timeout = 504 } - - public kStatusCode StatusCode { get; private set; } = kStatusCode.Switching_Protocols; + public kStatusCode? StatusCode { get; private set; } = null; protected string StatusCodeText { get { return Enum.GetName(typeof(kStatusCode), StatusCode).Replace('_', ' '); } } + private Dictionary Headers = new Dictionary(StringComparer.OrdinalIgnoreCase); public string Content { get; set; } = null; public Handshake(string rawData) { + IsRequest = true; + var headerLength = rawData.IndexOf("\r\n\r\n"); if(headerLength == -1) throw new FormatException("Header delimeter not found in raw data"); @@ -55,13 +58,6 @@ namespace Kneesocks { parts = line.Trim().Split(' '); if(parts.Length < 3) throw new FormatException("Status line in header malformed"); - - /*int code; - if(!int.TryParse(parts[1], out code)) - throw new FormatException("Status code sent is not a number");*/ - - /*if(!Enum.IsDefined(typeof(kStatusCode), code)) - throw new NotSupportedException("Status code not supported");*/ } else { parts = line.Trim().Split(new char[] {':'}, 2); if(parts.Length == 2) @@ -99,10 +95,13 @@ namespace Kneesocks { } public byte[] ToBytes() { - return Encoding.ASCII.GetBytes(ToString()); + return ToString().GetBytes(); } public override string ToString() { + if(IsRequest) + throw new NotSupportedException("Cannot create a request string."); + if(Content != null) { SetHeader("Content-Length", Content.ByteLength().ToString()); if(GetHeader("Content-Type") == null) @@ -115,6 +114,10 @@ namespace Kneesocks { return raw += "\r\n"; } + public bool HasHeader(string name) { + return Headers.ContainsKey(name); + } + public string GetHeader(string name) { if(Headers.ContainsKey(name)) return Headers[name]; diff --git a/server/Libraries/Square/ArrayExtensions.cs b/server/Libraries/Square/ArrayExtensions.cs new file mode 100644 index 0000000..c6687fc --- /dev/null +++ b/server/Libraries/Square/ArrayExtensions.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Square { + public static class ArrayExtensions { + public static T[] Subset(this T[] arr, int offset, int count = -1) { + if(count < 0) + return arr.Skip(offset).ToArray(); + else + return arr.Skip(offset).Take(count).ToArray(); + } + + public static T[] Range(this T[] arr, int start, int end) { + return arr.Subset(start, end - start); + } + } + + public static class ByteArrayExtensions { + public static string Base64Encode(this byte[] bytes) { + return Convert.ToBase64String(bytes); + } + + public static string ToHexString(this byte[] bytes) { + return BitConverter.ToString(bytes).Replace("-", ""); + } + + public static string ToString(this byte[] bytes, bool isUtf8 = true) { + return isUtf8 ? Encoding.UTF8.GetString(bytes) + : Encoding.ASCII.GetString(bytes); + } + + public static byte[] HostToNetworkOrder(this byte[] bytes) { + if(BitConverter.IsLittleEndian) + return bytes.Reverse().ToArray(); + else + return bytes; + } + + public static byte[] NetworkToHostOrder(this byte[] bytes) { + if(BitConverter.IsLittleEndian) + return bytes.Reverse().ToArray(); + else + return bytes; + } + + public static Single UnpackFloat(this byte[] bytes) { + return BitConverter.ToSingle(bytes.NetworkToHostOrder(), 0); + } + + public static Double UnpackDouble(this byte[] bytes) { + return BitConverter.ToDouble(bytes.NetworkToHostOrder(), 0); + } + + public static Int16 UnpackInt16(this byte[] bytes) { + return BitConverter.ToInt16(bytes.NetworkToHostOrder(), 0); + } + + public static UInt16 UnpackUInt16(this byte[] bytes) { + return BitConverter.ToUInt16(bytes.NetworkToHostOrder(), 0); + } + + public static Int32 UnpackInt32(this byte[] bytes) { + return BitConverter.ToInt32(bytes.NetworkToHostOrder(), 0); + } + + public static UInt32 UnpackUInt32(this byte[] bytes) { + return BitConverter.ToUInt32(bytes.NetworkToHostOrder(), 0); + } + + public static Int64 UnpackInt64(this byte[] bytes) { + return BitConverter.ToInt64(bytes.NetworkToHostOrder(), 0); + } + + public static UInt64 UnpackUInt64(this byte[] bytes) { + return BitConverter.ToUInt64(bytes.NetworkToHostOrder(), 0); + } + } +} diff --git a/server/Libraries/Square/ByteArrayExtensions.cs b/server/Libraries/Square/ByteArrayExtensions.cs deleted file mode 100644 index 91b0afc..0000000 --- a/server/Libraries/Square/ByteArrayExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Square { - public static class ByteArrayExtensions { - public static string Base64Encode(this byte[] bytes) { - return Convert.ToBase64String(bytes); - } - - public static string ToHexString(this byte[] bytes) { - return BitConverter.ToString(bytes).Replace("-", ""); - } - } -} diff --git a/server/Libraries/Square/CryptoExtensions.cs b/server/Libraries/Square/CryptoExtensions.cs index c149d1d..38617fd 100644 --- a/server/Libraries/Square/CryptoExtensions.cs +++ b/server/Libraries/Square/CryptoExtensions.cs @@ -26,17 +26,5 @@ namespace Square { return hasher.ComputeHash(bytes); } } - - /*private static string ParseRawHash(byte[] hash, kHashReturnType type) { - switch(type) { - case kHashReturnType.BASE64: - return hash.Base64Encode(); - case kHashReturnType.HEX: - return BitConverter.ToString(hash).Replace("-", ""); - case kHashReturnType.RAW: - default: - return hash; - } - }*/ } } diff --git a/server/Libraries/Square/NumericExtensions.cs b/server/Libraries/Square/NumericExtensions.cs index 10e2957..9b18f73 100644 --- a/server/Libraries/Square/NumericExtensions.cs +++ b/server/Libraries/Square/NumericExtensions.cs @@ -6,6 +6,36 @@ using System.Threading.Tasks; namespace Square { public static class NumericExtensions { + public static byte[] Pack(this Single value) { + return BitConverter.GetBytes(value).HostToNetworkOrder(); + } + public static byte[] Pack(this Double value) { + return BitConverter.GetBytes(value).HostToNetworkOrder(); + } + + public static byte[] Pack(this Int16 value) { + return BitConverter.GetBytes(value).HostToNetworkOrder(); + } + + public static byte[] Pack(this UInt16 value) { + return BitConverter.GetBytes(value).HostToNetworkOrder(); + } + + public static byte[] Pack(this Int32 value) { + return BitConverter.GetBytes(value).HostToNetworkOrder(); + } + + public static byte[] Pack(this UInt32 value) { + return BitConverter.GetBytes(value).HostToNetworkOrder(); + } + + public static byte[] Pack(this Int64 value) { + return BitConverter.GetBytes(value).HostToNetworkOrder(); + } + + public static byte[] Pack(this UInt64 value) { + return BitConverter.GetBytes(value).HostToNetworkOrder(); + } } } diff --git a/server/Libraries/Square/Square.csproj b/server/Libraries/Square/Square.csproj index 3a322fc..a8c16a9 100644 --- a/server/Libraries/Square/Square.csproj +++ b/server/Libraries/Square/Square.csproj @@ -40,7 +40,7 @@ - +