Skip to content

Commit c2cac1d

Browse files
committed
Merge branch 'dev' into master (#79)
2 parents e5d8ee2 + 6366df2 commit c2cac1d

7 files changed

Lines changed: 124 additions & 53 deletions

File tree

build.ps1

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ param (
99
[string]$SemanticVersion = '1.0.0-zlocal',
1010
[string]$Branch,
1111
[string]$CommitSHA,
12-
[string]$BuildBranch = 'ed30a6392ef7c342ca46b20f7b9c964ab9ad5881'
12+
[string]$BuildBranch = '2d8feecabe3aeaed7f5b4d50b9be78c94faf39ec'
1313
)
1414

1515
$msBuildVersion = 15;
@@ -91,9 +91,8 @@ Invoke-BuildStep 'Creating artifacts' {
9191
} `
9292
-ev +BuildErrors
9393

94-
Invoke-BuildStep 'Signing the packages' {
95-
$ProjectPath = Join-Path $PSScriptRoot "build\sign.proj"
96-
Build-Solution $Configuration $BuildNumber -MSBuildVersion "$msBuildVersion" $ProjectPath `
94+
Invoke-BuildStep 'Signing the packages' {
95+
Sign-Packages -Configuration $Configuration -BuildNumber $BuildNumber -MSBuildVersion $msBuildVersion `
9796
} `
9897
-ev +BuildErrors
9998

build/sign.proj

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/NuGet.Server.V2/NuGetV2WebApiEnabler.cs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
34
using System;
45
using System.Linq;
56
using System.Net.Http;
@@ -19,10 +20,46 @@ namespace NuGet.Server.V2
1920
{
2021
public static class NuGetV2WebApiEnabler
2122
{
23+
/// <summary>
24+
/// Enables the NuGet V2 protocol routes on this <see cref="HttpConfiguration"/>. Note that this method does
25+
/// not activate the legacy push URL, <code>api/v2/package</code>. To activate the legacy push route, use the
26+
/// <see cref="UseNuGetV2WebApiFeed(HttpConfiguration, string, string, string, bool)"/> method overload.
27+
/// </summary>
28+
/// <param name="config">The HTTP configuration associated with your web app.</param>
29+
/// <param name="routeName">The route name prefix, to allow multiple feeds per web app.</param>
30+
/// <param name="routeUrlRoot">The base URL for the routes, to allow multiple feeds per web app.</param>
31+
/// <param name="oDatacontrollerName">The name of the OData controller containing the actions.</param>
32+
/// <returns>The <paramref name="config"/> provided, for chaining purposes.</returns>
2233
public static HttpConfiguration UseNuGetV2WebApiFeed(this HttpConfiguration config,
2334
string routeName,
24-
string routeUrlRoot,
35+
string routeUrlRoot,
2536
string oDatacontrollerName)
37+
{
38+
return config.UseNuGetV2WebApiFeed(
39+
routeName,
40+
routeUrlRoot,
41+
oDatacontrollerName,
42+
enableLegacyPushRoute: false);
43+
}
44+
45+
/// <summary>
46+
/// Enables the NuGet V2 protocol routes on this <see cref="HttpConfiguration"/>.
47+
/// </summary>
48+
/// <param name="config">The HTTP configuration associated with your web app.</param>
49+
/// <param name="routeName">The route name prefix, to allow multiple feeds per web app.</param>
50+
/// <param name="routeUrlRoot">The base URL for the routes, to allow multiple feeds per web app.</param>
51+
/// <param name="oDatacontrollerName">The name of the OData controller containing the actions.</param>
52+
/// <param name="enableLegacyPushRoute">
53+
/// Whether or not to enable the legacy push URL, <code>api/v2/package</code>. Note that this route does not
54+
/// use the <paramref name="routeName"/> prefix or <paramref name="routeUrlRoot"/> and therefore should only
55+
/// be enabled once (i.e. on a single controller).
56+
/// </param>
57+
/// <returns>The <paramref name="config"/> provided, for chaining purposes.</returns>
58+
public static HttpConfiguration UseNuGetV2WebApiFeed(this HttpConfiguration config,
59+
string routeName,
60+
string routeUrlRoot,
61+
string oDatacontrollerName,
62+
bool enableLegacyPushRoute)
2663
{
2764
// Insert conventions to make NuGet-compatible OData feed possible
2865
var conventions = ODataRoutingConventions.CreateDefault();
@@ -53,12 +90,15 @@ public static HttpConfiguration UseNuGetV2WebApiFeed(this HttpConfiguration conf
5390
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Delete) }
5491
);
5592

56-
config.Routes.MapHttpRoute(
57-
name: "apiv2package_upload",
58-
routeTemplate: "api/v2/package",
59-
defaults: new { controller = oDatacontrollerName, action = "UploadPackage" },
60-
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Put) }
61-
);
93+
if (enableLegacyPushRoute)
94+
{
95+
config.Routes.MapHttpRoute(
96+
name: "apiv2package_upload",
97+
routeTemplate: "api/v2/package",
98+
defaults: new { controller = oDatacontrollerName, action = "UploadPackage" },
99+
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Put) }
100+
);
101+
}
62102

63103
config.Routes.MapODataServiceRoute(routeName, routeUrlRoot, oDataModel, new CountODataPathHandler(), conventions);
64104
return config;

src/NuGet.Server/App_Start/NuGetODataConfig.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ public static void Start()
2828

2929
public static void Initialize(HttpConfiguration config, string controllerName)
3030
{
31-
NuGetV2WebApiEnabler.UseNuGetV2WebApiFeed(config, "NuGetDefault", "nuget", controllerName);
31+
NuGetV2WebApiEnabler.UseNuGetV2WebApiFeed(
32+
config,
33+
"NuGetDefault",
34+
"nuget",
35+
controllerName,
36+
enableLegacyPushRoute: true);
3237

3338
config.Services.Replace(typeof(IExceptionLogger), new TraceExceptionLogger());
3439

src/NuGet.Server/App_Start/NuGetODataConfig.cs.pp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,19 @@
1111
namespace $rootnamespace$.App_Start
1212
{
1313
public static class NuGetODataConfig
14-
{
14+
{
1515
public static void Start()
16-
{
16+
{
1717
ServiceResolver.SetServiceResolver(new DefaultServiceResolver());
1818

1919
var config = GlobalConfiguration.Configuration;
2020

21-
NuGetV2WebApiEnabler.UseNuGetV2WebApiFeed(config, "NuGetDefault", "nuget", "PackagesOData");
21+
NuGetV2WebApiEnabler.UseNuGetV2WebApiFeed(
22+
config,
23+
"NuGetDefault",
24+
"nuget",
25+
"PackagesOData",
26+
enableLegacyPushRoute: true);
2227

2328
config.Services.Replace(typeof(IExceptionLogger), new TraceExceptionLogger());
2429

test/NuGet.Server.Tests/IntegrationTests.cs

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using NuGet.Server.Core.Logging;
2020
using NuGet.Server.Core.Tests;
2121
using NuGet.Server.Core.Tests.Infrastructure;
22+
using NuGet.Server.V2;
2223
using Xunit;
2324
using Xunit.Abstractions;
2425
using ISystemDependencyResolver = System.Web.Http.Dependencies.IDependencyResolver;
@@ -162,6 +163,51 @@ public async Task PushPackageThenReadPackages()
162163
}
163164
}
164165

166+
[Fact]
167+
public async Task CanSupportMultipleSetsOfRoutes()
168+
{
169+
// Arrange
170+
using (var tc = new TestContext(_output))
171+
{
172+
// Enable another set of routes.
173+
NuGetV2WebApiEnabler.UseNuGetV2WebApiFeed(
174+
tc.Config,
175+
"NuGetDefault2",
176+
"nuget2",
177+
TestablePackagesODataController.Name);
178+
179+
string apiKey = "foobar";
180+
tc.SetApiKey(apiKey);
181+
182+
var packagePath = Path.Combine(tc.TemporaryDirectory, "package.nupkg");
183+
TestData.CopyResourceToPath(TestData.PackageResource, packagePath);
184+
185+
// Act & Assert
186+
// 1. Push to the legacy route.
187+
await tc.PushPackageAsync(apiKey, packagePath, "/api/v2/package");
188+
189+
// 2. Make a request to the first set of routes.
190+
using (var request = new HttpRequestMessage(HttpMethod.Get, "/nuget/Packages()"))
191+
using (var response = await tc.Client.SendAsync(request))
192+
{
193+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
194+
var content = await response.Content.ReadAsStringAsync();
195+
196+
Assert.Contains(TestData.PackageId, content);
197+
}
198+
199+
// 3. Make a request to the second set of routes.
200+
using (var request = new HttpRequestMessage(HttpMethod.Get, "/nuget2/Packages()"))
201+
using (var response = await tc.Client.SendAsync(request))
202+
{
203+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
204+
var content = await response.Content.ReadAsStringAsync();
205+
206+
Assert.Contains(TestData.PackageId, content);
207+
}
208+
}
209+
}
210+
165211
/// <summary>
166212
/// Added due to https://github.com/NuGet/NuGetGallery/issues/6960. There was a concurrency issue when pushing
167213
/// packages that could lead to unnecessary cache rebuilds.
@@ -354,7 +400,6 @@ public static IEnumerable<object[]> EndpointsSupportingProjection
354400
private sealed class TestContext : IDisposable
355401
{
356402
private readonly HttpServer _server;
357-
private readonly HttpConfiguration _config;
358403

359404
public TestContext(ITestOutputHelper output)
360405
{
@@ -371,13 +416,13 @@ public TestContext(ITestOutputHelper output)
371416

372417
ServiceResolver = new DefaultServiceResolver(PackagesDirectory, Settings, Logger);
373418

374-
_config = new HttpConfiguration();
375-
_config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
376-
_config.DependencyResolver = new DependencyResolverAdapter(ServiceResolver);
419+
Config = new HttpConfiguration();
420+
Config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
421+
Config.DependencyResolver = new DependencyResolverAdapter(ServiceResolver);
377422

378-
NuGetODataConfig.Initialize(_config, "TestablePackagesOData");
423+
NuGetODataConfig.Initialize(Config, TestablePackagesODataController.Name);
379424

380-
_server = new HttpServer(_config);
425+
_server = new HttpServer(Config);
381426
Client = new SystemHttpClient(_server);
382427
Client.BaseAddress = new Uri("http://localhost/");
383428
}
@@ -388,6 +433,7 @@ public TestContext(ITestOutputHelper output)
388433
public TemporaryDirectory TemporaryDirectory { get; }
389434
public TemporaryDirectory PackagesDirectory { get; }
390435
public NameValueCollection Settings { get; }
436+
public HttpConfiguration Config { get; }
391437
public SystemHttpClient Client { get; }
392438

393439
public void SetApiKey(string apiKey)
@@ -416,30 +462,27 @@ public MultipartContent GetFileUploadContent(params string[] paths)
416462
return content;
417463
}
418464

419-
public async Task PushPackageAsync(string apiKey, string packagePath)
465+
public async Task PushPackageAsync(string apiKey, string packagePath, string pushUrl = "/nuget")
420466
{
421-
using (var request = new HttpRequestMessage(HttpMethod.Put, "/nuget")
467+
using (var request = new HttpRequestMessage(HttpMethod.Put, pushUrl)
422468
{
423469
Headers =
424470
{
425471
{ "X-NUGET-APIKEY", apiKey }
426472
},
427473
Content = GetFileUploadContent(packagePath)
428474
})
475+
using (var response = await Client.SendAsync(request))
429476
{
430-
using (request)
431-
using (var response = await Client.SendAsync(request))
432-
{
433-
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
434-
}
477+
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
435478
}
436479
}
437480

438481
public void Dispose()
439482
{
440483
Client.Dispose();
441484
_server.Dispose();
442-
_config.Dispose();
485+
Config.Dispose();
443486
ServiceResolver.Dispose();
444487
PackagesDirectory.Dispose();
445488
TemporaryDirectory.Dispose();

test/NuGet.Server.Tests/TestablePackagesODataController.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ namespace NuGet.Server.Tests
77
{
88
public class TestablePackagesODataController : PackagesODataController
99
{
10+
public static readonly string Name = nameof(TestablePackagesODataController)
11+
.Substring(0, nameof(TestablePackagesODataController).Length - "Controller".Length);
12+
1013
public TestablePackagesODataController(IServiceResolver serviceResolver)
1114
: base(serviceResolver)
1215
{

0 commit comments

Comments
 (0)