@@ -383,10 +383,74 @@ let getDetailsFromNuGetViaODataFast isVersionAssumed nugetSource (packageName:Pa
383383 | Choice2Of2 ex -> return raise ( exn( " error" , ex))
384384 }
385385
386+ // parse search results.
387+ let parseFindPackagesByIDODataListDetails ( url , nugetURL , packageName : PackageName , version : SemVerInfo , doc ) : ODataSearchResult =
388+ let feedNode =
389+ match doc |> getNode " feed" with
390+ | Some node -> node
391+ | None ->
392+ failwithf " Could not find 'entry' node for package %O %O " packageName version
393+
394+ let getVersion ( n : XmlNode ) =
395+ match n |> getNode " properties" |> optGetNode " Version" with
396+ | Some v -> Some( SemVer.Parse( v.InnerText) .Normalize())
397+ | None -> None
398+
399+ let v = version.Normalize()
400+
401+ match feedNode |> getNodes " entry" |> List.tryFind ( fun n -> getVersion n = Some v) with
402+ | None ->
403+ // When no entry node is found our search did not yield anything.
404+ EmptyResult
405+ | Some entry ->
406+ handleODataEntry nugetURL packageName version entry
407+ |> ODataSearchResult.Match
408+
409+ let rec parseFindPackagesByIDODataEntryDetails ( url , nugetSource : NuGetSource , packageName : PackageName , version : SemVerInfo ) = async {
410+ let! raw = getFromUrl( nugetSource.Authentication, url, acceptXml)
411+ if verbose then
412+ tracefn " Response from %s :" url
413+ tracefn " "
414+ tracefn " %s " raw
415+ let doc = getXmlDoc url raw
416+
417+ match parseFindPackagesByIDODataListDetails ( url, nugetSource.Url, packageName, version, doc) with
418+ | EmptyResult ->
419+ let linksToFollow =
420+ doc
421+ |> getNodes " link"
422+ |> List.filter ( fun node -> node |> getAttribute " rel" = Some " next" )
423+ |> List.choose ( fun a ->
424+ match getAttribute " href" a with
425+ | Some data ->
426+ let newUrl = Uri.UnescapeDataString data
427+ if newUrl <> url then Some newUrl else None
428+ | _ -> None)
429+ let result = ref None
430+
431+ for link in linksToFollow do
432+ if ! result = None then
433+ let! r = parseFindPackagesByIDODataEntryDetails ( link, nugetSource, packageName, version)
434+ match r with
435+ | EmptyResult -> ()
436+ | r -> result := Some r
437+
438+ match ! result with
439+ | Some r -> return r
440+ | _ -> return EmptyResult
441+
442+ | ODataSearchResult.Match entry -> return ODataSearchResult.Match entry
443+ }
386444
387445/// Gets package details from NuGet via OData
388- let getDetailsFromNuGetViaOData isVersionAssumed nugetSource ( packageName : PackageName ) ( version : SemVerInfo ) =
389- getDetailsFromNuGetViaODataFast isVersionAssumed nugetSource packageName version
446+ let getDetailsFromNuGetViaOData isVersionAssumed nugetSource ( packageName : PackageName ) ( version : SemVerInfo ) = async {
447+ try
448+ return ! getDetailsFromNuGetViaODataFast isVersionAssumed nugetSource packageName version
449+ with
450+ | _ ->
451+ let url = sprintf " %s /FindPackagesById()?semVerLevel=2.0.0&id='%O '" nugetSource.Url packageName
452+ return ! parseFindPackagesByIDODataEntryDetails ( url, nugetSource, packageName, version)
453+ }
390454
391455let getDetailsFromNuGet force isVersionAssumed nugetSource packageName version =
392456 getDetailsFromCacheOr
0 commit comments