/// <summary>Gets the URLs from the Link HTTP header, if any.</summary> /// <param name="source">The source.</param> /// <returns>The list of URLs.</returns> /// <remarks> /// If there are multiple link headers then they are concatenated. /// <para /> /// Multiple links with the same relation are not filtered out. /// </remarks> public static IEnumerable <HeaderLinkUrl> GetLink(this HttpResponseHeaders source) { IEnumerable <string> values; if (source.TryGetValues(StandardHeaders.Links, out values) && (values?.Any() ?? false)) { foreach (var value in values) { if (String.IsNullOrEmpty(value)) { continue; } //Links are separated by commas var links = value.Split(','); foreach (var link in links) { if (String.IsNullOrEmpty(link)) { continue; } HeaderLinkUrl url; if (HeaderLinkUrl.TryParse(link, out url)) { yield return(url); } } ; } ; } ; }
/// <summary>Attempts to parse a formatted string to a link URL.</summary> /// <param name="value">The value to parse.</param> /// <param name="result">The result.</param> /// <returns><see langword="true"/> if successful or <see langword="false"/> otherwise.</returns> /// <remarks> /// The string is expected to be formatted as required for the LINK header. /// </remarks> public static bool TryParse(string value, out HeaderLinkUrl result) { result = null; if (String.IsNullOrEmpty(value)) { return(false); } //Format is <{url}>[; rel="{rel}"> var match = s_re.Match(value); if (!match.Success) { return(false); } var str = match.Groups["url"]?.Value; Uri uri; if (String.IsNullOrEmpty(str) || !Uri.TryCreate(str, UriKind.Absolute, out uri)) { return(false); } var url = new HeaderLinkUrl(uri); //Parse the relations, if any var relationValue = match.Groups["relation"]?.Value; if (!String.IsNullOrEmpty(relationValue)) { var relations = relationValue.Split(s_relationDelimiters, StringSplitOptions.RemoveEmptyEntries); url.Relations.AddRange(relations); } ; result = url; return(true); }