Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Invoke-RestMethod -FollowRelLink does not work when links contain commas #17528

Copy link
Copy link
@ashscodes

Description

@ashscodes
Issue body actions

Prerequisites

Steps to reproduce

Here is a basic sample with PowerShell based on what the current code seems to do:

[string[]]$Links = "<https://some.api.com/api/item?fields=id,description,name&offset=0&limit=1000>;rel=`"first`",<https://some.api.com/api/item?fields=id,short_description,name&offset=1000&limit=1000>;rel=`"next`",<https://some.api.com/api/item?fields=id,short_description,name&offset=4000&limit=1000>;rel=`"last`""

$Links[0].Split(',')

Result

<https://some.api.com/api/item?fields=id
description
name&offset=0&limit=1000>;rel="first"
<https://some.api.com/api/item?fields=id
short_description
name&offset=1000&limit=1000>;rel="next"
<https://some.api.com/api/item?fields=id
short_description
name&offset=4000&limit=1000>;rel="last"

Expected behavior

Invoke-RestMethod can follow RelLink when a comma does appear within a header url. Although I feel the REST API provider (I discovered this with ServiceNow) should provide urlencoded links, I believe this cannot be relied upon and is an easy fix by using a MatchCollection instead.

Current - ParseLinkHeader

Suggested

internal void ParseLinkHeader(HttpResponseMessage response, System.Uri requestUri)
{
    if (_relationLink == null)
    {
        // Must ignore the case of relation links. See RFC 8288 (https://tools.ietf.org/html/rfc8288)
        _relationLink = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
    }
    else
    {
        _relationLink.Clear();
    }

    // we only support the URL in angle brackets and `rel`, other attributes are ignored
    // user can still parse it themselves via the Headers property
    const string pattern = "<(?<url>.*?)>;\\s*rel=(?<quoted>\")?(?<rel>(?(quoted).*?|[^,;]*))(?(quoted)\")";
    IEnumerable<string> links;
    if (response.Headers.TryGetValues("Link", out links))
    {
        foreach (string linkHeader in links)
        {
            MatchCollection matchCollection = Regex.Matches(link, pattern)
            foreach (Match match in matchCollection)
            {
                if (match.Success)
                {
                    string url = match.Groups["url"].Value;
                    string rel = match.Groups["rel"].Value;
                    if (url != string.Empty && rel != string.Empty && !_relationLink.ContainsKey(rel))
                    {
                        Uri absoluteUri = new(requestUri, url);
                        _relationLink.Add(rel, absoluteUri.AbsoluteUri);
                    }
                }
            }
        }
    }
}

Actual behavior

See Steps To Reproduce. Splitting the links returned by a comma breaks the links before they can be parsed by the regex.

Error details

N/A

Environment data

7+

Visuals

No response

Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-TriageThe issue is new and needs to be triaged by a work group.The issue is new and needs to be triaged by a work group.Resolution-FixedThe issue is fixed.The issue is fixed.WG-Cmdlets-Utilitycmdlets in the Microsoft.PowerShell.Utility modulecmdlets in the Microsoft.PowerShell.Utility module

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.