Skip to content

Commit f2436a7

Browse files
authored
Set the CacheControl property on packages blobs (#6297)
This sets the `CacheControl` property on all packages blobs to 2 minutes. Fixes #6285
1 parent bc0954b commit f2436a7

3 files changed

Lines changed: 66 additions & 2 deletions

File tree

src/NuGetGallery.Core/CoreConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public static class CoreConstants
2323
public const string CertificateContentType = "application/pkix-cert";
2424
public const string JsonContentType = "application/json";
2525

26+
public const string DefaultCacheControl = "max-age=120";
27+
2628
public const string UserCertificatesFolderName = "user-certificates";
2729
public const string ContentFolderName = "content";
2830
public const string DownloadsFolderName = "downloads";

src/NuGetGallery.Core/Services/CloudBlobCoreFileStorageService.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ public async Task SaveFileAsync(string folderName, string fileName, Stream file,
318318
}
319319

320320
blob.Properties.ContentType = GetContentType(folderName);
321+
blob.Properties.CacheControl = GetCacheControl(folderName);
321322
await blob.SetPropertiesAsync();
322323
}
323324

@@ -549,6 +550,7 @@ private static string GetContentType(string folderName)
549550
case CoreConstants.PackageReadMesFolderName:
550551
return CoreConstants.TextContentType;
551552

553+
case CoreConstants.ContentFolderName:
552554
case CoreConstants.RevalidationFolderName:
553555
case CoreConstants.StatusFolderName:
554556
return CoreConstants.JsonContentType;
@@ -562,6 +564,32 @@ private static string GetContentType(string folderName)
562564
}
563565
}
564566

567+
private static string GetCacheControl(string folderName)
568+
{
569+
switch (folderName)
570+
{
571+
case CoreConstants.PackagesFolderName:
572+
return CoreConstants.DefaultCacheControl;
573+
574+
case CoreConstants.PackageBackupsFolderName:
575+
case CoreConstants.UploadsFolderName:
576+
case CoreConstants.ValidationFolderName:
577+
case CoreConstants.SymbolPackagesFolderName:
578+
case CoreConstants.SymbolPackageBackupsFolderName:
579+
case CoreConstants.DownloadsFolderName:
580+
case CoreConstants.PackageReadMesFolderName:
581+
case CoreConstants.ContentFolderName:
582+
case CoreConstants.RevalidationFolderName:
583+
case CoreConstants.StatusFolderName:
584+
case CoreConstants.UserCertificatesFolderName:
585+
return null;
586+
587+
default:
588+
throw new InvalidOperationException(
589+
String.Format(CultureInfo.CurrentCulture, "The folder name {0} is not supported.", folderName));
590+
}
591+
}
592+
565593
private async Task<ICloudBlobContainer> PrepareContainer(string folderName, bool isPublic)
566594
{
567595
var container = _client.GetContainerReference(folderName);

tests/NuGetGallery.Core.Facts/Services/CloudBlobCoreFileStorageServiceFacts.cs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public override IEnumerable<object[]> GetData(MethodInfo testMethod)
4848
{
4949
var folderNames = new List<object[]>
5050
{
51-
new object[] { CoreConstants.ContentFolderName, false, null, },
51+
new object[] { CoreConstants.ContentFolderName, false, CoreConstants.JsonContentType, },
5252
new object[] { CoreConstants.DownloadsFolderName, true, CoreConstants.OctetStreamContentType },
5353
new object[] { CoreConstants.PackageBackupsFolderName, true, CoreConstants.PackageContentType },
5454
new object[] { CoreConstants.PackageReadMesFolderName, false, CoreConstants.TextContentType },
@@ -73,7 +73,6 @@ public override IEnumerable<object[]> GetData(MethodInfo testMethod)
7373
else if (!IncludePermissions && IncludeContentTypes)
7474
{
7575
folderNames = folderNames
76-
.Where(fn => fn[2] != null)
7776
.Select(fn => new[] { fn[0], fn[2] })
7877
.ToList();
7978
}
@@ -512,6 +511,41 @@ public async Task WillSetTheBlobContentType(string folderName, string contentTyp
512511
Assert.Equal(contentType, fakeBlob.Object.Properties.ContentType);
513512
fakeBlob.Verify(x => x.SetPropertiesAsync());
514513
}
514+
515+
[Theory]
516+
[FolderNamesData]
517+
public async Task WillSetTheBlobControlCacheOnPackagesFolder(string folderName)
518+
{
519+
var fakeBlobClient = new Mock<ICloudBlobClient>();
520+
var fakeBlobContainer = new Mock<ICloudBlobContainer>();
521+
fakeBlobContainer.Setup(x => x.CreateIfNotExistAsync()).Returns(Task.FromResult(0));
522+
fakeBlobContainer.Setup(x => x.SetPermissionsAsync(It.IsAny<BlobContainerPermissions>())).Returns(Task.FromResult(0));
523+
var fakeBlob = new Mock<ISimpleCloudBlob>();
524+
fakeBlobClient.Setup(x => x.GetContainerReference(It.IsAny<string>())).Returns(fakeBlobContainer.Object);
525+
fakeBlobContainer.Setup(x => x.GetBlobReference(It.IsAny<string>())).Returns(fakeBlob.Object);
526+
fakeBlob.Setup(x => x.Properties).Returns(new BlobProperties());
527+
fakeBlob.Setup(x => x.Uri).Returns(new Uri("http://theUri"));
528+
fakeBlob.Setup(x => x.DeleteIfExistsAsync()).Returns(Task.FromResult(0));
529+
fakeBlob.Setup(x => x.SetPropertiesAsync()).Returns(Task.FromResult(0));
530+
var service = CreateService(fakeBlobClient: fakeBlobClient);
531+
var fakePackageFile = new MemoryStream();
532+
fakeBlob.Setup(x => x.UploadFromStreamAsync(fakePackageFile, true)).Returns(Task.FromResult(0)).Verifiable();
533+
534+
await service.SaveFileAsync(folderName, "theFileName", fakePackageFile);
535+
536+
fakeBlob.Verify();
537+
538+
if (folderName == CoreConstants.PackagesFolderName)
539+
{
540+
Assert.Equal(CoreConstants.DefaultCacheControl, fakeBlob.Object.Properties.CacheControl);
541+
}
542+
else
543+
{
544+
Assert.Null(fakeBlob.Object.Properties.CacheControl);
545+
}
546+
547+
fakeBlob.Verify(x => x.SetPropertiesAsync());
548+
}
515549
}
516550

517551
public class TheSaveFileWithAccessConditionMethod

0 commit comments

Comments
 (0)