public static bool TryParse(BDictionary message, out FindNodeQuery query) { if (message.Contains("q", new BString("find_node")) && message.TryGetValue("t", out BString transactionId) && transactionId.Length > 0 && message.TryGetValue("a", out BDictionary arguments) && arguments.TryGetValue("id", out BString nodeId) && nodeId.Length == NodeID.Size && arguments.TryGetValue("target", out BString targetId) && targetId.Length == NodeID.Size) { query = new FindNodeQuery(new TransactionID(transactionId), new NodeID(nodeId), new NodeID(targetId)); if (arguments.TryGetValue("want", out BList wantList)) { if (wantList.Contains(new BString("n4"))) { query.Want |= Want.IPv4Nodes; } if (wantList.Contains(new BString("n6"))) { query.Want |= Want.IPv6Nodes; } } return(true); } query = null; return(false); }
public static bool TryParse(BDictionary message, out AnnouncePeerResponse response) { if (message.TryGetValue("t", out BString transactionId) && transactionId.Length > 0 && message.TryGetValue("a", out BDictionary arguments) && arguments.TryGetValue("id", out BString nodeId) && nodeId.Length == NodeID.Size) { response = new AnnouncePeerResponse(new TransactionID(transactionId), new NodeID(nodeId)); return(true); } response = null; return(false); }
public static bool TryParse(BDictionary message, out PingQuery query) { if (message.Contains("q", new BString("ping")) && message.TryGetValue("t", out BString transactionId) && transactionId.Length > 0 && message.TryGetValue("a", out BDictionary arguments) && arguments.TryGetValue("id", out BString nodeId) && nodeId.Length == NodeID.Size) { query = new PingQuery(new TransactionID(transactionId), new NodeID(nodeId)); return(true); } query = null; return(false); }
public static bool TryParse(BDictionary message, out ErrorMessage error) { if (message.TryGetValue("t", out BString transactionId) && transactionId.Length > 0 && message.TryGetValue("e", out BList errorList) && errorList.Count >= 2 && errorList[0] is BInteger errorCode && errorCode >= 201 && errorCode <= 204 && errorList[1] is BString errorMessage) { error = new ErrorMessage(new TransactionID(transactionId), (ErrorCode)errorCode.Value, errorMessage); return(true); } error = null; return(false); }
public static MessageType TryParseMessage(byte[] messageBytes, out BDictionary message) { if (BObject.TryParse(messageBytes, out BObject bObject)) { if (bObject is BDictionary dictionary) { message = dictionary; if (message.TryGetValue("y", out BString type)) { if (!message.ContainsKey <BString>("t")) { return(MessageType.Invalid); } switch (type.Text) { case "q": return(MessageType.Query); case "r": return(MessageType.Response); case "e": return(MessageType.Error); default: return(MessageType.Unknown); } } } } message = null; return(MessageType.Invalid); }
public static bool TryParse(BDictionary message, out FindNodeResponse response) { response = null; if (message.TryGetValue("t", out BString transactionId) && transactionId.Length > 0 && message.TryGetValue("a", out BDictionary arguments) && arguments.TryGetValue("id", out BString nodeId) && nodeId.Length == NodeID.Size) { IPv4Node[] nodes = null; IPv6Node[] nodes6 = null; if (arguments.TryGetValue("nodes", out BString nodeBytes)) { if (!IPv4Node.TryParseCompactNodeInfos(nodeBytes.Bytes, out nodes)) { return(false); } } if (arguments.TryGetValue("nodes6", out BString node6Bytes)) { if (!IPv6Node.TryParseCompactNodeInfos(nodeBytes.Bytes, out nodes6)) { return(false); } } if (nodes != null) { if (nodes6 != null) { response = new FindNodeResponse(new TransactionID(transactionId), new NodeID(nodeId), nodes, nodes6); } else { response = new FindNodeResponse(new TransactionID(transactionId), new NodeID(nodeId), nodes); } } else if (nodes6 != null) { response = new FindNodeResponse(new TransactionID(transactionId), new NodeID(nodeId), nodes6); } } return(response != null); }
public static bool TryParse(BDictionary message, out GetPeersQuery query) { if (message.Contains("q", new BString("get_peers")) && message.TryGetValue("t", out BString transactionId) && transactionId.Length > 0 && message.TryGetValue("a", out BDictionary arguments) && arguments.TryGetValue("id", out BString nodeId) && nodeId.Length == NodeID.Size && arguments.TryGetValue("info_hash", out BString infoHash) && infoHash.Length == InfoHash.Size) { query = new GetPeersQuery(new TransactionID(transactionId), new NodeID(nodeId), new InfoHash(infoHash)); if (arguments.TryGetValue("want", out BList wantList)) { if (wantList.Contains(new BString("n4"))) query.Want |= Want.IPv4Nodes; if (wantList.Contains(new BString("n6"))) query.Want |= Want.IPv6Nodes; } return true; } query = null; return false; }
public static bool TryParse(BDictionary message, out AnnouncePeerQuery query) { if (message.Contains("q", new BString("announce_peer")) && message.TryGetValue("t", out BString transactionId) && transactionId.Length > 0 && message.TryGetValue("a", out BDictionary arguments) && arguments.TryGetValue("id", out BString nodeId) && nodeId.Length == NodeID.Size && arguments.TryGetValue("info_hash", out BString infoHash) && infoHash.Length == InfoHash.Size && arguments.TryGetValue("token", out BString token) && token.Length > 0 && arguments.TryGetValue("port", out BInteger port) && port.Value >= 0 && port.Value < 65536) { bool impliedPort = false; if (arguments.TryGetValue("implied_port", out BInteger impliedPortValue)) { impliedPort = impliedPortValue.Value == 1; } query = new AnnouncePeerQuery( new TransactionID(transactionId), new NodeID(nodeId), new InfoHash(infoHash), new PeerToken(token), (int)port.Value, impliedPort); return(true); } query = null; return(false); }
public static QueryType TryGetQuery(BDictionary message, out Query query) { if (message.TryGetValue("q", out BString type)) { switch (type.Text) { case "ping": if (PingQuery.TryParse(message, out PingQuery pingQuery)) { query = pingQuery; return(QueryType.ping); } break; case "find_node": if (FindNodeQuery.TryParse(message, out FindNodeQuery findNodeQuery)) { query = findNodeQuery; return(QueryType.find_node); } break; case "get_peers": if (GetPeersQuery.TryParse(message, out GetPeersQuery getPeersQuery)) { query = getPeersQuery; return(QueryType.get_peers); } break; case "announce_peer": if (AnnouncePeerQuery.TryParse(message, out AnnouncePeerQuery announcePeerQuery)) { query = announcePeerQuery; return(QueryType.announce_peer); } break; default: query = null; return(QueryType.Unknown); } } query = null; return(QueryType.Invalid); }
public static bool TryGetNonBlankString(this BDictionary d, string key, out string s) { if (!(d.TryGetValue(key, out IBObject op) && op is BString bs)) { s = null; return(false); } var tmp = bs.ToString(); if (!string.IsNullOrWhiteSpace(tmp)) { s = tmp; return(true); } else { s = null; return(false); } }
public static bool TryParse(BDictionary message, out GetPeersResponse response) { response = null; if (message.TryGetValue("t", out BString transactionId) && transactionId.Length > 0 && message.TryGetValue("a", out BDictionary arguments) && arguments.TryGetValue("id", out BString nodeId) && nodeId.Length == NodeID.Size && arguments.TryGetValue("token", out BString token) && token.Length > 0) { if (arguments.TryGetValue("values", out BList values)) { PeerContact[] peers = new PeerContact[values.Count]; for (int i = 0; i < peers.Length; i++) { BObject value = values[i]; if (value is BString peer) { if (peer.Length == IPv4PeerContact.CompactInfoSize) { peers[i] = new IPv4PeerContact(peer); } else if (peer.Length == IPv6PeerContact.CompactInfoSize) { peers[i] = new IPv6PeerContact(peer); } else { return(false); } } else { return(false); } } response = new GetPeersResponse(new TransactionID(transactionId), new NodeID(nodeId), new PeerToken(token), peers); } else { IPv4Node[] nodes = null; IPv6Node[] nodes6 = null; if (arguments.TryGetValue("nodes", out BString nodeBytes)) { if (!IPv4Node.TryParseCompactNodeInfos(nodeBytes.Bytes, out nodes)) { return(false); } } if (arguments.TryGetValue("nodes6", out BString node6Bytes)) { if (!IPv6Node.TryParseCompactNodeInfos(nodeBytes.Bytes, out nodes6)) { return(false); } } if (nodes != null) { if (nodes6 != null) { response = new GetPeersResponse(new TransactionID(transactionId), new NodeID(nodeId), new PeerToken(token), nodes, nodes6); } else { response = new GetPeersResponse(new TransactionID(transactionId), new NodeID(nodeId), new PeerToken(token), nodes); } } else if (nodes6 != null) { response = new GetPeersResponse(new TransactionID(transactionId), new NodeID(nodeId), new PeerToken(token), nodes6); } } } return(response != null); }
async Task HandleVar_Execute_Internal(string id, BDictionary msg, bool expectOne = false, bool rawResults = false) { if (!msg.TryGetValue("args", out var beArgs) || !(beArgs is BString beArgsStr)) { await SendException(id, $"Missing required \"args\" argument."); return; } IReadOnlyDictionary <string, JToken> argMap; try { argMap = JsonConvert.DeserializeObject <IList <IReadOnlyDictionary <string, JToken> > >(beArgsStr.ToString()).First(); } catch (Exception ex) { await SendException(id, $"Couldn't deserialize json payload. Expected a map. Error: {ex.Message}"); return; } if (!argMap.TryGetNonBlankString("connection-string", out var connStr)) { await SendException(id, $"Missing required \"connection-string\" argument."); return; } if (!argMap.TryGetNonBlankString("command-text", out var commandText)) { await SendException(id, $"Missing required \"command-text\" argument."); return; } try { using (var conn = new SqlConnection(connStr)) using (var cmd = conn.CreateCommand()) { await conn.OpenAsync(); cmd.CommandText = commandText; if (argMap.TryGetValue("command-type", out JToken commandTypeTok) && commandTypeTok.Type != JTokenType.Null) { if (commandTypeTok.Type != JTokenType.String) { await SendException(id, $"Expected string. Failing key: \"$.command-type\""); return; } var commandType = commandTypeTok.Value <string>(); switch (commandType) { case "stored-procedure": cmd.CommandType = System.Data.CommandType.StoredProcedure; break; case "text": break; // This is the default default: await SendException(id, $"Expected \"stored-procedure\" | \"text\". Failing key: \"$.command-type\""); return; } } if (argMap.TryGetValue("parameters", out JToken paramTok) && paramTok is JObject paramObj) { foreach (var item in paramObj) { if (!(item.Value is JValue v)) { await SendException(id, $"Can only accept simple values (integers, strings, etc) for parameters. Failing key: \"$.parameters.{item.Key}\""); return; } cmd.Parameters.AddWithValue(item.Key, v.Value); } } var results = new List <object>(); bool multiResultSet; argMap.TryGetBool("multi-rs", out multiResultSet); // same key as next.jdbc using (var rdr = await cmd.ExecuteReaderAsync()) { do { var fieldCount = rdr.FieldCount; var rs = new ResultSet { columns = Enumerable.Range(0, fieldCount) .Select(i => rdr.GetName(i)) .ToArray() }; var isJson = rs.columns.Length == 1 && rs.columns[0] == "JSON_F52E2B61-18A1-11d1-B105-00805F49916B"; if (isJson) { var sb = new StringBuilder(); while (rdr.Read()) { sb.Append(rdr.GetString(0)); } if (expectOne || !multiResultSet) { await SendResult(id, sb.ToString(), isJson : true); return; } else { // @PERF - Think of a way to eliminate deserialize -> serialize for this case var obj = ParseJson(sb.ToString()); results.Add(obj); } } else { var rows = rs.rows = new List <object[]>(); while (rdr.Read()) { var row = new object[fieldCount]; for (int i = 0; i < fieldCount; i++) { rdr.GetValues(row); } rows.Add(row); } if (expectOne) { if (rows.Count > 0) { await SendResult(id, ResultSet2DictArray(rs)[0]); } else { await SendResult(id, null); } return; } results.Add(rawResults ? (object)rs : ResultSet2DictArray(rs)); } } while (rdr.NextResult() && multiResultSet); } object result = null; if (rawResults || multiResultSet) { result = results; } else if (results.Count > 0) { result = results[0]; } await SendResult(id, result); } } catch (Exception ex) { await SendException(id, ex.Message); } }