Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoCompleteResource.IdStartsWith does not return packages that only have pre-release versions #7540

Closed
tintoy opened this issue Nov 21, 2018 · 8 comments
Assignees
Labels
Area:HttpCommunication Area:Protocol Client/Server protocol /code around it Priority:3 Issues under consideration. With enough upvotes, will be reconsidered to be added to the backlog. Type:Bug
Milestone

Comments

@tintoy
Copy link

tintoy commented Nov 21, 2018

Details about Problem

Hi.

As far as I can tell, AutoCompleteResource.IdStartsWith (v3 API) incorrectly passes the query parameter includePrerelease=true, but it should be passing prerelease=true (according to the API docs here).

NuGet product used: NuGet client library (specifically, NuGet.Protocol.Core.Types.AutoCompleteResource).

NuGet version: NuGet.Protocol (v4.8.0.0).

Below is a small console app that reproduces the issue and demonstrates that, if the URL uses the correct prerelease=true query parameter, correct results are returned.

Detailed repro steps so we can see the same problem

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using NuGet.Common;
using NuGet.Configuration;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;

namespace NuGetSuggestions
{
    static class Program
    {
        static async Task Main()
        {
            PackageSource packageSource = new PackageSource("https://api.nuget.org/v3/index.json");

            var providers = new List<Lazy<INuGetResourceProvider>>();
            providers.AddRange(
                Repository.Provider.GetCoreV3()
            );

            SourceRepository sourceRepository = new SourceRepository(packageSource, providers);
            AutoCompleteResource autoCompleteResource = await sourceRepository.GetResourceAsync<AutoCompleteResource>(CancellationToken.None);

            IEnumerable<string> packageIds = await autoCompleteResource.IdStartsWith("SixLabors", includePrerelease: true, log: NullLogger.Instance, CancellationToken.None);
            Console.WriteLine("Without fix, got {0} package Ids.", packageIds.Count()); // Shows 0 package Ids

            // Patch the HttpClient handler chain, inserting our fix.

            FieldInfo clientField = autoCompleteResource.GetType().GetField("_client", BindingFlags.Instance | BindingFlags.NonPublic);
            HttpSource httpSource = (HttpSource)clientField.GetValue(autoCompleteResource);

            FieldInfo httpClientField = httpSource.GetType().GetField("_httpClient", BindingFlags.Instance | BindingFlags.NonPublic);
            HttpClient httpClient = (HttpClient)httpClientField.GetValue(httpSource);

            FieldInfo handlerField = typeof(HttpMessageInvoker).GetField("_handler", BindingFlags.Instance | BindingFlags.NonPublic);
            HttpMessageHandler innerHandler = (HttpMessageHandler)handlerField.GetValue(httpClient);

            PrereleaseFixHandler prereleaseFixHandler = new PrereleaseFixHandler(innerHandler);
            httpClient = new HttpClient(prereleaseFixHandler);

            httpClientField.SetValue(httpSource, httpClient);

            packageIds = await autoCompleteResource.IdStartsWith("SixLabors", includePrerelease: true, log: NullLogger.Instance, CancellationToken.None);
            Console.WriteLine("With fix, got {0} package Ids.", packageIds.Count()); // Shows 7 package Ids
        }

        class PrereleaseFixHandler : DelegatingHandler
        {
            public PrereleaseFixHandler(HttpMessageHandler innerHandler)
                : base(innerHandler)
            {
            }

            protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken)
            {
                Console.WriteLine("Original request URI: {0}", requestMessage.RequestUri);

                // Fix incorrectly-named "includePrerelease" query parameter (should be "prerelease").
                requestMessage.RequestUri = new Uri(requestMessage.RequestUri.AbsoluteUri.Replace("&includePrerelease=", "&prerelease="));
                
                Console.WriteLine("Modified request URI: {0}", requestMessage.RequestUri);

                HttpResponseMessage responseMessage = await base.SendAsync(requestMessage, cancellationToken);

                return responseMessage;
            }
        }
    }
}
@nkolev92 nkolev92 added Type:Bug Area:HttpCommunication Area:Protocol Client/Server protocol /code around it labels Nov 21, 2018
@nkolev92
Copy link
Member

@ryuyu
I think you might have some context about the protocol.
Has this always been the case?
Was the client implementation always wrong?

@nkolev92 nkolev92 added this to the Backlog milestone Nov 21, 2018
@nkolev92 nkolev92 added Priority:3 Issues under consideration. With enough upvotes, will be reconsidered to be added to the backlog. help wanted Considered good issues for community contributions. labels Nov 21, 2018
@tintoy
Copy link
Author

tintoy commented Nov 22, 2018

I'm happy to submit a PR if it turns out this needs fixing, by the way :)

@nkolev92
Copy link
Member

I synced up with @joelverhagen
The v2 protocol used includePrerelease https://github.com/NuGet/NuGetGallery/blob/7bcc3973abd94302c3f61df992113dd3d31693e9/src/NuGetGallery/Controllers/ApiController.cs#L890, but the v3 uses only prerelease.

So only that needs changing.

@nkolev92 nkolev92 removed the help wanted Considered good issues for community contributions. label Nov 28, 2018
@joelverhagen
Copy link
Member

@tintoy
Copy link
Author

tintoy commented Nov 30, 2018

Should I open a PR for this, then? Happy to have a go.

@nkolev92
Copy link
Member

@tintoy
Thanks, I have assigned it to @heng-liu as she is familiarizing herself with the codebase.
I imagine she'll have a PR soon :)

@heng-liu
Copy link
Contributor

heng-liu commented Jan 25, 2019

Fixed. PR NuGet/NuGet.Client#2579

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area:HttpCommunication Area:Protocol Client/Server protocol /code around it Priority:3 Issues under consideration. With enough upvotes, will be reconsidered to be added to the backlog. Type:Bug
Projects
None yet
Development

No branches or pull requests

4 participants