Title: Invoke-RestMethod -FollowRelLink does not work when links contain commas · Issue #17528 · PowerShell/PowerShell · GitHub
Open Graph Title: Invoke-RestMethod -FollowRelLink does not work when links contain commas · Issue #17528 · PowerShell/PowerShell
X Title: Invoke-RestMethod -FollowRelLink does not work when links contain commas · Issue #17528 · PowerShell/PowerShell
Description: Prerequisites Write a descriptive title. Make sure you are able to repro it on the latest released version Search the existing issues. Refer to the FAQ. Refer to Differences between Windows PowerShell 5.1 and PowerShell. Steps to reprodu...
Open Graph Description: Prerequisites Write a descriptive title. Make sure you are able to repro it on the latest released version Search the existing issues. Refer to the FAQ. Refer to Differences between Windows PowerSh...
X Description: Prerequisites Write a descriptive title. Make sure you are able to repro it on the latest released version Search the existing issues. Refer to the FAQ. Refer to Differences between Windows PowerSh...
Opengraph URL: https://github.com/PowerShell/PowerShell/issues/17528
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Invoke-RestMethod -FollowRelLink does not work when links contain commas","articleBody":"### Prerequisites\r\n\r\n- [X] Write a descriptive title.\r\n- [X] Make sure you are able to repro it on the [latest released version](https://github.com/PowerShell/PowerShell/releases)\r\n- [X] Search the existing issues.\r\n- [X] Refer to the [FAQ](https://github.com/PowerShell/PowerShell/blob/master/docs/FAQ.md).\r\n- [X] Refer to [Differences between Windows PowerShell 5.1 and PowerShell](https://docs.microsoft.com/powershell/scripting/whats-new/differences-from-windows-powershell).\r\n\r\n### Steps to reproduce\r\n\r\nHere is a basic sample with PowerShell based on what the [current code seems to do](https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs#L1865):\r\n\r\n```powershell\r\n[string[]]$Links = \"\u003chttps://some.api.com/api/item?fields=id,description,name\u0026offset=0\u0026limit=1000\u003e;rel=`\"first`\",\u003chttps://some.api.com/api/item?fields=id,short_description,name\u0026offset=1000\u0026limit=1000\u003e;rel=`\"next`\",\u003chttps://some.api.com/api/item?fields=id,short_description,name\u0026offset=4000\u0026limit=1000\u003e;rel=`\"last`\"\"\r\n\r\n$Links[0].Split(',')\r\n```\r\n\r\n**Result**\r\n\r\n```\r\n\u003chttps://some.api.com/api/item?fields=id\r\ndescription\r\nname\u0026offset=0\u0026limit=1000\u003e;rel=\"first\"\r\n\u003chttps://some.api.com/api/item?fields=id\r\nshort_description\r\nname\u0026offset=1000\u0026limit=1000\u003e;rel=\"next\"\r\n\u003chttps://some.api.com/api/item?fields=id\r\nshort_description\r\nname\u0026offset=4000\u0026limit=1000\u003e;rel=\"last\"\r\n```\r\n\r\n### Expected behavior\r\n\r\nInvoke-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.\r\n\r\n**Current** - [ParseLinkHeader](https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs#L1845-L1881)\r\n\r\n**Suggested**\r\n\r\n```csharp\r\ninternal void ParseLinkHeader(HttpResponseMessage response, System.Uri requestUri)\r\n{\r\n if (_relationLink == null)\r\n {\r\n // Must ignore the case of relation links. See RFC 8288 (https://tools.ietf.org/html/rfc8288)\r\n _relationLink = new Dictionary\u003cstring, string\u003e(StringComparer.OrdinalIgnoreCase);\r\n }\r\n else\r\n {\r\n _relationLink.Clear();\r\n }\r\n\r\n // we only support the URL in angle brackets and `rel`, other attributes are ignored\r\n // user can still parse it themselves via the Headers property\r\n const string pattern = \"\u003c(?\u003curl\u003e.*?)\u003e;\\\\s*rel=(?\u003cquoted\u003e\\\")?(?\u003crel\u003e(?(quoted).*?|[^,;]*))(?(quoted)\\\")\";\r\n IEnumerable\u003cstring\u003e links;\r\n if (response.Headers.TryGetValues(\"Link\", out links))\r\n {\r\n foreach (string linkHeader in links)\r\n {\r\n MatchCollection matchCollection = Regex.Matches(link, pattern)\r\n foreach (Match match in matchCollection)\r\n {\r\n if (match.Success)\r\n {\r\n string url = match.Groups[\"url\"].Value;\r\n string rel = match.Groups[\"rel\"].Value;\r\n if (url != string.Empty \u0026\u0026 rel != string.Empty \u0026\u0026 !_relationLink.ContainsKey(rel))\r\n {\r\n Uri absoluteUri = new(requestUri, url);\r\n _relationLink.Add(rel, absoluteUri.AbsoluteUri);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n\r\n### Actual behavior\r\n\r\nSee Steps To Reproduce. Splitting the links returned by a comma breaks the links before they can be parsed by the regex.\r\n\r\n### Error details\r\n\r\nN/A\r\n\r\n### Environment data\r\n\r\n7+\r\n\r\n### Visuals\r\n\r\n_No response_","author":{"url":"https://github.com/ashscodes","@type":"Person","name":"ashscodes"},"datePublished":"2022-06-15T08:47:31.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":2},"url":"https://github.com/17528/PowerShell/issues/17528"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:d7b2d2e5-5fac-554d-2502-df2f6e88e489 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 92D2:22AA41:6DFEE3:9F3B2D:6A54924A |
| html-safe-nonce | 8408d17f6a244536eae3d314aedec4837f97fd110f9151242567aa45e6024fc2 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5MkQyOjIyQUE0MTo2REZFRTM6OUYzQjJEOjZBNTQ5MjRBIiwidmlzaXRvcl9pZCI6IjUzNjU0MTEzMDQxNjAxMzc4MDIiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 6aa521f19c31d6953605b8f93dfe4d15255a063f6415d5da99b9713704b6c85d |
| hovercard-subject-tag | issue:1271889818 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/PowerShell/PowerShell/17528/issue_layout |
| twitter:image | https://opengraph.githubassets.com/cba72b7fe019c4906ac80f6aad97a84b3c53b97f57598e4f81df637f88f642a8/PowerShell/PowerShell/issues/17528 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/cba72b7fe019c4906ac80f6aad97a84b3c53b97f57598e4f81df637f88f642a8/PowerShell/PowerShell/issues/17528 |
| og:image:alt | Prerequisites Write a descriptive title. Make sure you are able to repro it on the latest released version Search the existing issues. Refer to the FAQ. Refer to Differences between Windows PowerSh... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | ashscodes |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| turbo-cache-control | no-preview |
| go-import | github.com/PowerShell/PowerShell git https://github.com/PowerShell/PowerShell.git |
| octolytics-dimension-user_id | 11524380 |
| octolytics-dimension-user_login | PowerShell |
| octolytics-dimension-repository_id | 49609581 |
| octolytics-dimension-repository_nwo | PowerShell/PowerShell |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 49609581 |
| octolytics-dimension-repository_network_root_nwo | PowerShell/PowerShell |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | f8cfff6384f62259baea531c7f58bc7040f8dd92 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width