/// <summary> /// WebSocket implementation OnBinary event handler. /// </summary> private void OnBinary(WebSocket ws, byte[] data) { if (ws != Implementation) { return; } if (HTTPManager.Logger.Level <= BestHTTP.Logger.Loglevels.All) { HTTPManager.Logger.Verbose("WebSocketTransport", "OnBinary"); } if (PacketWithAttachment != null) { switch (this.Manager.Options.ServerVersion) { case SupportedSocketIOVersions.v2: PacketWithAttachment.AddAttachmentFromServer(data, false); break; case SupportedSocketIOVersions.v3: PacketWithAttachment.AddAttachmentFromServer(data, true); break; default: HTTPManager.Logger.Warning("WebSocketTransport", "Binary packet received while the server's version is Unknown. Set SocketOption's ServerVersion to the correct value to avoid packet mishandling!"); // Fall back to V2 by default. this.Manager.Options.ServerVersion = SupportedSocketIOVersions.v2; goto case SupportedSocketIOVersions.v2; } if (PacketWithAttachment.HasAllAttachment) { try { OnPacket(PacketWithAttachment); } catch (Exception ex) { HTTPManager.Logger.Exception("WebSocketTransport", "OnBinary", ex); } finally { PacketWithAttachment = null; } } } else { // Room for improvement: we received an unwanted binary message? } }
private void OnBinary(VRC.Core.BestHTTP.WebSocket.WebSocket ws, byte[] data) { if (ws == Implementation) { if (HTTPManager.Logger.Level <= Loglevels.All) { HTTPManager.Logger.Verbose("WebSocketTransport", "OnBinary"); } if (PacketWithAttachment != null) { PacketWithAttachment.AddAttachmentFromServer(data, copyFull: false); if (PacketWithAttachment.HasAllAttachment) { try { OnPacket(PacketWithAttachment); } catch (Exception ex) { HTTPManager.Logger.Exception("WebSocketTransport", "OnBinary", ex); } finally { PacketWithAttachment = null; } } } } }
/// <summary> /// WebSocket implementation OnBinary event handler. /// </summary> private void OnBinary(WebSocket ws, byte[] data) { HTTPManager.Logger.Verbose("WebSocketTransport", "OnBinary"); if (PacketWithAttachment != null) { PacketWithAttachment.AddAttachmentFromServer(data, false); if (PacketWithAttachment.HasAllAttachment) { try { OnPacket(PacketWithAttachment); } catch (Exception ex) { HTTPManager.Logger.Exception("WebSocketTransport", "OnBinary", ex); } finally { PacketWithAttachment = null; } } } else { // TODO: we received an unwanted binary message? } }
/// <summary> /// WebSocket implementation OnBinary event handler. /// </summary> private void OnBinary(WebSocket ws, byte[] data) { if (ws != Implementation) { return; } if (HTTPManager.Logger.Level <= BestHTTP.Logger.Loglevels.All) { HTTPManager.Logger.Verbose("WebSocketTransport", "OnBinary"); } if (PacketWithAttachment != null) { PacketWithAttachment.AddAttachmentFromServer(data, false); if (PacketWithAttachment.HasAllAttachment) { try { OnPacket(PacketWithAttachment); } catch (Exception ex) { HTTPManager.Logger.Exception("WebSocketTransport", "OnBinary", ex); } finally { PacketWithAttachment = null; } } } else { // Room for improvement: we received an unwanted binary message? } }
private void ParseResponse(HTTPResponse resp) { try { if (resp != null && resp.Data != null && resp.Data.Length >= 1) { string dataAsText = resp.DataAsText; if (!(dataAsText == "ok")) { int num = dataAsText.IndexOf(':', 0); int num2 = 0; while (num >= 0 && num < dataAsText.Length) { int num3 = int.Parse(dataAsText.Substring(num2, num - num2)); string text = dataAsText.Substring(++num, num3); if (text.Length <= 2 || text[0] != 'b' || text[1] != '4') { try { Packet packet = new Packet(text); OnPacket(packet); } catch (Exception ex) { HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket", ex); ((IManager)Manager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); } } else { byte[] data = Convert.FromBase64String(text.Substring(2)); if (PacketWithAttachment != null) { PacketWithAttachment.AddAttachmentFromServer(data, copyFull: true); if (PacketWithAttachment.HasAllAttachment) { try { OnPacket(PacketWithAttachment); } catch (Exception ex2) { HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket with attachment", ex2); ((IManager)Manager).EmitError(SocketIOErrors.Internal, ex2.Message + " " + ex2.StackTrace); } finally { PacketWithAttachment = null; } } } } num2 = num + num3; num = dataAsText.IndexOf(':', num2); } } } } catch (Exception ex3) { ((IManager)Manager).EmitError(SocketIOErrors.Internal, ex3.Message + " " + ex3.StackTrace); HTTPManager.Logger.Exception("PollingTransport", "ParseResponse", ex3); } }
/// <summary> /// Will parse the response, and send out the parsed packets. /// </summary> private void ParseResponse(HTTPResponse resp) { try { if (resp != null && resp.Data != null && resp.Data.Length >= 1) { int idx = 0; while (idx < resp.Data.Length) { PayloadTypes type = PayloadTypes.Text; int length = 0; if (resp.Data[idx] < '0') { type = (PayloadTypes)resp.Data[idx++]; byte num = resp.Data[idx++]; while (num != 0xFF) { length = (length * 10) + num; num = resp.Data[idx++]; } } else { byte next = resp.Data[idx++]; while (next != ':') { length = (length * 10) + (next - '0'); next = resp.Data[idx++]; } // Because length can be different from the byte length, we have to do a little post-processing to support unicode characters. int brackets = 0; int tmpIdx = idx; while (tmpIdx < idx + length) { if (resp.Data[tmpIdx] == '[') { brackets++; } else if (resp.Data[tmpIdx] == ']') { brackets--; } tmpIdx++; } if (brackets > 0) { while (brackets > 0) { if (resp.Data[tmpIdx] == '[') { brackets++; } else if (resp.Data[tmpIdx] == ']') { brackets--; } tmpIdx++; } length = tmpIdx - idx; } } Packet packet = null; switch (type) { case PayloadTypes.Text: packet = new Packet(Encoding.UTF8.GetString(resp.Data, idx, length)); break; case PayloadTypes.Binary: if (PacketWithAttachment != null) { // First byte is the packet type. We can skip it, so we advance our idx and we also have // to decrease length idx++; length--; byte[] buffer = new byte[length]; Array.Copy(resp.Data, idx, buffer, 0, length); PacketWithAttachment.AddAttachmentFromServer(buffer, true); if (PacketWithAttachment.HasAllAttachment) { packet = PacketWithAttachment; PacketWithAttachment = null; } } break; } // switch if (packet != null) { try { OnPacket(packet); } catch (Exception ex) { HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket", ex); (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); } } idx += length; }// while } } catch (Exception ex) { (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); HTTPManager.Logger.Exception("PollingTransport", "ParseResponse", ex); } }
/// <summary> /// Will parse the response, and send out the parsed packets. /// </summary> private void ParseResponse(HTTPResponse resp) { try { if (resp != null && resp.Data != null && resp.Data.Length >= 1) { string msg = resp.DataAsText; if (msg == "ok") { return; } int idx = msg.IndexOf(':', 0); int startIdx = 0; while (idx >= 0 && idx < msg.Length) { int length = int.Parse(msg.Substring(startIdx, idx - startIdx)); string packetData = msg.Substring(++idx, length); // Binary data? if (packetData.Length > 2 && packetData[0] == 'b' && packetData[1] == '4') { byte[] buffer = Convert.FromBase64String(packetData.Substring(2)); if (PacketWithAttachment != null) { PacketWithAttachment.AddAttachmentFromServer(buffer, true); if (PacketWithAttachment.HasAllAttachment) { try { OnPacket(PacketWithAttachment); } catch (Exception ex) { HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket with attachment", ex); (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); } finally { PacketWithAttachment = null; } } } } else { try { Packet packet = new Packet(packetData); OnPacket(packet); } catch (Exception ex) { HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket", ex); (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); } } startIdx = idx + length; idx = msg.IndexOf(':', startIdx); } } } catch (Exception ex) { (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); HTTPManager.Logger.Exception("PollingTransport", "ParseResponse", ex); } }
/// <summary> /// Will parse the response, and send out the parsed packets. /// </summary> private void ParseResponse(HTTPResponse resp) { try { if (resp != null && resp.Data != null && resp.Data.Length >= 1) { // 1.x //00000000 00 09 07 ff 30 7b 22 73 69 64 22 3a 22 6f 69 48 0{"sid":"oiH //00000010 34 31 33 73 61 49 4e 52 53 67 37 41 4b 41 41 41 413saINRSg7AKAAA //00000020 41 22 2c 22 75 70 67 72 61 64 65 73 22 3a 5b 22 A","upgrades":[" //00000030 77 65 62 73 6f 63 6b 65 74 22 5d 2c 22 70 69 6e websocket"],"pin //00000040 67 49 6e 74 65 72 76 61 6c 22 3a 32 35 30 30 30 gInterval":25000 //00000050 2c 22 70 69 6e 67 54 69 6d 65 6f 75 74 22 3a 36 ,"pingTimeout":6 //00000060 30 30 30 30 7d 0000} // 2.x //00000000 39 37 3a 30 7b 22 73 69 64 22 3a 22 73 36 62 5a 97:0{"sid":"s6bZ //00000010 6c 43 37 66 51 59 6b 4f 46 4f 62 35 41 41 41 41 lC7fQYkOFOb5AAAA //00000020 22 2c 22 75 70 67 72 61 64 65 73 22 3a 5b 22 77 ","upgrades":["w //00000030 65 62 73 6f 63 6b 65 74 22 5d 2c 22 70 69 6e 67 ebsocket"],"ping //00000040 49 6e 74 65 72 76 61 6c 22 3a 32 35 30 30 30 2c Interval":25000, //00000050 22 70 69 6e 67 54 69 6d 65 6f 75 74 22 3a 36 30 "pingTimeout":60 //00000060 30 30 30 7d 32 3a 34 30 000}2:40 int idx = 0; while (idx < resp.Data.Length) { PayloadTypes type = PayloadTypes.Text; int length = 0; if (resp.Data[idx] < '0') { type = (PayloadTypes)resp.Data[idx++]; byte num = resp.Data[idx++]; while (num != 0xFF) { length = (length * 10) + num; num = resp.Data[idx++]; } } else { byte next = resp.Data[idx++]; while (next != ':') { length = (length * 10) + (next - '0'); next = resp.Data[idx++]; } } Packet packet = null; switch (type) { case PayloadTypes.Text: packet = new Packet(Encoding.UTF8.GetString(resp.Data, idx, length)); break; case PayloadTypes.Binary: if (PacketWithAttachment != null) { // First byte is the packet type. We can skip it, so we advance our idx and we also have // to decrease length idx++; length--; byte[] buffer = new byte[length]; Array.Copy(resp.Data, idx, buffer, 0, length); PacketWithAttachment.AddAttachmentFromServer(buffer, true); if (PacketWithAttachment.HasAllAttachment) { packet = PacketWithAttachment; PacketWithAttachment = null; } } break; } // switch if (packet != null) { try { OnPacket(packet); } catch (Exception ex) { HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket", ex); (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); } } idx += length; }// while } } catch (Exception ex) { (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); HTTPManager.Logger.Exception("PollingTransport", "ParseResponse", ex); } }
private void ParseResponseV3(HTTPResponse resp) { try { if (resp == null || resp.Data == null || resp.Data.Length < 1) { return; } //HeaderParser contentType = new HeaderParser(resp.GetFirstHeaderValue("content-type")); //PayloadTypes type = contentType.Values.FirstOrDefault().Key == "text/plain" ? PayloadTypes.Text : PayloadTypes.Binary; int idx = 0; while (idx < resp.Data.Length) { int endIdx = FindNextRecordSeparator(resp.Data, idx); int length = endIdx - idx; if (length <= 0) { break; } Packet packet = null; if (resp.Data[idx] == 'b') { if (PacketWithAttachment != null) { // First byte is the binary indicator('b'). We must skip it, so we advance our idx and also have to decrease length idx++; length--; var base64Encoded = System.Text.Encoding.UTF8.GetString(resp.Data, idx, length); PacketWithAttachment.AddAttachmentFromServer(Convert.FromBase64String(base64Encoded), true); if (PacketWithAttachment.HasAllAttachment) { packet = PacketWithAttachment; PacketWithAttachment = null; } } else { HTTPManager.Logger.Warning("PollingTransport", "Received binary but no packet to attach to!"); } } else { packet = new Packet(Encoding.UTF8.GetString(resp.Data, idx, length)); } if (packet != null) { try { OnPacket(packet); } catch (Exception ex) { HTTPManager.Logger.Exception("PollingTransport", "ParseResponseV3 - OnPacket", ex); (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); } } idx = endIdx + 1; } } catch (Exception ex) { (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); HTTPManager.Logger.Exception("PollingTransport", "ParseResponseV3", ex); } }
/// <summary> /// Will parse the response, and send out the parsed packets. /// </summary> private void ParseResponse(HTTPResponse resp) { try { if (resp != null && resp.Data != null && resp.Data.Length >= 1) { int idx = 0; while (idx < resp.Data.Length) { PayloadTypes type = (PayloadTypes)resp.Data[idx++]; int length = 0; byte num = resp.Data[idx++]; while (num != 0xFF) { length = (length * 10) + num; num = resp.Data[idx++]; } Packet packet = null; switch (type) { case PayloadTypes.Text: packet = new Packet(Encoding.UTF8.GetString(resp.Data, idx, length)); break; case PayloadTypes.Binary: if (PacketWithAttachment != null) { // First byte is the packet type. We can skip it, so we advance our idx and we also have // to decrease length idx++; length--; byte[] buffer = new byte[length]; Array.Copy(resp.Data, idx, buffer, 0, length); PacketWithAttachment.AddAttachmentFromServer(buffer, true); if (PacketWithAttachment.HasAllAttachment) { packet = PacketWithAttachment; PacketWithAttachment = null; } } break; } // switch if (packet != null) { try { OnPacket(packet); } catch (Exception ex) { HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket", ex); (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); } } idx += length; }// while } } catch (Exception ex) { (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); HTTPManager.Logger.Exception("PollingTransport", "ParseResponse", ex); } }
/// <summary> /// Will parse the response, and send out the parsed packets. /// </summary> private void ParseResponse(HTTPResponse resp) { try { if (resp != null && resp.Data != null && resp.Data.Length >= 1) { // 1.x //00000000 00 09 07 ff 30 7b 22 73 69 64 22 3a 22 6f 69 48 0{"sid":"oiH //00000010 34 31 33 73 61 49 4e 52 53 67 37 41 4b 41 41 41 413saINRSg7AKAAA //00000020 41 22 2c 22 75 70 67 72 61 64 65 73 22 3a 5b 22 A","upgrades":[" //00000030 77 65 62 73 6f 63 6b 65 74 22 5d 2c 22 70 69 6e websocket"],"pin //00000040 67 49 6e 74 65 72 76 61 6c 22 3a 32 35 30 30 30 gInterval":25000 //00000050 2c 22 70 69 6e 67 54 69 6d 65 6f 75 74 22 3a 36 ,"pingTimeout":6 //00000060 30 30 30 30 7d 0000} // 2.x //00000000 39 37 3a 30 7b 22 73 69 64 22 3a 22 73 36 62 5a 97:0{"sid":"s6bZ //00000010 6c 43 37 66 51 59 6b 4f 46 4f 62 35 41 41 41 41 lC7fQYkOFOb5AAAA //00000020 22 2c 22 75 70 67 72 61 64 65 73 22 3a 5b 22 77 ","upgrades":["w //00000030 65 62 73 6f 63 6b 65 74 22 5d 2c 22 70 69 6e 67 ebsocket"],"ping //00000040 49 6e 74 65 72 76 61 6c 22 3a 32 35 30 30 30 2c Interval":25000, //00000050 22 70 69 6e 67 54 69 6d 65 6f 75 74 22 3a 36 30 "pingTimeout":60 //00000060 30 30 30 7d 32 3a 34 30 000}2:40 //00000000 38 30 3a 34 32 5b 22 50 6f 6c 6c 69 6e 67 20 69 80:42["Polling i //00000010 73 20 77 6f 72 6b 69 6e 67 20 6e 6f 72 6d 61 6c s working normal //00000020 6c 79 20 62 75 74 20 63 72 61 73 68 65 73 20 6f ly but crashes o //00000030 6e 20 72 65 63 65 69 76 69 6e 67 20 6d 75 74 61 n receiving muta //00000040 74 65 64 20 76 6f 77 65 6c 73 20 c3 bc 20 c3 b6 ted vowels //00000050 20 c3 a4 2e 22 5d ."] int idx = 0; while (idx < resp.Data.Length) { PayloadTypes type = PayloadTypes.Text; int length = 0; if (resp.Data[idx] < '0') { type = (PayloadTypes)resp.Data[idx++]; byte num = resp.Data[idx++]; while (num != 0xFF) { length = (length * 10) + num; num = resp.Data[idx++]; } } else { byte next = resp.Data[idx++]; while (next != ':') { length = (length * 10) + (next - '0'); next = resp.Data[idx++]; } } Packet packet = null; switch (type) { case PayloadTypes.Text: // While we already received a length for the packet, it contains the character count of the packet not the byte count. // So, when the packet contains UTF8 characters, length will contain less than the actual byte count. // To fix this, we have to find the last square or curly bracket and if the sent and calculated lengths are different // we will use the larger one. int customLength = 1; byte next = resp.Data[idx]; while (next != SquareBrackets[0] && next != CurlyBrackets[0] && idx + customLength < resp.Data.Length) { next = resp.Data[idx + customLength++]; } if (idx + customLength < resp.Data.Length) { byte[] brackets = SquareBrackets; if (next == CurlyBrackets[0]) { brackets = CurlyBrackets; } int bracketCount = 1; while (bracketCount != 0 && idx + customLength < resp.Data.Length) { next = resp.Data[idx + customLength++]; if (next == brackets[0]) { bracketCount++; } else if (next == brackets[1]) { bracketCount--; } } } packet = new Packet(Encoding.UTF8.GetString(resp.Data, idx, Math.Max(length, customLength))); break; case PayloadTypes.Binary: if (PacketWithAttachment != null) { // First byte is the packet type. We can skip it, so we advance our idx and we also have // to decrease length idx++; length--; byte[] buffer = new byte[length]; Array.Copy(resp.Data, idx, buffer, 0, length); PacketWithAttachment.AddAttachmentFromServer(buffer, true); if (PacketWithAttachment.HasAllAttachment) { packet = PacketWithAttachment; PacketWithAttachment = null; } } break; } // switch if (packet != null) { try { OnPacket(packet); } catch (Exception ex) { HTTPManager.Logger.Exception("PollingTransport", "ParseResponse - OnPacket", ex); (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); } } idx += length; }// while } } catch (Exception ex) { (Manager as IManager).EmitError(SocketIOErrors.Internal, ex.Message + " " + ex.StackTrace); HTTPManager.Logger.Exception("PollingTransport", "ParseResponse", ex); } }