public void HexTest() { InfoHash hash = Create(); string hex = hash.ToHex(); Assert.AreEqual(40, hex.Length, "#1"); InfoHash other = InfoHash.FromHex(hex); Assert.AreEqual(hash, other, "#2"); }
void ParseMagnetLink(string url) { string[] splitStr = url.Split('?'); if (splitStr.Length == 0 || splitStr[0] != "magnet:") { throw new FormatException("The magnet link must start with 'magnet:?'."); } if (splitStr.Length == 1) { return;//no parametter } string[] parameters = splitStr[1].Split('&', ';'); for (int i = 0; i < parameters.Length; i++) { string[] keyval = parameters[i].Split('='); if (keyval.Length != 2) { throw new FormatException("A field-value pair of the magnet link contain more than one equal'."); } switch (keyval[0].Substring(0, 2)) { case "xt": //exact topic if (InfoHash != null) { throw new FormatException("More than one infohash in magnet link is not allowed."); } string val = keyval[1].Substring(9); switch (keyval[1].Substring(0, 9)) { case "urn:sha1:": //base32 hash case "urn:btih:": if (val.Length == 32) { InfoHash = InfoHash.FromBase32(val); } else if (val.Length == 40) { InfoHash = InfoHash.FromHex(val); } else { throw new FormatException("Infohash must be base32 or hex encoded."); } break; } break; case "tr": //address tracker var bytes = UriHelper.UrlDecode(keyval[1]); AnnounceUrls.Add(Encoding.UTF8.GetString(bytes, 0, bytes.Length)); break; case "as": //Acceptable Source Webseeds.Add(keyval[1]); break; case "dn": //display name var name = UriHelper.UrlDecode(keyval[1]); Name = Encoding.UTF8.GetString(name, 0, name.Length); break; case "xl": //exact length case "xs": // eXact Source - P2P link. case "kt": //keyword topic case "mt": //manifest topic //not supported for moment break; default: //not supported break; } } }
/// <summary> /// Parses a magnet link from the given Uri. The uri should be in the form magnet:?xt=urn:btih: /// </summary> /// <param name="uri"></param> /// <returns></returns> public static MagnetLink FromUri(Uri uri) { InfoHash infoHash = null; string name = null; var announceUrls = new List <string> (); var webSeeds = new List <string> (); long? size = null; if (uri.Scheme != "magnet") { throw new FormatException("Magnet links must start with 'magnet:'."); } string[] parameters = uri.Query.Substring(1).Split('&'); for (int i = 0; i < parameters.Length; i++) { string[] keyval = parameters[i].Split('='); if (keyval.Length != 2) { // Skip anything we don't understand. Urls could theoretically contain many // unknown parameters. continue; } switch (keyval[0].Substring(0, 2)) { case "xt": //exact topic string val = keyval[1].Substring(9); switch (keyval[1].Substring(0, 9)) { case "urn:sha1:": //base32 hash case "urn:btih:": if (infoHash != null) { throw new FormatException("More than one infohash in magnet link is not allowed."); } if (val.Length == 32) { infoHash = InfoHash.FromBase32(val); } else if (val.Length == 40) { infoHash = InfoHash.FromHex(val); } else { throw new FormatException("Infohash must be base32 or hex encoded."); } break; case "urn:btmh:": // placeholder to parse v2 multihash break; } break; case "tr": //address tracker announceUrls.Add(keyval[1].UrlDecodeUTF8()); break; case "as": //Acceptable Source webSeeds.Add(keyval[1].UrlDecodeUTF8()); break; case "dn": //display name name = keyval[1].UrlDecodeUTF8(); break; case "xl": //exact length size = long.Parse(keyval[1]); break; //case "xs":// eXact Source - P2P link. //case "kt"://keyword topic //case "mt"://manifest topic // Unused //break; default: // Unknown/unsupported break; } } if (infoHash == null) { throw new FormatException("The magnet link did not contain a valid 'xt' parameter referencing the infohash"); } return(new MagnetLink(infoHash, name, announceUrls, webSeeds, size)); }
/// <summary> /// Parses a magnet link from the given Uri. The uri should be in the form magnet:?xt=urn:btih: /// </summary> /// <param name="uri"></param> /// <returns></returns> public static MagnetLink FromUri(Uri uri) { InfoHash infoHash = null; string name = null; var announceUrls = new RawTrackerTier(); var webSeeds = new List <string> (); long? size = null; if (uri.Scheme != "magnet") { throw new FormatException("Magnet links must start with 'magnet:'."); } string[] parameters = uri.Query.Substring(1).Split('&'); for (int i = 0; i < parameters.Length; i++) { string[] keyval = parameters[i].Split('='); if (keyval.Length != 2) { throw new FormatException("A field-value pair of the magnet link contain more than one equal'."); } switch (keyval[0].Substring(0, 2)) { case "xt": //exact topic if (infoHash != null) { throw new FormatException("More than one infohash in magnet link is not allowed."); } string val = keyval[1].Substring(9); switch (keyval[1].Substring(0, 9)) { case "urn:sha1:": //base32 hash case "urn:btih:": if (val.Length == 32) { infoHash = InfoHash.FromBase32(val); } else if (val.Length == 40) { infoHash = InfoHash.FromHex(val); } else { throw new FormatException("Infohash must be base32 or hex encoded."); } break; } break; case "tr": //address tracker announceUrls.Add(keyval[1].UrlDecodeUTF8()); break; case "as": //Acceptable Source webSeeds.Add(keyval[1].UrlDecodeUTF8()); break; case "dn": //display name name = keyval[1].UrlDecodeUTF8(); break; case "xl": //exact length size = long.Parse(keyval [1]); break; case "xs": // eXact Source - P2P link. case "kt": //keyword topic case "mt": //manifest topic //not supported for moment break; default: //not supported break; } } return(new MagnetLink(infoHash, name, announceUrls, webSeeds, size)); }
public void NullHex() { Assert.Throws <ArgumentNullException> (() => { InfoHash.FromHex(null); }); }
public void InvalidHex() { Assert.Throws <ArgumentException> (() => { InfoHash.FromHex("123123123123123123123"); }); }
/// <summary> /// 从给定的Uri解析磁铁链接. uri必须为[magnet:?xt=urn:btih:]开头的Uri对象 /// </summary> /// <param name="uri">以[magnet:?xt=urn:btih:]开头的Uri对象</param> /// <returns></returns> public static MagnetLink FromUri(Uri uri) { InfoHash infoHash = null; string name = null; var announceUrls = new RawTrackerTier(); var webSeeds = new List <string> (); long? size = null; if (uri.Scheme != "magnet") { throw new FormatException("磁力链接必须为'magnet:'开头."); } string[] parameters = uri.Query.Substring(1).Split('&'); for (int i = 0; i < parameters.Length; i++) { string[] keyval = parameters[i].Split('='); if (keyval.Length != 2) { // Skip anything we don't understand. Urls could theoretically contain many // unknown parameters. continue; } switch (keyval[0].Substring(0, 2)) { case "xt": //exact topic if (infoHash != null) { throw new FormatException("磁铁链接中不允许有多个infohash."); } string val = keyval[1].Substring(9); switch (keyval[1].Substring(0, 9)) { case "urn:sha1:": //base32 hash case "urn:btih:": if (val.Length == 32) { infoHash = InfoHash.FromBase32(val); } else if (val.Length == 40) { infoHash = InfoHash.FromHex(val); } else { throw new FormatException("Infohash必须是Base32或十六进制编码."); } break; } break; case "tr": //address tracker announceUrls.Add(keyval[1].UrlDecodeUTF8()); break; case "as": //Acceptable Source webSeeds.Add(keyval[1].UrlDecodeUTF8()); break; case "dn": //display name name = keyval[1].UrlDecodeUTF8(); break; case "xl": //exact length size = long.Parse(keyval[1]); break; //case "xs":// eXact Source - P2P link. //case "kt"://keyword topic //case "mt"://manifest topic // Unused //break; default: // Unknown/unsupported break; } } if (infoHash == null) { throw new FormatException("磁铁链接不包含引用infohash的有效\"xt\"参数"); } return(new MagnetLink(infoHash, name, announceUrls, webSeeds, size)); }
void ParseMagnetLink(string url) { string[] splitStr = url.Split('?'); if (splitStr.Length == 0 || splitStr[0] != "magnet:") { throw new FormatException("The magnet link must start with 'magnet:?'."); } if (splitStr.Length == 1) { return;//no parametter } string[] parameters = splitStr[1].Split('&', ';'); for (int i = 0; i < parameters.Length; i++) { string[] keyval = parameters[i].Split('='); if (keyval.Length != 2) { throw new FormatException("A field-value pair of the magnet link contain more than one equal'."); } switch (keyval[0].Substring(0, 2)) { case "xt": //exact topic if (InfoHash != null) { throw new FormatException("More than one infohash in magnet link is not allowed."); } string val = keyval[1].Substring(9); //TODO: Support more hash encoding scheme //https://en.wikipedia.org/wiki/Magnet_URI_scheme#URN.2C_containing_hash_.28xt.29 switch (keyval[1].Substring(0, 9)) { case "urn:sha1:": //base32 hash case "urn:btih:": if (val.Length == 32) { InfoHash = InfoHash.FromBase32(val); } else if (val.Length == 40) { InfoHash = InfoHash.FromHex(val); } else { throw new FormatException("Infohash must be base32 or hex encoded."); } break; default: throw new FormatException("Infohash must be base32 or hex encoded."); } break; case "dn": //display name Name = System.Web.HttpUtility.UrlDecode(keyval[1]); break; default: //not supported break; } } }