fsprojects / fsprojects/Paket

Call authentication provider for each unique host

Open
#3,653 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
F#
Stars
2.1k
Forks
528
Avg merge
1d 12m
Merged PRs (30d)
54

Description

Description

I have a NuGet V3 service where the index.json, metadata and package listing comes from one host and the content another - in this setup the package downloads are served by Azure CDN.

  • alice.domain.com = index.json
  • bob.somedomain.com = content (nupkgs)

The NuGet V3 service is secured. A custom credential provider provides a user/password for the authorization header. Paket handles this great.

The problem is the CDN does not like the Authorization header that is added by Paket when requesting content from the CDN as Paket is using the same credentials for the entire update/restore operation.

Expected behavior

As I am using two different hosts I would like my credential provider to be called a second time to get new credentials for the CDN host. For my exact use case the provider would actually return no credentials as I am using one-time generated tokens in the download URLs for the CDN.

Actual behavior

Download fails.

Performance:
 - Resolver: 3 seconds (1 runs)
    - Runtime: 173 milliseconds
    - Blocked (retrieving package details): 29 milliseconds (1 times)
    - Blocked (retrieving package versions): 3 seconds (1 times)
 - Average Download Time: 658 milliseconds
 - Number of downloads: 3
 - Average Request Time: 830 milliseconds
 - Number of Requests: 3
 - Runtime: 7 seconds
Paket failed with
-> Could not download abc 13.0.0-build5465 from https://cdn.blob.core.windows.net/packages/blah.
   StackTrace:
        at Paket.NuGet.download@870-70.Invoke(Exception _arg14)
        at Microsoft.FSharp.Control.AsyncBuilderImpl.callA@522.Invoke(AsyncParams`1 args)
     --- End of stack trace from previous location where exception was thrown ---
        at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
        at Microsoft.FSharp.Control.AsyncBuilderImpl.commit[a](AsyncImplResult`1 res)
        at Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronouslyInCurrentThread[a](CancellationToken token, FSharpAsync`1 computation)
        at Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronously[a](CancellationToken token, FSharpAsync`1 computation, FSharpOption`1 timeout)
        at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken)
        at Microsoft.FSharp.Collections.Internal.IEnumerator.map@74.DoMoveNext(b& curr)
        at Microsoft.FSharp.Collections.Internal.IEnumerator.MapEnumerator`1.System-Collections-IEnumerator-MoveNext()
        at Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.takeOuter@274[T,TResult](ConcatEnumerator`2 x, Unit unitVar0)
        at Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.takeOuter@274[T,TResult](ConcatEnumerator`2 x, Unit unitVar0)
        at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
        at Microsoft.FSharp.Collections.SeqModule.ToArray[T](IEnumerable`1 source)
        at Paket.InstallProcess.InstallIntoProjects[a](InstallerOptions options, Boolean forceTouch, DependenciesFile dependenciesFile, LockFile lockFile, FSharpList`1 projectsAndReferences, FSharpMap`2 updatedGroups)
        at Paket.UpdateProcess.SmartInstall(DependenciesFile dependenciesFile, UpdateMode updateMode, UpdaterOptions options)
        at <StartupCode$Paket-Core>.$PublicAPI.Update@321.Invoke(Unit unitVar0)
        at Paket.Utils.RunInLockedAccessMode[a](String lockedFolder, FSharpFunc`2 action)
        at Paket.Program.handleCommand@842-16.Invoke(ParseResults`1 results)
        at Paket.Program.processWithValidationEx$cont@42[a](Boolean silent, FSharpFunc`2 commandF, a result, Unit unitVar)
        at Paket.Program.processWithValidation[T](Boolean silent, FSharpFunc`2 validateF, FSharpFunc`2 commandF, ParseResults`1 result)
        at Paket.Program.handleCommand(Boolean silent, Command command)
        at Paket.Program.main()
-> HTTP status code was 400 - BadRequest
Known workarounds

None

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the Paket.NuGet.download entry point shown in the stack trace and inspect credential-provider handling during update and restore. Reproduce the two-host NuGet V3 scenario, then verify the provider is called separately for each unique host and the CDN request succeeds without reused credentials.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, fsharp
Domain
cli, devtools
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.