public IEnumerable <JToken> GetListAvailableDataStart(InterceptCallContext context, JObject index)
        {
            string skipTo = null;

            if (context.Args.SkipToken != null)
            {
                var skipToken = ParseSkipToken(context.Args.SkipToken);
                skipTo = skipToken.Item1;
            }
            else if (context.Args.FilterStartsWithId != null)
            {
                skipTo = context.Args.FilterStartsWithId;
            }
            if (context.Args.PartialId != null) // intellisense
            {
                skipTo = context.Args.PartialId;
            }

            var segments = GetListAvailableSegmentsIncludingAndAfter(context, index, skipTo);

            foreach (var segUrl in segments)
            {
                var dataTask = FetchJson(context, new Uri(segUrl));
                dataTask.Wait();
                var data = dataTask.Result;

                var orderedData = data["entry"].OrderBy(e => e["id"].ToString(), StringComparer.InvariantCultureIgnoreCase)
                                  .ThenBy(e => new NuGetVersion(e["version"].ToString()), VersionComparer.VersionRelease);

                foreach (var entry in orderedData)
                {
                    yield return(entry);
                }
            }
        }
        public async Task GetListOfPackageVersions(InterceptCallContext context, string id)
        {
            V3InteropTraceSources.Channel.Verbose("GetListOfPackageVersions", id);

            JObject resolverBlob = await FetchJson(context, MakeResolverAddress(id));

            JArray array = new JArray();

            // the package may not exist, in that case return an empty array
            if (resolverBlob != null)
            {
                List <NuGetVersion> versions = new List <NuGetVersion>();
                foreach (JToken package in resolverBlob["packages"])
                {
                    NuGetVersion version = NuGetVersion.Parse(package["version"].ToString());

                    // all versions are returned, filter to only stable if needed
                    if (context.Args.IncludePrerelease || !version.IsPrerelease)
                    {
                        versions.Add(version);
                    }
                }

                versions.Sort();

                foreach (NuGetVersion version in versions)
                {
                    array.Add(version.ToString());
                }
            }

            await context.WriteResponse(array);
        }
        public async Task GetListOfPackages(InterceptCallContext context)
        {
            V3InteropTraceSources.Channel.Verbose("GetListOfPackages", String.Empty);

            var index = await FetchJson(context, context.Args.IncludePrerelease?new Uri(_listAvailableLatestPrereleaseIndex) : new Uri(_listAvailableLatestStableIndex));

            var data = GetListAvailableDataStart(context, index);

            // apply startswith if needed
            if (context.Args.PartialId != null)
            {
                data = data.Where(e => e["id"].ToString().StartsWith(context.Args.PartialId, StringComparison.OrdinalIgnoreCase));

                data = data.TakeWhile(e => e["id"].ToString().StartsWith(context.Args.PartialId, StringComparison.OrdinalIgnoreCase));
            }

            // take only 30
            var ids = data.Take(30).Select(p => p["id"].ToString()).ToList();

            ids.Sort(StringComparer.InvariantCultureIgnoreCase);

            JArray array = new JArray();

            foreach (var id in ids)
            {
                array.Add(id);
            }

            await context.WriteResponse(array);
        }
        public async Task Metadata(InterceptCallContext context, string feed = null)
        {
            V3InteropTraceSources.Channel.Verbose("metadata", feed ?? String.Empty);

            Stream   stream = GetResourceStream(feed == null ? "xml.Metadata.xml" : "xml.FeedMetadata.xml");
            XElement xml    = XElement.Load(stream);
            await context.WriteResponse(xml);
        }
예제 #5
0
        private async Task Feed_Metadata(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();
            string feed = ExtractFeed(context.RequestUri.AbsolutePath);

            V3InteropTraceSources.Dispatcher.Verbose("metadata_feed", "Feed: {0}", feed);
            await _channel.Metadata(context, feed);
        }
예제 #6
0
        private async Task Feed_Search(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();
            string feed = ExtractFeed(context.RequestUri.AbsolutePath);

            V3InteropTraceSources.Dispatcher.Verbose("search_feed", "Feed: {0}", feed);
            await SearchImpl(context, feed);
        }
예제 #7
0
        private async Task Feed_FindPackagesById(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();
            string feed = ExtractFeed(context.RequestUri.AbsolutePath);

            V3InteropTraceSources.Dispatcher.Verbose("findpackagesbyid_feed", "Feed: {0}", feed);
            await _channel.GetAllPackageVersions(context, context.Args.Id);
        }
예제 #8
0
        private async Task SearchImpl(InterceptCallContext context, string feed = null)
        {
            int skip = context.Args.Skip ?? 0;
            int take = context.Args.Top ?? 30;

            string sortBy = string.Empty;

            await _channel.Search(context, context.Args.SearchTerm, context.Args.IsLatestVersion, context.Args.TargetFramework, context.Args.IncludePrerelease, skip, take, feed, sortBy);
        }
예제 #9
0
        private async Task PackageVersions(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            string path = context.RequestUri.AbsolutePath;
            string id   = path.Substring(path.LastIndexOf("/") + 1);

            await _channel.GetListOfPackageVersions(context, id);
        }
예제 #10
0
        private async Task Packages(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            string path  = Uri.UnescapeDataString(context.RequestUri.AbsolutePath);
            string query = context.RequestUri.Query;

            await GetPackage(context, path, query);
        }
        public async Task ListAvailable(InterceptCallContext context)
        {
            string indexUrl = _listAvailableLatestStableIndex;

            if (!context.Args.IsLatestVersion)
            {
                indexUrl = _listAvailableAllIndex;
            }
            else if (context.Args.IncludePrerelease)
            {
                indexUrl = _listAvailableLatestPrereleaseIndex;
            }

            var index = await FetchJson(context, new Uri(indexUrl));

            var data = GetListAvailableData(context, index);

            // all versions with no pre
            if (!context.Args.IsLatestVersion && !context.Args.IncludePrerelease)
            {
                data = data.Where(p => (new NuGetVersion(p["version"].ToString())).IsPrerelease == false);
            }

            string nextUrl = null;

            // Convert to a list after calling Take to avoid enumerating the list multiple times.

            if (context.Args.Top.HasValue && context.Args.Top.Value > 0)
            {
                data = data.Take(context.Args.Top.Value).ToList();
            }
            else
            {
                data = data.Take(30).ToList();

                if (data.Count() >= 30)
                {
                    var last = data.LastOrDefault();

                    if (last != null)
                    {
                        string argsWithoutSkipToken = String.Join("&", context.Args.Arguments.Where(a => a.Key.ToLowerInvariant() != "$skiptoken")
                                                                  .Select(a => String.Format(CultureInfo.InvariantCulture, "{0}={1}", a.Key, a.Value)));

                        nextUrl = String.Format(CultureInfo.InvariantCulture, "{0}?{1}&$skiptoken='{2}','{2}','{3}'",
                                                context.RequestUri.AbsoluteUri.Split('?')[0],
                                                argsWithoutSkipToken,
                                                last["id"],
                                                last["version"]);
                    }
                }
            }

            XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "Packages", data, data.Select(e => e["id"].ToString()).ToArray(), nextUrl);
            await context.WriteResponse(feed);
        }
        public async Task SearchCount(InterceptCallContext context, string searchTerm, bool isLatestVersion, string targetFramework, bool includePrerelease, int skip, int take, string feedName, string sortBy)
        {
            V3InteropTraceSources.Channel.Verbose("searchcount", searchTerm);

            JObject obj = await FetchJson(context, MakeSearchAddress(searchTerm, isLatestVersion, targetFramework, includePrerelease, skip, take, feedName, sortBy));

            string count = obj != null ? count = obj["totalHits"].ToString() : "0";

            await context.WriteResponse(count);
        }
        public async Task Search(InterceptCallContext context, string searchTerm, bool isLatestVersion, string targetFramework, bool includePrerelease, int skip, int take, string feedName, string sortBy)
        {
            V3InteropTraceSources.Channel.Verbose("search", "{0} ({1},{2})", searchTerm, skip, take);

            JObject obj = await FetchJson(context, MakeSearchAddress(searchTerm, isLatestVersion, targetFramework, includePrerelease, skip, take, feedName, sortBy));

            IEnumerable <JToken> data = (obj != null) ? data = obj["data"] : Enumerable.Empty <JToken>();

            XElement feed = InterceptFormatting.MakeFeedFromSearch(_source, _passThroughAddress, "Packages", data, "");
            await context.WriteResponse(feed);
        }
        public IEnumerable <JToken> GetListAvailableData(InterceptCallContext context, JObject index)
        {
            var data = GetListAvailableFastForwardSkipToken(context, index);

            // apply startswith if needed
            if (context.Args.FilterStartsWithId != null)
            {
                data = data.Where(e => e["id"].ToString().StartsWith(context.Args.FilterStartsWithId, StringComparison.OrdinalIgnoreCase));

                data = data.TakeWhile(e => e["id"].ToString().StartsWith(context.Args.FilterStartsWithId, StringComparison.OrdinalIgnoreCase));
            }

            return(data);
        }
        public async Task <List <JObject> > GetUpdatesCore(InterceptCallContext context, string[] packageIds, string[] versions, string[] versionConstraints, string[] targetFrameworks, bool includePrerelease, bool includeAllVersions)
        {
            List <JObject> packages = new List <JObject>();

            for (int i = 0; i < packageIds.Length; i++)
            {
                VersionRange range = null;

                if (i < versionConstraints.Length && !String.IsNullOrEmpty(versionConstraints[i]))
                {
                    VersionRange.TryParse(versionConstraints[i], out range);
                }

                JObject resolverBlob = await FetchJson(context, MakeResolverAddress(packageIds[i]));

                // TODO: handle this error
                if (resolverBlob != null)
                {
                    // this can be null if all packages are prerelease
                    JObject latest = ExtractLatestVersion(resolverBlob, includePrerelease, range) as JObject;
                    if (latest != null)
                    {
                        // add the id if it isn't there
                        if (latest["id"] == null)
                        {
                            latest.Add("id", JToken.Parse("'" + packageIds[i] + "'"));
                        }

                        if (i < versions.Length && !String.IsNullOrEmpty(versions[i]))
                        {
                            NuGetVersion latestVersion  = NuGetVersion.Parse(latest["version"].ToString());
                            NuGetVersion currentVersion = NuGetVersion.Parse(versions[i]);

                            // only add the package if it is not the latest version
                            if (VersionComparer.VersionRelease.Compare(latestVersion, currentVersion) > 0)
                            {
                                packages.Add(latest);
                            }
                        }
                        else
                        {
                            packages.Add(latest);
                        }
                    }
                }
            }

            return(packages);
        }
예제 #16
0
        private async Task Feed_Packages(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();
            string feed = ExtractFeed(context.RequestUri.AbsolutePath);

            V3InteropTraceSources.Dispatcher.Verbose("packages_feed", "Feed: {0}", feed);

            string path = Uri.UnescapeDataString(context.RequestUri.AbsolutePath);

            path = path.Substring(path.IndexOf(feed) + feed.Length + 1);

            string query = context.RequestUri.Query;

            await GetPackage(context, path, query, feed);
        }
예제 #17
0
        private async Task GetUpdates(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            IDictionary <string, string> arguments = context.Args.Arguments;

            string[] packageIds         = Uri.UnescapeDataString(arguments["packageIds"]).Trim('\'').Split('|');
            string[] versions           = Uri.UnescapeDataString(arguments["versions"]).Trim('\'').Split('|');
            string[] versionConstraints = Uri.UnescapeDataString(arguments["versionConstraints"]).Trim('\'').Split('|');
            string[] targetFrameworks   = Uri.UnescapeDataString(arguments["targetFrameworks"]).Trim('\'').Split('|');
            bool     includeAllVersions = false;

            bool.TryParse(arguments["includeAllVersions"], out includeAllVersions);

            await _channel.GetUpdates(context, packageIds, versions, versionConstraints, targetFrameworks, context.Args.IncludePrerelease, includeAllVersions, context.Args.Count);
        }
        public async Task GetUpdates(InterceptCallContext context, string[] packageIds, string[] versions, string[] versionConstraints, string[] targetFrameworks, bool includePrerelease, bool includeAllVersions, bool count = false)
        {
            V3InteropTraceSources.Channel.Info(count ? "getupdates" : "getupdatescount", String.Join(", ", packageIds));

            var packages = await GetUpdatesCore(context, packageIds, versions, versionConstraints, targetFrameworks, includePrerelease, includeAllVersions);

            if (count)
            {
                await context.WriteResponse(packages.Count);
            }
            else
            {
                XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "GetUpdates", packages, packages.Select(p => p["id"].ToString()).ToArray());
                await context.WriteResponse(feed);
            }
        }
        public async Task GetPackage(InterceptCallContext context, string id, string version, string feedName)
        {
            V3InteropTraceSources.Channel.Verbose("getpackage", "{0} {1}", id, version);

            var desiredPackage = await GetPackageCore(context, id, version);

            if (desiredPackage == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "unable to find version {0} of package {1}", version, id));
            }

            XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "Packages", new List <JToken> {
                desiredPackage
            }, id);
            await context.WriteResponse(feed);
        }
예제 #20
0
        private async Task DownloadPackage(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            var urlParts = new List <string>(context.RequestUri.AbsoluteUri.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries));

            urlParts.Reverse();

            if (urlParts.Count > 3 && StringComparer.OrdinalIgnoreCase.Equals("package", urlParts[2]))
            {
                await _channel.DownloadPackage(context, urlParts[1], urlParts[0]);
            }
            else
            {
                throw new ShimException("Invalid download url: " + context.RequestUri.ToString());
            }
        }
        public IEnumerable <JToken> GetListAvailableFastForwardSkipToken(InterceptCallContext context, JObject index)
        {
            var data = GetListAvailableDataStart(context, index);

            if (context.Args.SkipToken != null)
            {
                var skipToken    = ParseSkipToken(context.Args.SkipToken);
                var skipTokenId  = skipToken.Item1;
                var skipTokenVer = new NuGetVersion(skipToken.Item2);

                data = data.Where(e => skipTokenId == null || StringComparer.InvariantCultureIgnoreCase.Compare(e["id"].ToString(), skipTokenId) > 0 ||
                                  (StringComparer.InvariantCultureIgnoreCase.Equals(e["id"].ToString(), skipTokenId) &&
                                   (skipTokenVer == null || VersionComparer.VersionRelease.Compare(new NuGetVersion(e["version"].ToString()), skipTokenVer) > 0)));
            }

            return(data);
        }
예제 #22
0
        private async Task FindPackagesById(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            if (context.Args.Id == null)
            {
                throw new ShimException("unable to find id in query string");
            }

            if (context.Args.IsLatestVersion)
            {
                await _channel.GetLatestVersionPackage(context, context.Args.Id, context.Args.IncludePrerelease);
            }
            else
            {
                await _channel.GetAllPackageVersions(context, context.Args.Id);
            }
        }
        public async Task GetAllPackageVersions(InterceptCallContext context, string id)
        {
            V3InteropTraceSources.Channel.Verbose("getallpackageversions", id);

            var ids = id.Split(new string[] { " or " }, StringSplitOptions.RemoveEmptyEntries);

            List <JToken> packages = new List <JToken>();

            foreach (var s in ids)
            {
                string curId = s.Trim('\'');

                if (curId.StartsWith("tolower(id) eq '"))
                {
                    curId = curId.Split('\'')[1];
                }

                // TODO: run in parallel
                JObject resolverBlob = await FetchJson(context, MakeResolverAddress(curId));

                if (resolverBlob == null)
                {
                    throw new InvalidOperationException(string.Format("package {0} not found", curId));
                }

                foreach (var p in resolverBlob["packages"])
                {
                    NuGetVersion version = NuGetVersion.Parse(p["version"].ToString());

                    // all versions are returned, filter to only stable if needed
                    if (context.Args.IncludePrerelease || !version.IsPrerelease)
                    {
                        p["id"] = resolverBlob["id"];

                        packages.Add(p);
                    }
                }
            }

            var data = packages.OrderBy(p => p["id"].ToString()).ThenByDescending(p => NuGetVersion.Parse(p["version"].ToString()), VersionComparer.VersionRelease);

            XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "Packages", data, data.Select(p => p["id"].ToString()).ToArray());
            await context.WriteResponse(feed);
        }
예제 #24
0
        public async Task Root(InterceptCallContext context, string feedName = null)
        {
            V3InteropTraceSources.Channel.Verbose("root", feedName ?? String.Empty);

            if (feedName == null)
            {
                Stream stream = GetResourceStream("xml.Root.xml");
                XElement xml = XElement.Load(stream);
                await context.WriteResponse(xml);
            }
            else
            {
                Stream stream = GetResourceStream("xml.FeedRoot.xml");
                string s = (new StreamReader(stream)).ReadToEnd();
                string t = string.Format(s, feedName);
                XElement xml = XElement.Load(new StringReader(t), LoadOptions.SetBaseUri);
                await context.WriteResponse(xml);
            }
        }
        public async Task Root(InterceptCallContext context, string feedName = null)
        {
            V3InteropTraceSources.Channel.Verbose("root", feedName ?? String.Empty);

            if (feedName == null)
            {
                Stream   stream = GetResourceStream("xml.Root.xml");
                XElement xml    = XElement.Load(stream);
                await context.WriteResponse(xml);
            }
            else
            {
                Stream   stream = GetResourceStream("xml.FeedRoot.xml");
                string   s      = (new StreamReader(stream)).ReadToEnd();
                string   t      = string.Format(s, feedName);
                XElement xml    = XElement.Load(new StringReader(t), LoadOptions.SetBaseUri);
                await context.WriteResponse(xml);
            }
        }
        private async Task <JObject> FetchJson(InterceptCallContext context, Uri address)
        {
            JObject fromCache = null;

            if (_cache.TryGet(address, out fromCache))
            {
                V3InteropTraceSources.Channel.Verbose("cachehit", "Cache HIT : {0}", address);
                return(fromCache);
            }

            V3InteropTraceSources.Channel.Verbose("cachemiss", "Cache MISS: {0}", address);

            Stopwatch timer = new Stopwatch();

            timer.Start();

            System.Net.Http.HttpClient client   = new System.Net.Http.HttpClient();
            HttpResponseMessage        response = await client.GetAsync(address);

            timer.Stop();

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                V3InteropTraceSources.Channel.Verbose("jsonresp", "Retrieved {0} in {1}ms.", address, timer.ElapsedMilliseconds);
                string json = await response.Content.ReadAsStringAsync();

                JObject obj = JObject.Parse(json);

                _cache.AddOrUpdate(address, obj);

                return(obj);
            }
            else
            {
                // expected in some cases
                V3InteropTraceSources.Channel.Verbose("jsonresp", "{2} error retrieving {0} in {1}ms.", address, timer.ElapsedMilliseconds, (int)response.StatusCode);
                return(null);
            }
        }
        private async Task <JToken> GetPackageCore(InterceptCallContext context, string id, string version)
        {
            JToken  desiredPackage = null;
            JObject resolverBlob   = await FetchJson(context, MakeResolverAddress(id));


            if (resolverBlob != null)
            {
                NuGetVersion desiredVersion = NuGetVersion.Parse(version);

                foreach (JToken package in resolverBlob["packages"])
                {
                    NuGetVersion currentVersion = NuGetVersion.Parse(package["version"].ToString());
                    if (currentVersion == desiredVersion)
                    {
                        desiredPackage = package;
                        break;
                    }
                }
            }

            return(desiredPackage);
        }
        public async Task GetLatestVersionPackage(InterceptCallContext context, string id, bool includePrerelease)
        {
            V3InteropTraceSources.Channel.Verbose("getlatestversionpackage", "{0} Pre={1}", id, includePrerelease);

            JObject resolverBlob = await FetchJson(context, MakeResolverAddress(id));

            if (resolverBlob == null)
            {
                throw new InvalidOperationException(string.Format("package {0} not found", id));
            }

            JToken latest = ExtractLatestVersion(resolverBlob, includePrerelease);

            if (latest == null)
            {
                throw new InvalidOperationException(string.Format("package {0} not found", id));
            }

            XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "Packages", new List <JToken> {
                latest
            }, id);
            await context.WriteResponse(feed);
        }
예제 #29
0
        private async Task GetPackage(InterceptCallContext context, string path, string query, string feed = null)
        {
            if (path.EndsWith("Packages()"))
            {
                if (!String.IsNullOrEmpty(context.Args.FilterId))
                {
                    await _channel.GetAllPackageVersions(context, context.Args.FilterId.ToLowerInvariant());
                }
                else
                {
                    await _channel.ListAvailable(context);
                }
            }
            else
            {
                string args = path.Substring(path.LastIndexOf('(')).Trim('(', ')');

                string id      = null;
                string version = null;

                string[] aps = args.Split(',');
                foreach (var ap in aps)
                {
                    string[] a = ap.Split('=');
                    if (a[0].Trim('\'') == "Id")
                    {
                        id = a[1].Trim('\'');
                    }
                    else if (a[0].Trim('\'') == "Version")
                    {
                        version = a[1].Trim('\'');
                    }
                }

                await _channel.GetPackage(context, id, version, feed);
            }
        }
        public static Queue <string> GetListAvailableSegmentsIncludingAndAfter(InterceptCallContext context, JObject index, string startsWith = null)
        {
            var segs = index["entry"].ToArray();

            Queue <string> needed = new Queue <string>();

            for (int i = 0; i < segs.Length; i++)
            {
                // once we add the first one, take everythign after
                if (needed.Count > 0 || String.IsNullOrEmpty(startsWith))
                {
                    needed.Enqueue(segs[i]["url"].ToString());
                }
                else
                {
                    var seg = segs[i];

                    string lowest = seg["lowest"].ToString();

                    // advance until we go too far
                    if (needed.Count < 1 && StringComparer.InvariantCultureIgnoreCase.Compare(lowest, startsWith) >= 0)
                    {
                        if (i > 0)
                        {
                            // get the previous one
                            needed.Enqueue(segs[i - 1]["url"].ToString());
                        }

                        // add the current one
                        needed.Enqueue(segs[i]["url"].ToString());
                    }
                }
            }

            return(needed);
        }
        public async Task DownloadPackage(InterceptCallContext context, string id, string version)
        {
            JToken package = await GetPackageCore(context, id, version);

            if (package == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "unable to find version {0} of package {1}", version, id));
            }

            string address = package["nupkgUrl"].ToString();


            V3InteropTraceSources.Channel.Info("downloadingpackage", "Downloading {0}", address);

            Stopwatch timer = new Stopwatch();

            timer.Start();

            System.Net.Http.HttpClient client   = new System.Net.Http.HttpClient();
            HttpResponseMessage        response = await client.GetAsync(address);

            byte[] data = await response.Content.ReadAsByteArrayAsync();

            timer.Stop();

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                V3InteropTraceSources.Channel.Info("downloadedpackage", "Downloaded {0} in {1}ms", address, timer.ElapsedMilliseconds);
            }
            else
            {
                V3InteropTraceSources.Channel.Error("downloadedpackage_error", "Error downloading {0} in {1}ms (status {2})", address, timer.ElapsedMilliseconds, response.StatusCode);
            }

            await context.WriteResponse(data, "application/zip");
        }
예제 #32
0
        public async Task SearchCount(InterceptCallContext context, string searchTerm, bool isLatestVersion, string targetFramework, bool includePrerelease, int skip, int take, string feedName, string sortBy)
        {
            V3InteropTraceSources.Channel.Verbose("searchcount", searchTerm);
            
            JObject obj = await FetchJson(context, MakeSearchAddress(searchTerm, isLatestVersion, targetFramework, includePrerelease, skip, take, feedName, sortBy));

            string count = obj != null ? count = obj["totalHits"].ToString() : "0";

            await context.WriteResponse(count);
        }
예제 #33
0
        private async Task<JObject> FetchJson(InterceptCallContext context, Uri address)
        {
            JObject fromCache = null;
            if (_cache.TryGet(address, out fromCache))
            {
                V3InteropTraceSources.Channel.Verbose("cachehit", "Cache HIT : {0}", address);
                return fromCache;
            }

            V3InteropTraceSources.Channel.Verbose("cachemiss", "Cache MISS: {0}", address);
            
            Stopwatch timer = new Stopwatch();
            timer.Start();

            System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
            HttpResponseMessage response = await client.GetAsync(address);

            timer.Stop();

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                V3InteropTraceSources.Channel.Verbose("jsonresp", "Retrieved {0} in {1}ms.", address, timer.ElapsedMilliseconds);
                string json = await response.Content.ReadAsStringAsync();
                JObject obj = JObject.Parse(json);

                _cache.AddOrUpdate(address, obj);

                return obj;
            }
            else
            {
                // expected in some cases
                V3InteropTraceSources.Channel.Verbose("jsonresp", "{2} error retrieving {0} in {1}ms.", address, timer.ElapsedMilliseconds, (int)response.StatusCode);
                return null;
            }
        }
예제 #34
0
        public async Task GetUpdates(InterceptCallContext context, string[] packageIds, string[] versions, string[] versionConstraints, string[] targetFrameworks, bool includePrerelease, bool includeAllVersions, bool count = false)
        {
            V3InteropTraceSources.Channel.Info(count ? "getupdates" : "getupdatescount", String.Join(", ", packageIds));

            var packages = await GetUpdatesCore(context, packageIds, versions, versionConstraints, targetFrameworks, includePrerelease, includeAllVersions);

            if (count)
            {
                await context.WriteResponse(packages.Count);
            }
            else
            {
                XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "GetUpdates", packages, packages.Select(p => p["id"].ToString()).ToArray());
                await context.WriteResponse(feed);
            }
        }
예제 #35
0
        public IEnumerable<JToken> GetListAvailableDataStart(InterceptCallContext context, JObject index)
        {
            string skipTo = null;

            if (context.Args.SkipToken != null)
            {
                var skipToken = ParseSkipToken(context.Args.SkipToken);
                skipTo = skipToken.Item1;
            }
            else if (context.Args.FilterStartsWithId != null)
            {
                skipTo = context.Args.FilterStartsWithId;
            }
            if (context.Args.PartialId != null) // intellisense
            {
                skipTo = context.Args.PartialId;
            }

            var segments = GetListAvailableSegmentsIncludingAndAfter(context, index, skipTo);

            foreach(var segUrl in segments)
            {
                var dataTask = FetchJson(context, new Uri(segUrl));
                dataTask.Wait();
                var data = dataTask.Result;

                var orderedData = data["entry"].OrderBy(e => e["id"].ToString(), StringComparer.InvariantCultureIgnoreCase)
                    .ThenBy(e => new NuGetVersion(e["version"].ToString()), VersionComparer.VersionRelease);

                foreach (var entry in orderedData)
                {
                    yield return entry;
                }
            }
        }
예제 #36
0
        private async Task FindPackagesById(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            if (context.Args.Id == null)
            {
                throw new ShimException("unable to find id in query string");
            }

            if (context.Args.IsLatestVersion)
            {
                await _channel.GetLatestVersionPackage(context, context.Args.Id, context.Args.IncludePrerelease);
            }
            else
            {
                await _channel.GetAllPackageVersions(context, context.Args.Id);
            }
        }
예제 #37
0
        private async Task<JToken> GetPackageCore(InterceptCallContext context, string id, string version)
        {
            JToken desiredPackage = null;
            JObject resolverBlob = await FetchJson(context, MakeResolverAddress(id));


            if (resolverBlob != null)
            {
                NuGetVersion desiredVersion = NuGetVersion.Parse(version);

                foreach (JToken package in resolverBlob["packages"])
                {
                    NuGetVersion currentVersion = NuGetVersion.Parse(package["version"].ToString());
                    if (currentVersion == desiredVersion)
                    {
                        desiredPackage = package;
                        break;
                    }
                }
            }

            return desiredPackage;
        }
예제 #38
0
        public async Task GetAllPackageVersions(InterceptCallContext context, string id)
        {
            V3InteropTraceSources.Channel.Verbose("getallpackageversions", id);

            var ids = id.Split(new string[] { " or " }, StringSplitOptions.RemoveEmptyEntries);

            List<JToken> packages = new List<JToken>();

            foreach (var s in ids)
            {
                string curId = s.Trim('\'');

                if (curId.StartsWith("tolower(id) eq '"))
                {
                    curId = curId.Split('\'')[1];
                }

                // TODO: run in parallel
                JObject resolverBlob = await FetchJson(context, MakeResolverAddress(curId));

                if (resolverBlob == null)
                {
                    throw new InvalidOperationException(string.Format("package {0} not found", curId));
                }

                foreach (var p in resolverBlob["packages"])
                {
                    NuGetVersion version = NuGetVersion.Parse(p["version"].ToString());

                    // all versions are returned, filter to only stable if needed
                    if (context.Args.IncludePrerelease || !version.IsPrerelease)
                    {
                        p["id"] = resolverBlob["id"];

                        packages.Add(p);
                    }
                }
            }

            var data = packages.OrderBy(p => p["id"].ToString()).ThenByDescending(p => NuGetVersion.Parse(p["version"].ToString()), VersionComparer.VersionRelease);

            XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "Packages", data, data.Select(p => p["id"].ToString()).ToArray());
            await context.WriteResponse(feed);
        }
예제 #39
0
        private async Task GetPackage(InterceptCallContext context, string path, string query, string feed = null)
        {
            if (path.EndsWith("Packages()"))
            {
                if(!String.IsNullOrEmpty(context.Args.FilterId))
                {
                    await _channel.GetAllPackageVersions(context, context.Args.FilterId.ToLowerInvariant());
                }
                else
                {
                    await _channel.ListAvailable(context);
                }
            }
            else
            {
                string args = path.Substring(path.LastIndexOf('(')).Trim('(', ')');

                string id = null;
                string version = null;

                string[] aps = args.Split(',');
                foreach (var ap in aps)
                {
                    string[] a = ap.Split('=');
                    if (a[0].Trim('\'') == "Id")
                    {
                        id = a[1].Trim('\'');
                    }
                    else if (a[0].Trim('\'') == "Version")
                    {
                        version = a[1].Trim('\'');
                    }
                }

                await _channel.GetPackage(context, id, version, feed);
            }
        }
예제 #40
0
 private async Task Feed_Metadata(InterceptCallContext context)
 {
     V3InteropTraceSources.Dispatcher.EnterMethod();
     string feed = ExtractFeed(context.RequestUri.AbsolutePath);
     V3InteropTraceSources.Dispatcher.Verbose("metadata_feed", "Feed: {0}", feed);
     await _channel.Metadata(context, feed);
 }
예제 #41
0
 private async Task Feed_Search(InterceptCallContext context)
 {
     V3InteropTraceSources.Dispatcher.EnterMethod();
     string feed = ExtractFeed(context.RequestUri.AbsolutePath);
     V3InteropTraceSources.Dispatcher.Verbose("search_feed", "Feed: {0}", feed);
     await SearchImpl(context, feed);
 }
예제 #42
0
 private async Task Feed_FindPackagesById(InterceptCallContext context)
 {
     V3InteropTraceSources.Dispatcher.EnterMethod();
     string feed = ExtractFeed(context.RequestUri.AbsolutePath);
     V3InteropTraceSources.Dispatcher.Verbose("findpackagesbyid_feed", "Feed: {0}", feed);
     await _channel.GetAllPackageVersions(context, context.Args.Id);
 }
예제 #43
0
        private async Task Feed_Packages(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();
            string feed = ExtractFeed(context.RequestUri.AbsolutePath);
            V3InteropTraceSources.Dispatcher.Verbose("packages_feed", "Feed: {0}", feed);

            string path = Uri.UnescapeDataString(context.RequestUri.AbsolutePath);
            path = path.Substring(path.IndexOf(feed) + feed.Length + 1);

            string query = context.RequestUri.Query;

            await GetPackage(context, path, query, feed);
        }
예제 #44
0
        public async Task Search(InterceptCallContext context, string searchTerm, bool isLatestVersion, string targetFramework, bool includePrerelease, int skip, int take, string feedName, string sortBy)
        {
            V3InteropTraceSources.Channel.Verbose("search", "{0} ({1},{2})", searchTerm, skip, take);
            
            JObject obj = await FetchJson(context, MakeSearchAddress(searchTerm, isLatestVersion, targetFramework, includePrerelease, skip, take, feedName, sortBy));

            IEnumerable<JToken> data = (obj != null) ? data = obj["data"] : Enumerable.Empty<JToken>();

            XElement feed = InterceptFormatting.MakeFeedFromSearch(_source, _passThroughAddress, "Packages", data, "");
            await context.WriteResponse(feed);
        }
예제 #45
0
        public async Task GetPackage(InterceptCallContext context, string id, string version, string feedName)
        {
            V3InteropTraceSources.Channel.Verbose("getpackage", "{0} {1}", id, version);
            
            var desiredPackage = await GetPackageCore(context, id, version);

            if (desiredPackage == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "unable to find version {0} of package {1}", version, id));
            }

            XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "Packages", new List<JToken> { desiredPackage }, id);
            await context.WriteResponse(feed);
        }
예제 #46
0
        public async Task GetListOfPackages(InterceptCallContext context)
        {
            V3InteropTraceSources.Channel.Verbose("GetListOfPackages", String.Empty);
            
            var index = await FetchJson(context, context.Args.IncludePrerelease ? new Uri(_listAvailableLatestPrereleaseIndex) : new Uri(_listAvailableLatestStableIndex));
            var data = GetListAvailableDataStart(context, index);

            // apply startswith if needed
            if (context.Args.PartialId != null)
            {
                data = data.Where(e => e["id"].ToString().StartsWith(context.Args.PartialId, StringComparison.OrdinalIgnoreCase));

                data = data.TakeWhile(e => e["id"].ToString().StartsWith(context.Args.PartialId, StringComparison.OrdinalIgnoreCase));
            }

            // take only 30
            var ids = data.Take(30).Select(p => p["id"].ToString()).ToList();

            ids.Sort(StringComparer.InvariantCultureIgnoreCase);

            JArray array = new JArray();
            foreach (var id in ids)
            {
                array.Add(id);
            }

            await context.WriteResponse(array);
        }
예제 #47
0
        public async Task GetLatestVersionPackage(InterceptCallContext context, string id, bool includePrerelease)
        {
            V3InteropTraceSources.Channel.Verbose("getlatestversionpackage", "{0} Pre={1}", id, includePrerelease);
            
            JObject resolverBlob = await FetchJson(context, MakeResolverAddress(id));

            if (resolverBlob == null)
            {
                throw new InvalidOperationException(string.Format("package {0} not found", id));
            }

            JToken latest = ExtractLatestVersion(resolverBlob, includePrerelease);

            if (latest == null)
            {
                throw new InvalidOperationException(string.Format("package {0} not found", id));
            }

            XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "Packages", new List<JToken> { latest }, id);
            await context.WriteResponse(feed);
        }
예제 #48
0
        public IEnumerable<JToken> GetListAvailableData(InterceptCallContext context, JObject index)
        {
            var data = GetListAvailableFastForwardSkipToken(context, index);

            // apply startswith if needed
            if (context.Args.FilterStartsWithId != null)
            {
                data = data.Where(e => e["id"].ToString().StartsWith(context.Args.FilterStartsWithId, StringComparison.OrdinalIgnoreCase));

                data = data.TakeWhile(e => e["id"].ToString().StartsWith(context.Args.FilterStartsWithId, StringComparison.OrdinalIgnoreCase));
            }

            return data;
        }
예제 #49
0
        public async Task GetListOfPackageVersions(InterceptCallContext context, string id)
        {
            V3InteropTraceSources.Channel.Verbose("GetListOfPackageVersions", id);
            
            JObject resolverBlob = await FetchJson(context, MakeResolverAddress(id));

            JArray array = new JArray();

            // the package may not exist, in that case return an empty array
            if (resolverBlob != null)
            {
                List<NuGetVersion> versions = new List<NuGetVersion>();
                foreach (JToken package in resolverBlob["packages"])
                {
                    NuGetVersion version = NuGetVersion.Parse(package["version"].ToString());

                    // all versions are returned, filter to only stable if needed
                    if (context.Args.IncludePrerelease || !version.IsPrerelease)
                    {
                        versions.Add(version);
                    }
                }

                versions.Sort();

                foreach (NuGetVersion version in versions)
                {
                    array.Add(version.ToString());
                }
            }

            await context.WriteResponse(array);
        }
예제 #50
0
        private async Task Packages(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            string path = Uri.UnescapeDataString(context.RequestUri.AbsolutePath);
            string query = context.RequestUri.Query;

            await GetPackage(context, path, query);
        }
예제 #51
0
        public async Task ListAvailable(InterceptCallContext context)
        {
            string indexUrl = _listAvailableLatestStableIndex;

            if (!context.Args.IsLatestVersion)
            {
                indexUrl = _listAvailableAllIndex;
            }
            else if (context.Args.IncludePrerelease)
            {
                indexUrl = _listAvailableLatestPrereleaseIndex;
            }

            var index = await FetchJson(context, new Uri(indexUrl));

            var data = GetListAvailableData(context, index);

            // all versions with no pre
            if (!context.Args.IsLatestVersion && !context.Args.IncludePrerelease)
            {
                data = data.Where(p => (new NuGetVersion(p["version"].ToString())).IsPrerelease == false);
            }

            string nextUrl = null;

            // Convert to a list after calling Take to avoid enumerating the list multiple times.

            if (context.Args.Top.HasValue && context.Args.Top.Value > 0)
            {
                data = data.Take(context.Args.Top.Value).ToList();
            }
            else
            {
                data = data.Take(30).ToList();

                if (data.Count() >= 30)
                {
                    var last = data.LastOrDefault();

                    if (last != null)
                    {
                        string argsWithoutSkipToken = String.Join("&", context.Args.Arguments.Where(a => a.Key.ToLowerInvariant() != "$skiptoken")
                            .Select(a => String.Format(CultureInfo.InvariantCulture, "{0}={1}", a.Key, a.Value)));

                        nextUrl = String.Format(CultureInfo.InvariantCulture, "{0}?{1}&$skiptoken='{2}','{2}','{3}'",
                                                context.RequestUri.AbsoluteUri.Split('?')[0],
                                                argsWithoutSkipToken,
                                                last["id"],
                                                last["version"]);
                    }
                }
            }

            XElement feed = InterceptFormatting.MakeFeed(_passThroughAddress, "Packages", data, data.Select(e => e["id"].ToString()).ToArray(), nextUrl);
            await context.WriteResponse(feed);
        }
예제 #52
0
        private async Task GetUpdates(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            IDictionary<string, string> arguments = context.Args.Arguments;

            string[] packageIds = Uri.UnescapeDataString(arguments["packageIds"]).Trim('\'').Split('|');
            string[] versions = Uri.UnescapeDataString(arguments["versions"]).Trim('\'').Split('|');
            string[] versionConstraints = Uri.UnescapeDataString(arguments["versionConstraints"]).Trim('\'').Split('|');
            string[] targetFrameworks = Uri.UnescapeDataString(arguments["targetFrameworks"]).Trim('\'').Split('|');
            bool includeAllVersions = false;
            bool.TryParse(arguments["includeAllVersions"], out includeAllVersions);

            await _channel.GetUpdates(context, packageIds, versions, versionConstraints, targetFrameworks, context.Args.IncludePrerelease, includeAllVersions, context.Args.Count);
        }
예제 #53
0
        public IEnumerable<JToken> GetListAvailableFastForwardSkipToken(InterceptCallContext context, JObject index)
        {
            var data = GetListAvailableDataStart(context, index);

            if (context.Args.SkipToken != null)
            {
                var skipToken = ParseSkipToken(context.Args.SkipToken);
                var skipTokenId = skipToken.Item1;
                var skipTokenVer = new NuGetVersion(skipToken.Item2);

                data = data.Where(e => skipTokenId == null || StringComparer.InvariantCultureIgnoreCase.Compare(e["id"].ToString(), skipTokenId) > 0
                    || (StringComparer.InvariantCultureIgnoreCase.Equals(e["id"].ToString(), skipTokenId) &&
                        (skipTokenVer == null || VersionComparer.VersionRelease.Compare(new NuGetVersion(e["version"].ToString()), skipTokenVer) > 0)));
            }

            return data;
        }
예제 #54
0
        private async Task PackageVersions(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            string path = context.RequestUri.AbsolutePath;
            string id = path.Substring(path.LastIndexOf("/") + 1);

            await _channel.GetListOfPackageVersions(context, id);
        }
예제 #55
0
        public static Queue<string> GetListAvailableSegmentsIncludingAndAfter(InterceptCallContext context, JObject index, string startsWith=null)
        {
            var segs = index["entry"].ToArray();

            Queue<string> needed = new Queue<string>();

            for (int i=0; i < segs.Length; i++)
            {
                // once we add the first one, take everythign after
                if (needed.Count > 0 || String.IsNullOrEmpty(startsWith))
                {
                    needed.Enqueue(segs[i]["url"].ToString());
                }
                else
                {
                    var seg = segs[i];

                    string lowest = seg["lowest"].ToString();

                    // advance until we go too far
                    if (needed.Count < 1 && StringComparer.InvariantCultureIgnoreCase.Compare(lowest, startsWith) >= 0)
                    {
                        if (i > 0)
                        {
                            // get the previous one
                            needed.Enqueue(segs[i - 1]["url"].ToString());
                        }

                        // add the current one
                        needed.Enqueue(segs[i]["url"].ToString());
                    }
                }
            }

            return needed;
        }
예제 #56
0
        private async Task PackageIds(InterceptCallContext context)
        {
            V3InteropTraceSources.Dispatcher.EnterMethod();

            await _channel.GetListOfPackages(context);
        }
예제 #57
0
        public async Task<List<JObject>> GetUpdatesCore(InterceptCallContext context, string[] packageIds, string[] versions, string[] versionConstraints, string[] targetFrameworks, bool includePrerelease, bool includeAllVersions)
        {
            List<JObject> packages = new List<JObject>();

            for (int i = 0; i < packageIds.Length; i++)
            {
                VersionRange range = null;

                if (i < versionConstraints.Length && !String.IsNullOrEmpty(versionConstraints[i]))
                {
                    VersionRange.TryParse(versionConstraints[i], out range);
                }

                JObject resolverBlob = await FetchJson(context, MakeResolverAddress(packageIds[i]));

                // TODO: handle this error
                if (resolverBlob != null)
                {
                    // this can be null if all packages are prerelease
                    JObject latest = ExtractLatestVersion(resolverBlob, includePrerelease, range) as JObject;
                    if (latest != null)
                    {
                        // add the id if it isn't there
                        if (latest["id"] == null)
                        {
                            latest.Add("id", JToken.Parse("'" + packageIds[i] + "'"));
                        }

                        if (i < versions.Length && !String.IsNullOrEmpty(versions[i]))
                        {
                            NuGetVersion latestVersion = NuGetVersion.Parse(latest["version"].ToString());
                            NuGetVersion currentVersion = NuGetVersion.Parse(versions[i]);

                            // only add the package if it is not the latest version
                            if (VersionComparer.VersionRelease.Compare(latestVersion, currentVersion) > 0)
                            {
                                packages.Add(latest);
                            }
                        }
                        else
                        {
                            packages.Add(latest);
                        }
                    }
                }
            }

            return packages;
        }
예제 #58
0
        public async Task DownloadPackage(InterceptCallContext context, string id, string version)
        {
            JToken package = await GetPackageCore(context, id, version);

            if (package == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "unable to find version {0} of package {1}", version, id));
            }

            string address = package["nupkgUrl"].ToString();


            V3InteropTraceSources.Channel.Info("downloadingpackage", "Downloading {0}", address);

            Stopwatch timer = new Stopwatch();
            timer.Start();

            System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
            HttpResponseMessage response = await client.GetAsync(address);
            byte[] data = await response.Content.ReadAsByteArrayAsync();

            timer.Stop();

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                V3InteropTraceSources.Channel.Info("downloadedpackage", "Downloaded {0} in {1}ms", address, timer.ElapsedMilliseconds);
            }
            else
            {
                V3InteropTraceSources.Channel.Error("downloadedpackage_error", "Error downloading {0} in {1}ms (status {2})", address, timer.ElapsedMilliseconds, response.StatusCode);
            }

            await context.WriteResponse(data, "application/zip");
        }
예제 #59
0
        private async Task SearchImpl(InterceptCallContext context, string feed = null)
        {
            int skip = context.Args.Skip ?? 0;
            int take = context.Args.Top ?? 30;

            string sortBy = string.Empty;

            await _channel.Search(context, context.Args.SearchTerm, context.Args.IsLatestVersion, context.Args.TargetFramework, context.Args.IncludePrerelease, skip, take, feed, sortBy);
        }
예제 #60
0
        public async Task Metadata(InterceptCallContext context, string feed = null)
        {
            V3InteropTraceSources.Channel.Verbose("metadata", feed ?? String.Empty);

            Stream stream = GetResourceStream(feed == null ? "xml.Metadata.xml" : "xml.FeedMetadata.xml");
            XElement xml = XElement.Load(stream);
            await context.WriteResponse(xml);
        }