Skip to content

Commit

Permalink
Merge branch 'dev' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
joelverhagen committed Feb 5, 2018
2 parents c7d9144 + 44ce576 commit f507bd2
Show file tree
Hide file tree
Showing 18 changed files with 465 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using NuGet.Server.Core.Infrastructure;

namespace NuGet.Server.V2.Samples.OwinHost
{
public class DictionarySettingsProvider : ISettingsProvider
{
readonly Dictionary<string, bool> _settings;
readonly Dictionary<string, object> _settings;

public DictionarySettingsProvider(Dictionary<string, bool> settings)
public DictionarySettingsProvider(Dictionary<string, object> settings)
{
_settings = settings;
}
Expand All @@ -18,8 +19,13 @@ public DictionarySettingsProvider(Dictionary<string, bool> settings)
public bool GetBoolSetting(string key, bool defaultValue)
{
System.Diagnostics.Debug.WriteLine("getSetting: " + key);
return _settings.ContainsKey(key) ? _settings[key] : defaultValue;
return _settings.ContainsKey(key) ? Convert.ToBoolean(_settings[key]) : defaultValue;

}

public string GetStringSetting(string key, string defaultValue)
{
return _settings.ContainsKey(key) ? Convert.ToString(_settings[key]) : defaultValue;
}
}
}
2 changes: 1 addition & 1 deletion samples/NuGet.Server.V2.Samples.OwinHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static void Main(string[] args)

// Set up a common settingsProvider to be used by all repositories.
// If a setting is not present in dictionary default value will be used.
var settings = new Dictionary<string, bool>();
var settings = new Dictionary<string, object>();
settings.Add("enableDelisting", false); //default=false
settings.Add("enableFrameworkFiltering", false); //default=false
settings.Add("ignoreSymbolsPackages", true); //default=false
Expand Down
40 changes: 40 additions & 0 deletions src/NuGet.Server.Core/Core/NullFileSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;

namespace NuGet.Server.Core
{
/// <summary>
/// A file system implementation that persists nothing. This is intended to be used with
/// <see cref="OptimizedZipPackage"/> so that package files are never actually extracted anywhere on disk.
/// </summary>
public class NullFileSystem : IFileSystem
{
public static NullFileSystem Instance { get; } = new NullFileSystem();

public Stream CreateFile(string path) => Stream.Null;
public bool DirectoryExists(string path) => true;
public bool FileExists(string path) => false;
public string GetFullPath(string path) => null;
public Stream OpenFile(string path) => Stream.Null;

public ILogger Logger { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
public string Root => throw new NotSupportedException();
public void AddFile(string path, Stream stream) => throw new NotSupportedException();
public void AddFile(string path, Action<Stream> writeToStream) => throw new NotSupportedException();
public void AddFiles(IEnumerable<IPackageFile> files, string rootDir) => throw new NotSupportedException();
public void DeleteDirectory(string path, bool recursive) => throw new NotSupportedException();
public void DeleteFile(string path) => throw new NotSupportedException();
public void DeleteFiles(IEnumerable<IPackageFile> files, string rootDir) => throw new NotSupportedException();
public DateTimeOffset GetCreated(string path) => throw new NotSupportedException();
public IEnumerable<string> GetDirectories(string path) => throw new NotSupportedException();
public IEnumerable<string> GetFiles(string path, string filter, bool recursive) => throw new NotSupportedException();
public DateTimeOffset GetLastAccessed(string path) => throw new NotSupportedException();
public DateTimeOffset GetLastModified(string path) => throw new NotSupportedException();
public void MakeFileWritable(string path) => throw new NotSupportedException();
public void MoveFile(string source, string destination) => throw new NotSupportedException();
}
}
29 changes: 29 additions & 0 deletions src/NuGet.Server.Core/Core/PackageFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.IO;

namespace NuGet.Server.Core
{
public static class PackageFactory
{
public static IPackage Open(string fullPackagePath)
{
if (string.IsNullOrEmpty(fullPackagePath))
{
throw new ArgumentNullException(nameof(fullPackagePath));
}

var directoryName = Path.GetDirectoryName(fullPackagePath);
var fileName = Path.GetFileName(fullPackagePath);

var fileSystem = new PhysicalFileSystem(directoryName);

return new OptimizedZipPackage(
fileSystem,
fileName,
NullFileSystem.Instance);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@ public bool GetBoolSetting(string key, bool defaultValue)
{
return defaultValue;
}

public string GetStringSetting(string key, string defaultValue)
{
return defaultValue;
}
}
}
1 change: 1 addition & 0 deletions src/NuGet.Server.Core/Infrastructure/ISettingsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ namespace NuGet.Server.Core.Infrastructure
public interface ISettingsProvider
{
bool GetBoolSetting(string key, bool defaultValue);
string GetStringSetting(string key, string defaultValue);
}
}
40 changes: 35 additions & 5 deletions src/NuGet.Server.Core/Infrastructure/ServerPackageRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public ServerPackageRepository(
_runBackgroundTasks = true;
_settingsProvider = settingsProvider ?? new DefaultSettingsProvider();
_logger = logger ?? new TraceLogger();
_serverPackageCache = InitializeServerPackageStore();
_serverPackageCache = InitializeServerPackageCache();
_serverPackageStore = new ServerPackageStore(
_fileSystem,
new ExpandedPackageRepository(_fileSystem, hashProvider),
Expand All @@ -81,7 +81,7 @@ internal ServerPackageRepository(
_runBackgroundTasks = runBackgroundTasks;
_settingsProvider = settingsProvider ?? new DefaultSettingsProvider();
_logger = logger ?? new TraceLogger();
_serverPackageCache = InitializeServerPackageStore();
_serverPackageCache = InitializeServerPackageCache();
_serverPackageStore = new ServerPackageStore(
_fileSystem,
innerRepository,
Expand All @@ -105,9 +105,39 @@ internal ServerPackageRepository(
private bool EnableFileSystemMonitoring =>
_settingsProvider.GetBoolSetting("enableFileSystemMonitoring", true);

private ServerPackageCache InitializeServerPackageStore()
private string CacheFileName => _settingsProvider.GetStringSetting("cacheFileName", null);

private ServerPackageCache InitializeServerPackageCache()
{
return new ServerPackageCache(_fileSystem, Environment.MachineName.ToLowerInvariant() + ".cache.bin");
return new ServerPackageCache(_fileSystem, ResolveCacheFileName());
}

private string ResolveCacheFileName()
{
var fileName = CacheFileName;
const string suffix = ".cache.bin";

if (String.IsNullOrWhiteSpace(fileName))
{
// Default file name
return Environment.MachineName.ToLowerInvariant() + suffix;
}

if (fileName.LastIndexOfAny(Path.GetInvalidFileNameChars()) > 0)
{
var message = string.Format(Strings.Error_InvalidCacheFileName, fileName);

_logger.Log(LogLevel.Error, message);

throw new InvalidOperationException(message);
}

if (fileName.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))
{
return fileName;
}

return fileName + suffix;
}

/// <summary>
Expand Down Expand Up @@ -236,7 +266,7 @@ private void AddPackagesFromDropFolderWithoutLocking()
try
{
// Create package
var package = new OptimizedZipPackage(_fileSystem, packageFile);
var package = PackageFactory.Open(_fileSystem.GetFullPath(packageFile));

if (!CanPackageBeAddedWithoutLocking(package, shouldThrow: false))
{
Expand Down
2 changes: 2 additions & 0 deletions src/NuGet.Server.Core/NuGet.Server.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@
</Compile>
<Compile Include="Core\Constants.cs" />
<Compile Include="Core\FrameworkNameExtensions.cs" />
<Compile Include="Core\NullFileSystem.cs" />
<Compile Include="Core\PackageExtensions.cs" />
<Compile Include="Core\PackageFactory.cs" />
<Compile Include="DataServices\IgnoreCaseForPackageIdInterceptor.cs" />
<Compile Include="DataServices\NormalizeVersionInterceptor.cs" />
<Compile Include="DataServices\ODataPackage.cs" />
Expand Down
9 changes: 9 additions & 0 deletions src/NuGet.Server.Core/Strings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/NuGet.Server.Core/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Error_InvalidCacheFileName" xml:space="preserve">
<value>Configured cache file name '{0}' is invalid. Keep it simple; No paths allowed.</value>
</data>
<data name="Error_PackageAlreadyExists" xml:space="preserve">
<value>Package {0} already exists. The server is configured to not allow overwriting packages that already exist.</value>
</data>
Expand Down
4 changes: 2 additions & 2 deletions src/NuGet.Server.V2/Controllers/NuGetODataController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using System.Web.Http;
using System.Web.Http.OData;
using System.Web.Http.OData.Query;
using NuGet.Server.Core;
using NuGet.Server.Core.DataServices;
using NuGet.Server.Core.Infrastructure;
using NuGet.Server.V2.Model;
Expand Down Expand Up @@ -396,8 +397,7 @@ public virtual async Task<HttpResponseMessage> UploadPackage(CancellationToken t
}
}

var package = new OptimizedZipPackage(temporaryFile);

var package = PackageFactory.Open(temporaryFile);

HttpResponseMessage retValue;
if (_authenticationService.IsAuthenticated(User, apiKey, package.Id))
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Server/Infrastructure/WebConfigSettingsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,11 @@ public bool GetBoolSetting(string key, bool defaultValue)
bool value;
return !bool.TryParse(settings[key], out value) ? defaultValue : value;
}

public string GetStringSetting(string key, string defaultValue)
{
var settings = _getSettings();
return settings[key] ?? defaultValue;
}
}
}
6 changes: 6 additions & 0 deletions src/NuGet.Server/Web.config
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
-->
<add key="packagesPath" value="" />

<!--
Change the name of the internal cache file. Default is machine name (System.Environment.MachineName).
This is the name of the cache file in the packages folder. No paths allowed.
-->
<add key="cacheFileName" value="" />

<!--
Set allowOverrideExistingPackageOnPush to false to mimic NuGet.org's behaviour (do not allow overwriting packages with same id + version).
-->
Expand Down
83 changes: 83 additions & 0 deletions test/NuGet.Server.Core.Tests/Core/PackageFactoryTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.IO;
using NuGet.Server.Core.Tests.Infrastructure;
using Xunit;

namespace NuGet.Server.Core.Tests.Core
{
public class PackageFactoryTest
{
public class Open : IDisposable
{
private readonly TemporaryDirectory _directory;

public Open()
{
_directory = new TemporaryDirectory();
}

[Theory]
[InlineData(null)]
[InlineData("")]
public void RejectsInvalidPaths(string path)
{
var ex = Assert.Throws<ArgumentNullException>(
() => PackageFactory.Open(path));
Assert.Equal("fullPackagePath", ex.ParamName);
}

[Fact]
public void InitializesPackageWithMetadata()
{
// Arrange
var path = Path.Combine(_directory, "package.nupkg");
TestData.CopyResourceToPath(TestData.PackageResource, path);

// Act
var package = PackageFactory.Open(path);

// Assert
Assert.Equal(TestData.PackageId, package.Id);
Assert.Equal(TestData.PackageVersion, package.Version);
}

[Fact]
public void InitializesPackageWithSupportedFrameworks()
{
// Arrange
var path = Path.Combine(_directory, "package.nupkg");
TestData.CopyResourceToPath(TestData.PackageResource, path);

// Act
var package = PackageFactory.Open(path);

// Assert
var frameworks = package.GetSupportedFrameworks();
var framework = Assert.Single(frameworks);
Assert.Equal(VersionUtility.ParseFrameworkName("net40-client"), framework);
}

[Fact]
public void InitializesPackageWhichCanBeCheckedForSymbols()
{
// Arrange
var path = Path.Combine(_directory, "package.nupkg");
TestData.CopyResourceToPath(TestData.PackageResource, path);

// Act
var package = PackageFactory.Open(path);

// Assert
Assert.False(package.IsSymbolsPackage(), "The provided package is not a symbols package.");
}

public void Dispose()
{
_directory?.Dispose();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ namespace NuGet.Server.Core.Tests.Infrastructure
{
class FuncSettingsProvider : ISettingsProvider
{
readonly Func<string, bool, bool> _getSetting;
internal FuncSettingsProvider(Func<string,bool,bool> getSetting)
readonly Func<string, object, object> _getSetting;
internal FuncSettingsProvider(Func<string, object, object> getSetting)
{
if (getSetting == null)
{
Expand All @@ -20,7 +20,12 @@ internal FuncSettingsProvider(Func<string,bool,bool> getSetting)

public bool GetBoolSetting(string key, bool defaultValue)
{
return _getSetting(key, defaultValue);
return Convert.ToBoolean(_getSetting(key, defaultValue));
}

public string GetStringSetting(string key, string defaultValue)
{
return Convert.ToString(_getSetting(key, defaultValue));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
<ItemGroup>
<Compile Include="ApiKeyPackageAuthenticationServiceTest.cs" />
<Compile Include="ClientCompatibilityFactoryTests.cs" />
<Compile Include="Core\PackageFactoryTest.cs" />
<Compile Include="IdAndVersionEqualityComparerTest.cs" />
<Compile Include="IgnoreCaseForPackageIdInterceptorTest.cs" />
<Compile Include="Infrastructure\FuncSettingsProvider.cs" />
Expand Down
Loading

0 comments on commit f507bd2

Please sign in to comment.