can't think of a good name
some things
This commit is contained in:
parent
a1d57101cb
commit
80a732a371
7 changed files with 170 additions and 46 deletions
|
@ -26,7 +26,9 @@ namespace Kneesocks {
|
||||||
private NetworkStream Stream;
|
private NetworkStream Stream;
|
||||||
|
|
||||||
ReadBuffer Buffer;
|
ReadBuffer Buffer;
|
||||||
private Frame PartialFrame = null;
|
private byte[] FirstTwoBytes = null;
|
||||||
|
private int ExtraHeaderSize = 2;
|
||||||
|
private byte[] FrameHeader = null;
|
||||||
private List<Frame> FrameBuffer = new List<Frame>();
|
private List<Frame> FrameBuffer = new List<Frame>();
|
||||||
|
|
||||||
public bool Disconnected { get; private set; } = false;
|
public bool Disconnected { get; private set; } = false;
|
||||||
|
@ -54,7 +56,9 @@ namespace Kneesocks {
|
||||||
Stream = conn.Stream;
|
Stream = conn.Stream;
|
||||||
|
|
||||||
Buffer = conn.Buffer;
|
Buffer = conn.Buffer;
|
||||||
PartialFrame = conn.PartialFrame;
|
FirstTwoBytes = conn.FirstTwoBytes;
|
||||||
|
ExtraHeaderSize = conn.ExtraHeaderSize;
|
||||||
|
FrameHeader = conn.FrameHeader;
|
||||||
FrameBuffer = conn.FrameBuffer;
|
FrameBuffer = conn.FrameBuffer;
|
||||||
|
|
||||||
Disconnected = conn.Disconnected;
|
Disconnected = conn.Disconnected;
|
||||||
|
@ -69,7 +73,7 @@ namespace Kneesocks {
|
||||||
if(Buffer.IsReading) {
|
if(Buffer.IsReading) {
|
||||||
readBuffer = Buffer.AttemptRead();
|
readBuffer = Buffer.AttemptRead();
|
||||||
if(readBuffer == null) {
|
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");
|
Disconnect(Frame.kClosingReason.ProtocolError, "Timed out waiting for a full response");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -77,7 +81,7 @@ namespace Kneesocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Handshaked) {
|
if(!Handshaked) {
|
||||||
if(!Buffer.IsReading) {
|
if(readBuffer == null) {
|
||||||
readBuffer = Buffer.AttemptRead("\r\n\r\n");
|
readBuffer = Buffer.AttemptRead("\r\n\r\n");
|
||||||
if(readBuffer == null)
|
if(readBuffer == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -98,13 +102,48 @@ namespace Kneesocks {
|
||||||
return null;
|
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) {
|
/*if(!Buffer.IsReading) {
|
||||||
readBuffer = Buffer.AttemptRead("\r\n\r\n");
|
readBuffer = Buffer.AttemptRead("\r\n\r\n");
|
||||||
if(readBuffer == null)
|
if(readBuffer == null)
|
||||||
return null;
|
return null;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
OnParse();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ using Square;
|
||||||
namespace Kneesocks {
|
namespace Kneesocks {
|
||||||
public class Handshake {
|
public class Handshake {
|
||||||
private const string HttpVersion = "1.1";
|
private const string HttpVersion = "1.1";
|
||||||
|
public bool IsRequest = false;
|
||||||
|
|
||||||
public enum kStatusCode {
|
public enum kStatusCode {
|
||||||
Switching_Protocols = 101,
|
Switching_Protocols = 101,
|
||||||
|
@ -28,18 +29,20 @@ namespace Kneesocks {
|
||||||
Service_Unavailable = 503,
|
Service_Unavailable = 503,
|
||||||
Gateway_Timeout = 504
|
Gateway_Timeout = 504
|
||||||
}
|
}
|
||||||
|
public kStatusCode? StatusCode { get; private set; } = null;
|
||||||
public kStatusCode StatusCode { get; private set; } = kStatusCode.Switching_Protocols;
|
|
||||||
protected string StatusCodeText {
|
protected string StatusCodeText {
|
||||||
get {
|
get {
|
||||||
return Enum.GetName(typeof(kStatusCode), StatusCode).Replace('_', ' ');
|
return Enum.GetName(typeof(kStatusCode), StatusCode).Replace('_', ' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, string> Headers =
|
private Dictionary<string, string> Headers =
|
||||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
public string Content { get; set; } = null;
|
public string Content { get; set; } = null;
|
||||||
|
|
||||||
public Handshake(string rawData) {
|
public Handshake(string rawData) {
|
||||||
|
IsRequest = true;
|
||||||
|
|
||||||
var headerLength = rawData.IndexOf("\r\n\r\n");
|
var headerLength = rawData.IndexOf("\r\n\r\n");
|
||||||
if(headerLength == -1)
|
if(headerLength == -1)
|
||||||
throw new FormatException("Header delimeter not found in raw data");
|
throw new FormatException("Header delimeter not found in raw data");
|
||||||
|
@ -55,13 +58,6 @@ namespace Kneesocks {
|
||||||
parts = line.Trim().Split(' ');
|
parts = line.Trim().Split(' ');
|
||||||
if(parts.Length < 3)
|
if(parts.Length < 3)
|
||||||
throw new FormatException("Status line in header malformed");
|
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 {
|
} else {
|
||||||
parts = line.Trim().Split(new char[] {':'}, 2);
|
parts = line.Trim().Split(new char[] {':'}, 2);
|
||||||
if(parts.Length == 2)
|
if(parts.Length == 2)
|
||||||
|
@ -99,10 +95,13 @@ namespace Kneesocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] ToBytes() {
|
public byte[] ToBytes() {
|
||||||
return Encoding.ASCII.GetBytes(ToString());
|
return ToString().GetBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
|
if(IsRequest)
|
||||||
|
throw new NotSupportedException("Cannot create a request string.");
|
||||||
|
|
||||||
if(Content != null) {
|
if(Content != null) {
|
||||||
SetHeader("Content-Length", Content.ByteLength().ToString());
|
SetHeader("Content-Length", Content.ByteLength().ToString());
|
||||||
if(GetHeader("Content-Type") == null)
|
if(GetHeader("Content-Type") == null)
|
||||||
|
@ -115,6 +114,10 @@ namespace Kneesocks {
|
||||||
return raw += "\r\n";
|
return raw += "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasHeader(string name) {
|
||||||
|
return Headers.ContainsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
public string GetHeader(string name) {
|
public string GetHeader(string name) {
|
||||||
if(Headers.ContainsKey(name))
|
if(Headers.ContainsKey(name))
|
||||||
return Headers[name];
|
return Headers[name];
|
||||||
|
|
81
server/Libraries/Square/ArrayExtensions.cs
Normal file
81
server/Libraries/Square/ArrayExtensions.cs
Normal file
|
@ -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<T>(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<T>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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("-", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,17 +26,5 @@ namespace Square {
|
||||||
return hasher.ComputeHash(bytes);
|
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;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,36 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Square {
|
namespace Square {
|
||||||
public static class NumericExtensions {
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ByteArrayExtensions.cs" />
|
<Compile Include="ArrayExtensions.cs" />
|
||||||
<Compile Include="CryptoExtensions.cs" />
|
<Compile Include="CryptoExtensions.cs" />
|
||||||
<Compile Include="NumericExtensions.cs" />
|
<Compile Include="NumericExtensions.cs" />
|
||||||
<Compile Include="StringExtensions.cs" />
|
<Compile Include="StringExtensions.cs" />
|
||||||
|
|
Loading…
Reference in a new issue