public static extern void HP_Set_FN_Server_OnHandShake(IntPtr pListener, OnHandShake fn);
public void Start() { if (IsRunning) { OnStopped.Invoke(null); return; } IsRunning = true; //enter to an infinite cycle to be able to handle every change in stream while (IsRunning) { while (IsRunning && !_stream.DataAvailable) { ; } while (IsRunning && _client.Available < 3) { ; } if (IsRunning) { Byte[] bytes = new Byte[_client.Available]; _stream.Read(bytes, 0, _client.Available); string data = Encoding.UTF8.GetString(bytes); if (Regex.IsMatch(data, "^GET"))// test if it is handshake { WriteHandShake(_stream, data); OnHandShake?.Invoke(this); } else { bool fin = (bytes[0] & 0b10000000) != 0, mask = (bytes[1] & 0b10000000) != 0; // must be true, "All messages from the client to the server have this bit set" int opcode = bytes[0] & 0b00001111, // expecting 1 - text message msglen = bytes[1] - 128, // & 0111 1111 offset = 2; if (msglen == 126) { // was ToUInt16(bytes, offset) but the result is incorrect msglen = BitConverter.ToUInt16(new byte[] { bytes[3], bytes[2] }, 0); offset = 4; } else if (msglen == 127) { throw new NotImplementedException("Larger messages not implemented"); //Console.WriteLine("TODO: msglen == 127, needs qword to store msglen"); //// i don't really know the byte order, please edit this //msglen = BitConverter.ToUInt64(new byte[] { bytes[5], bytes[4], bytes[3], bytes[2], bytes[9], bytes[8], bytes[7], bytes[6] }, 0); //offset = 10; } if (msglen == 0) { OnData?.Invoke(this, new byte[0]); OnStringData?.Invoke(this, null); } else if (mask) { byte[] decoded = new byte[msglen]; byte[] masks = new byte[4] { bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3] }; offset += 4; for (int i = 0; i < msglen; ++i) { decoded[i] = (byte)(bytes[offset + i] ^ masks[i % 4]); } OnData?.Invoke(this, decoded); OnStringData?.Invoke(this, Encoding.UTF8.GetString(decoded)); } else { throw new NotImplementedException("Mask bit not set"); } } } } _stream?.Close(); _client?.Close(); _stream = null; _client = null; OnStopped.Invoke(this); }
public static extern void HP_Set_FN_Agent_OnHandShake(IntPtr pListener, OnHandShake fn);
public static extern void HP_Set_FN_HttpServer_OnHandShake(IntPtr pListener, OnHandShake fn);