From 71b69f35e4ce26d4ec7c81e5b83919c285130cd3 Mon Sep 17 00:00:00 2001 From: Daniel Mueller Date: Wed, 19 Aug 2015 15:24:00 +0200 Subject: [PATCH 1/2] UtilsSpecs: Unit test corrected - Use Path.Combine instead of +Path.DirectorySeparatorChar.ToString()+ - Fixes error if HOMEPATH=\ (Root directory, result was 'H:\\' or '//data' on Unix) --- tests/Paket.Tests/UtilsSpecs.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Paket.Tests/UtilsSpecs.fs b/tests/Paket.Tests/UtilsSpecs.fs index e1dbf17489..7a6395dfa3 100644 --- a/tests/Paket.Tests/UtilsSpecs.fs +++ b/tests/Paket.Tests/UtilsSpecs.fs @@ -15,7 +15,7 @@ let ``createRelativePath should handle spaces``() = let ``normalize path with home directory``() = "~/data" |> Utils.normalizeLocalPath - |> shouldEqual (AbsolutePath (GetHomeDirectory() + Path.DirectorySeparatorChar.ToString() + "data")) + |> shouldEqual (AbsolutePath (Path.Combine(GetHomeDirectory(), "data"))) [] let ``relative local path is returned as is``() = From fd394fc764cae747c6d9f3c410e6f5c2f2633802 Mon Sep 17 00:00:00 2001 From: Daniel Mueller Date: Wed, 19 Aug 2015 15:56:12 +0200 Subject: [PATCH 2/2] Proof of concept, Fixes compatibility issues mentioned in ticket #998 - WARNING: I am not a F# developer and this code could possibly break alternative NuGet server versions :-) - "It works on my machine" using the current master of Klondike (https://github.com/themotleyfool/Klondike) --- src/Paket.Core/NuGetV2.fs | 14 +++++++------- src/Paket.Core/NuGetV3.fs | 6 +++--- src/Paket.Core/RemoteDownload.fs | 8 ++++---- src/Paket.Core/Utils.fs | 15 +++++++++++++-- tests/Paket.Tests/NuGetOData/ODataSpecs.fs | 2 +- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/Paket.Core/NuGetV2.fs b/src/Paket.Core/NuGetV2.fs index 82a4059dcd..3e72854632 100644 --- a/src/Paket.Core/NuGetV2.fs +++ b/src/Paket.Core/NuGetV2.fs @@ -1,4 +1,4 @@ -/// Contains NuGet support. +/// Contains NuGet support. module Paket.NuGetV2 open System @@ -30,7 +30,7 @@ type NugetPackageCache = let rec private followODataLink getUrlContents url = async { - let! raw = getUrlContents url + let! raw = getUrlContents url acceptXml let doc = XmlDocument() doc.LoadXml raw let feed = @@ -83,8 +83,8 @@ let getAllVersionsFromNuGet2(auth,nugetURL,package) = async { let url = sprintf "%s/package-versions/%s?includePrerelease=true" nugetURL package verbosefn "getAllVersionsFromNuGet2 from url '%s'" url - let! raw = safeGetFromUrl(auth, url) - let getUrlContents url = getFromUrl(auth, url) + let! raw = safeGetFromUrl(auth, url, acceptJson) + let getUrlContents url acceptJson = getFromUrl(auth, url, acceptJson) match raw with | None -> let! result = getAllVersionsFromNugetOData(getUrlContents, nugetURL, package) return result @@ -215,7 +215,7 @@ let getDetailsFromNuGetViaODataFast auth nugetURL package (version:SemVerInfo) = async { try let url = sprintf "%s/Packages?$filter=Id eq '%s' and NormalizedVersion eq '%s'" nugetURL package (version.Normalize()) - let! raw = getFromUrl(auth,url) + let! raw = getFromUrl(auth,url,acceptXml) if verbose then tracefn "Response from %s:" url tracefn "" @@ -223,7 +223,7 @@ let getDetailsFromNuGetViaODataFast auth nugetURL package (version:SemVerInfo) = return parseODataDetails(nugetURL,package,version,raw) with _ -> let url = sprintf "%s/Packages?$filter=Id eq '%s' and Version eq '%s'" nugetURL package (version.ToString()) - let! raw = getFromUrl(auth,url) + let! raw = getFromUrl(auth,url,acceptXml) if verbose then tracefn "Response from %s:" url tracefn "" @@ -238,7 +238,7 @@ let getDetailsFromNuGetViaOData auth nugetURL package (version:SemVerInfo) = return! getDetailsFromNuGetViaODataFast auth nugetURL package version with _ -> let url = sprintf "%s/Packages(Id='%s',Version='%s')" nugetURL package (version.ToString()) - let! response = safeGetFromUrl(auth,url) + let! response = safeGetFromUrl(auth,url,acceptXml) let! raw = match response with diff --git a/src/Paket.Core/NuGetV3.fs b/src/Paket.Core/NuGetV3.fs index 4f5e98d5a5..1e57014c33 100644 --- a/src/Paket.Core/NuGetV3.fs +++ b/src/Paket.Core/NuGetV3.fs @@ -44,7 +44,7 @@ let getSearchAPI(auth,nugetUrl) = | None -> None | Some v3Path -> let serviceData = - safeGetFromUrl(auth,v3Path) + safeGetFromUrl(auth,v3Path,acceptJson) |> Async.RunSynchronously match serviceData with @@ -62,7 +62,7 @@ let internal findVersionsForPackage(auth, nugetURL, package, includingPrerelease async { match getSearchAPI(auth,nugetURL) with | Some url -> - let! response = safeGetFromUrl(auth,sprintf "%s?id=%s&take=%d%s" url package (max maxResults 100000) (if includingPrereleases then "&prerelease=true" else "")) // Nuget is showing old versions first + let! response = safeGetFromUrl(auth,sprintf "%s?id=%s&take=%d%s" url package (max maxResults 100000) (if includingPrereleases then "&prerelease=true" else ""), acceptXml) // Nuget is showing old versions first match response with | Some text -> let versions = @@ -94,7 +94,7 @@ let private getPackages(auth, nugetURL, packageNamePrefix, maxResults) = async { match getSearchAPI(auth,nugetURL) with | Some url -> let query = sprintf "%s?q=%s&take=%d" url packageNamePrefix maxResults - let! response = safeGetFromUrl(auth,query) + let! response = safeGetFromUrl(auth,query,acceptJson) match response with | Some text -> return extractPackages text | None -> return [||] diff --git a/src/Paket.Core/RemoteDownload.fs b/src/Paket.Core/RemoteDownload.fs index eec981f4b6..9854cabaeb 100644 --- a/src/Paket.Core/RemoteDownload.fs +++ b/src/Paket.Core/RemoteDownload.fs @@ -13,12 +13,12 @@ let getSHA1OfBranch origin owner project branch = match origin with | ModuleResolver.SingleSourceFileOrigin.GitHubLink -> let url = sprintf "https://api.github.com/repos/%s/%s/commits/%s" owner project branch - let! document = getFromUrl(None, url) + let! document = getFromUrl(None, url, null) let json = JObject.Parse(document) return json.["sha"].ToString() | ModuleResolver.SingleSourceFileOrigin.GistLink -> let url = sprintf "https://api.github.com/gists/%s/%s" project branch - let! document = getFromUrl(None, url) + let! document = getFromUrl(None, url, null) let json = JObject.Parse(document) let latest = json.["history"].First.["version"] return latest.ToString() @@ -44,7 +44,7 @@ let downloadDependenciesFile(rootPath,parserF,remoteFile:ModuleResolver.Resolved | ModuleResolver.GistLink -> rawGistFileUrl remoteFile.Owner remoteFile.Project dependenciesFileName | ModuleResolver.HttpLink url -> url.Replace(remoteFile.Name,Constants.DependenciesFileName) - let! result = safeGetFromUrl(None,url) + let! result = safeGetFromUrl(None,url,null) match result with | Some text when parserF text -> @@ -83,7 +83,7 @@ let downloadRemoteFiles(remoteFile:ResolvedSourceFile,destination) = async { let projectPath = fi.Directory.FullName let url = sprintf "https://api.github.com/gists/%s" remoteFile.Project - let! document = getFromUrl(None, url) + let! document = getFromUrl(None, url, null) let json = JObject.Parse(document) let files = json.["files"] |> Seq.map (fun i -> i.First.["filename"].ToString(), i.First.["raw_url"].ToString()) diff --git a/src/Paket.Core/Utils.fs b/src/Paket.Core/Utils.fs index fa63262d53..5e7977bb2d 100644 --- a/src/Paket.Core/Utils.fs +++ b/src/Paket.Core/Utils.fs @@ -12,6 +12,11 @@ open Paket.Logging open Chessie.ErrorHandling open Paket.Domain +let acceptXml = "application/atom+xml,application/xml" +let acceptJson = "application/atom+json,application/json" + +let notNullOrEmpty = not << System.String.IsNullOrEmpty + type Auth = { Username : string Password : string } @@ -168,10 +173,12 @@ let downloadFromUrl (auth:Auth option, url : string) (filePath: string) = } /// [omit] -let getFromUrl (auth:Auth option, url : string) = +let getFromUrl (auth:Auth option, url : string, contentType : string) = async { try use client = createWebClient(url,auth) + if notNullOrEmpty contentType then + client.Headers.Add(HttpRequestHeader.Accept, contentType) let s = client.DownloadStringTaskAsync(Uri(url)) |> Async.AwaitTask return! s with @@ -200,10 +207,14 @@ let getXmlFromUrl (auth:Auth option, url : string) = } /// [omit] -let safeGetFromUrl (auth:Auth option, url : string) = +let safeGetFromUrl (auth:Auth option, url : string, contentType : string) = async { try use client = createWebClient(url,auth) + + if notNullOrEmpty contentType then + client.Headers.Add(HttpRequestHeader.Accept, contentType) + let s = client.DownloadStringTaskAsync(Uri(url)) |> Async.AwaitTask let! raw = s return Some raw diff --git a/tests/Paket.Tests/NuGetOData/ODataSpecs.fs b/tests/Paket.Tests/NuGetOData/ODataSpecs.fs index 850346eee3..255b269199 100644 --- a/tests/Paket.Tests/NuGetOData/ODataSpecs.fs +++ b/tests/Paket.Tests/NuGetOData/ODataSpecs.fs @@ -116,7 +116,7 @@ let ``can calculate v3 path``() = [] let ``can read all versions from single page with multiple entries``() = - let getUrlContentsStub _ = async { return File.ReadAllText "NuGetOData/NUnit.xml" } + let getUrlContentsStub _ _ = async { return File.ReadAllText "NuGetOData/NUnit.xml" } let versions = getAllVersionsFromNugetOData(getUrlContentsStub, fakeUrl, "NUnit") |> Async.RunSynchronously