public InvalidProtocolEventArgs(Uri uri, IEnumerable <string> remainingSegments, IWwwFormUrlDecoderEntry invalidQueryEntry = null) { this.Uri = uri; this.RemainingSegments = remainingSegments != null?remainingSegments.ToList() : (IEnumerable <string>) new string[0]; if (invalidQueryEntry != null) { this.QueryEntryName = invalidQueryEntry.Name; this.QueryEntryValue = invalidQueryEntry.Value; } }
/// <summary> /// [WIP]<para/> /// Parses XMPP IRIs and URIs based on RFC 5122 and returns the result. /// </summary> /// <param name="uri">The URI or IRI that should get parsed.</param> /// <returns>The URI or IRI result or null if an error occurred.</returns> public static IUriAction parse(Uri uri) { if (!string.IsNullOrEmpty(uri?.OriginalString)) { if (string.Equals(uri.Scheme.ToLowerInvariant(), "xmpp")) { string tmp = uri.OriginalString; // 1. remove 'xmpp:' tmp = tmp.Substring(5); // 2. Authority string authority = null; if (tmp.StartsWith("//")) { tmp.Substring(2); int authEnd = tmp.IndexOf('/'); if (authEnd < 0) { authEnd = tmp.IndexOf('?'); if (authEnd < 0) { authEnd = tmp.IndexOf('#'); if (authEnd < 0) { authEnd = tmp.Length <= 0 ? 0 : tmp.Length - 1; } } authority = tmp.Substring(0, authEnd); tmp = tmp.Substring(authEnd + 1); } } if (string.Equals(uri.AbsolutePath, "iot-register")) { WwwFormUrlDecoder query = parseUriQuery(uri); if (query is null) { return(null); } IWwwFormUrlDecoderEntry macEntry = query.FirstOrDefault(x => x.Name.StartsWith("mac")); if (macEntry is null || string.IsNullOrEmpty(macEntry.Value)) { Logger.Error("None or invalid IoT MAC address: " + uri.OriginalString); return(null); } IWwwFormUrlDecoderEntry algoEntry = query.FirstOrDefault(x => x.Name.StartsWith("algo")); if (algoEntry is null || string.IsNullOrEmpty(algoEntry.Value)) { Logger.Error("None or invalid IoT key algorithm: " + uri.OriginalString); return(null); } IWwwFormUrlDecoderEntry keyEntry = query.FirstOrDefault(x => x.Name.StartsWith("key")); if (keyEntry is null || string.IsNullOrEmpty(keyEntry.Value)) { Logger.Error("None or invalid IoT key: " + uri.OriginalString); return(null); } return(new RegisterIoTUriAction(macEntry.Value, algoEntry.Value, keyEntry.Value)); } else { // Check if is OMEMO fingerprint URI: WwwFormUrlDecoder query = parseUriQuery(uri); if (query is null) { return(null); } IWwwFormUrlDecoderEntry entry = query.FirstOrDefault(x => x.Name.StartsWith("omemo-sid-")); if (!(entry is null)) { ECPubKeyModel pubKey = null; try { byte[] fingerprintBytes = SharedUtils.HexStringToByteArray(entry.Value); pubKey = new ECPubKeyModel(fingerprintBytes); } catch (Exception e) { Logger.Error("Failed to parse XMPP URI. Parsing fingerprint failed: " + entry.Value, e); return(null); } if (uint.TryParse(entry.Name.Replace("omemo-sid-", "").Trim(), out uint deviceId)) { OmemoProtocolAddress address = new OmemoProtocolAddress(uri.LocalPath, deviceId); return(new OmemoFingerprintUriAction(new OmemoFingerprint(pubKey, address))); } else { Logger.Warn("Failed to parse XMPP URI. Invalid device ID: " + entry.Name); } } } } else { Logger.Warn("Failed to parse XMPP URI. No 'xmpp' scheme."); } } return(null); }