Skip to content

Link header pagination only parsing first rel #5257

Closed

Description

@dddugan

Steps to reproduce

$uri_base = 'https://MYDEVORG.okta.com'
$apikey = 'MYAPIKEY'
$uri = $uri_base + '/api/v1/users/?filter=status eq "STAGED"&limit=200'
$method = 'GET'
$headers = @{'Accept'='application/json';'Content-Type'='application/json';'Authorization'="SSWS $apikey"}

PS /> $json = Invoke-RestMethod -Uri $uri -Method $method -Headers $headers -FollowRelLink
PS /> $json.Count
200
PS /> $webreq= Invoke-WebRequest -Uri $uri -Method $method -Headers $headers
PS /> $webreq.RelationLink

Key  Value
---  -----
self https://MYDEVORG.okta.com/api/v1/users?limit=200&filter=status+eq+%22STAGED%22


PS /> $webreq.Headers.Link
<https://MYDEVORG.okta.com/api/v1/users?limit=200&filter=status+eq+%22STAGED%22>; rel="self"
<https://MYDEVORG.okta.com/api/v1/users?after=OKTAUSERID&limit=200&filter=status+eq+%22STAGED%22>; rel="next"
PS />

Expected behavior

Invoke-RestMethod should follow the next rel link and return additional results.
Invoke-WebRequest RelationLink dictionary should contain both "self" and "next".

Actual behavior

Only the first value from $webreq.Headers.Link is parsed into RelationLink.

Environment data

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.3 LTS
Release:        16.04
Codename:       xenial
> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.0.0-beta.9
PSEdition                      Core
GitCommitId                    v6.0.0-beta.9
OS                             Linux 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

References

Related commit: 40446c8
Related RFC: https://github.com/PowerShell/PowerShell-RFC/blob/master/2-Draft-Accepted/RFC0021-Link-header-based-pagination-for-WebCmdlets.md

Activity

  1. dddugan commented on Oct 27, 2017

    @dddugan
    Author

    May be due to WebRequestPSCmdlet.CoreClr.cs ParseLinkHeader function using .FirstOrDefault() in the foreach? Also appears that IWR Headers.Link is a comma-separated string on Windows PowerShell, but an array of strings on PowerShell Core.

  2. added this to the milestone on Oct 27, 2017
  3. SteveL-MSFT commented on Oct 28, 2017

    @SteveL-MSFT
    Member

    dddugan can you post the the header section of the RawContent property of the result using Invoke-WebRequest? Feel free to scrub the data, but I'd like to see the format of the returned headers specifically the Link header.

  4. dddugan commented on Oct 28, 2017

    @dddugan
    Author

    There seem to be multiple headers for the multiple values. From my reading of the RFC a single Link: header should support multiple links. I don't see that it's prohibited to do multiple Link: headers instead, but no mention. So maybe I've run into a case where the vendor is doing something unexpected...

    HTTP/1.1 200 OK
    Date: Fri, 27 Oct 2017 14:50:47 GMT
    Server: nginx
    Public-Key-Pins-Report-Only: pin-sha256="abcdzZxQVvQpKo3AgYRaT7X2bDO/kj3ACwmxfdT2zt8="; pin-sha256="abcdcUgk2mvY/RFSGeSwBRkI+rZ6/dxe/DuQfBT/vnQ="; pin-sha256="abcdIEvDEWn+EThf3qjR7/bQSWaS2ZSLqolhnO6iyJI="; pin-sha256="abcdCLCCvqnk89gWibYT0JO6fNQ8cCit7GGoiVTjCOg="; max-age=60; report-uri="https://okta.report-uri.io/r/default/hpkp/reportOnly"
    Vary: Accept-Encoding
    X-Okta-Request-Id: ABCDx63U6bS-Mj9BfeJtBgAACIA
    P3P: CP="HONK"
    X-Rate-Limit-Limit: 600
    X-Rate-Limit-Remaining: 596
    X-Rate-Limit-Reset: 1509115864
    Cache-Control: no-store, no-cache
    Pragma: no-cache
    Link: <https://MYDEVORG.okta.com/api/v1/users?limit=200&filter=status+eq+%22STAGED%22>; rel="self"
    Link: <https://MYDEVORG.okta.com/api/v1/users?after=OKTAID&limit=200&filter=status+eq+%22STAGED%22>; rel="next"
    Strict-Transport-Security: max-age=315360000
    Set-Cookie: sid=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
    Set-Cookie: JSESSIONID=00ABCD87967C1854E80C4BB1245B549E; Path=/
    Transfer-Encoding: chunked
    Content-Type: application/json; charset=UTF-8
    Expires: 0
    
  5. SteveL-MSFT commented on Oct 28, 2017

    @SteveL-MSFT
    Member

    My reading of the RFC particularly:

       Multiple message-header fields with the same field-name MAY be
       present in a message if and only if the entire field-value for that
       header field is defined as a comma-separated list [i.e., #(values)].
    

    Is that multiple headers with the same name MUST be comma separated. So having two Link: headers that aren't a comma separated list seems to not be conforming.

  6. removed this from the milestone on Oct 28, 2017
  7. markekraus commented on Oct 28, 2017

    @markekraus
    Contributor

    Steve Lee (@SteveL-MSFT) that RFC is so poorly worded, What it means is that the following two must be equvilent:

    X-Header: Value1
    X-Header: Value2
    
    X-Header: Value1, Value2
    

    That means that you cannot do

    X-Header: Value1, Value2
    X-Header: Value3
    

    instead, Value1, Value2 becomes a single value and not 2 separate values. This allows for multiple headers to support commas as a character where as a single header, commas are always a value separator with no escape character.

    In Full CLR they mash these all together for you. In CoreFX they treat multiple headers as separate elements in the header collection.

    The solution is to implement something like what is in #4494 in ParseLinkHeader(). Since I'm familiar with it, I'll take this one. but it should be High Priority.

  8. dddugan commented on Oct 29, 2017

    @dddugan
    Author

    Thanks, friends! Appreciate the quick response. Looking forward to testing the fix.

  9. markekraus commented on Oct 29, 2017

    @markekraus
    Contributor

    dddugan If you want to validate it now you can build from the MultipleRelLinkFix branch on my repo: https://github.com/markekraus/PowerShell/tree/MultipleRelLinkFix

    On windows you can use the MSI or zip produced by AppVeyor https://ci.appveyor.com/project/PowerShell/powershell/build/6.0.0-beta.9-6425/artifacts

  10. added this to the milestone on Oct 29, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions