Last active
April 5, 2024 20:53
-
-
Save pimbrouwers/8f78e318ccfefff18f518a483997be29 to your computer and use it in GitHub Desktop.
C# Parse Link Header
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class LinkHeader | |
{ | |
public string FirstLink { get; set; } | |
public string PrevLink { get; set; } | |
public string NextLink { get; set; } | |
public string LastLink { get; set; } | |
public static LinkHeader LinksFromHeader(string linkHeaderStr) | |
{ | |
LinkHeader linkHeader = null; | |
if (!string.IsNullOrWhiteSpace(linkHeaderStr)) | |
{ | |
string[] linkStrings = linkHeaderStr.Split(','); | |
if (linkStrings != null && linkStrings.Any()) | |
{ | |
linkHeader = new LinkHeader(); | |
foreach (string linkString in linkStrings) | |
{ | |
var relMatch = Regex.Match(linkString, "(?<=rel=\").+?(?=\")", RegexOptions.IgnoreCase); | |
var linkMatch = Regex.Match(linkString, "(?<=<).+?(?=>)", RegexOptions.IgnoreCase); | |
if (relMatch.Success && linkMatch.Success) | |
{ | |
string rel = relMatch.Value.ToUpper(); | |
string link = linkMatch.Value; | |
switch (rel) | |
{ | |
case "FIRST": | |
linkHeader.FirstLink = link; | |
break; | |
case "PREV": | |
linkHeader.PrevLink = link; | |
break; | |
case "NEXT": | |
linkHeader.NextLink = link; | |
break; | |
case "LAST": | |
linkHeader.LastLink = link; | |
break; | |
} | |
} | |
} | |
} | |
} | |
return linkHeader; | |
} | |
} |
Thanks!
thanks
@Knazys, @caiolouro, @iesen -- most welcome :)
Awesome work, many thanks.
Thanks!
Made an F# version:
module Http =
type LinkHeader = {
First : string option
Last : string option
Next : string option
Previous : string option
}
with
static member Empty =
{
First = None
Last = None
Next = None
Previous = None
}
module LinkHeader =
open System.Text.RegularExpressions
let parse (linkHeader : string) =
let linksStrings = linkHeader.Split(',')
let linkHeader = LinkHeader.Empty
let findLink (linkString : string) =
let relMatch = Regex.Match(linkString, "(?<=rel=\").+?(?=\")", RegexOptions.IgnoreCase)
let linkMatch = Regex.Match(linkString, "(?<=<).+?(?=>)", RegexOptions.IgnoreCase)
if relMatch.Success && linkMatch.Success then
Some (relMatch.Value.ToUpper(), linkMatch.Value)
else
None
(linkHeader,linksStrings)
||> Array.fold (fun lh ls ->
match findLink ls with
| Some("FIRST", l) ->
{ lh with First = Option.ofObj l}
| Some("PREV", l) ->
{ lh with Previous = Option.ofObj l}
| Some("NEXT", l) ->
{ lh with Next = Option.ofObj l}
| Some("LAST", l) ->
{ lh with Last = Option.ofObj l}
| _ ->
lh
)
Yasssss @TheAngryByrd!
I added the following ctor.
public static LinkHeader LinksFromHeader(HttpResponseMessage httpResponseMessage)
{
if (httpResponseMessage.Headers.Contains("Link"))
{
return CreateInstance(httpResponseMessage.Headers.GetValues("Link").FirstOrDefault());
}
return null;
}
I am using it to loop though and build a list of GitHub Pull Requests.
var jsonList = new List<string>();
var url = $"{repo.Url}/pulls?state=closed&base=develop";
do
{
HttpResponseMessage response = httpClient.GetAsync(url).Result;
var linkHeader = LinkHeader.LinksFromHeader(response);
using (StreamReader stream = new StreamReader(response.Content.ReadAsStreamAsync().Result))
{
jsonList.Add(stream.ReadToEnd());
}
url = linkHeader.NextLink;
} while (url != null);
return jsonList;
Full Source: https://gist.github.com/Digitalroot/e9ca35596664fccd13494cf2da975aa2
Many thanks Pim! It Works!
Note that this breaks if the URL's themselves have commas in them. A more robust solution is here: https://stackoverflow.com/a/72034960
Works great, thanks!
Is there a JS/TS equivalent to this? If not, could someone please help me with writing this?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank You!