diff options
author | Rob Mensching <rob@firegiant.com> | 2021-04-19 12:49:52 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2021-04-19 16:01:11 -0700 |
commit | c76db43a5ce1da70a980dc5651141c2a6cd94f6b (patch) | |
tree | bfb53c18f063c6046e0920a4cf2f53cec843f717 /src | |
parent | 930b0ca136824d7f4917482fe7a7a577d28f6903 (diff) | |
download | wix-c76db43a5ce1da70a980dc5651141c2a6cd94f6b.tar.gz wix-c76db43a5ce1da70a980dc5651141c2a6cd94f6b.tar.bz2 wix-c76db43a5ce1da70a980dc5651141c2a6cd94f6b.zip |
Resolve container and payload DownloadUrls
Fixes wixtoolset/issues#6405
Diffstat (limited to 'src')
4 files changed, 138 insertions, 48 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index ea8d33d0..fd847e05 100644 --- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs | |||
@@ -459,12 +459,18 @@ namespace WixToolset.Core.Burn | |||
459 | containers = command.Containers; | 459 | containers = command.Containers; |
460 | } | 460 | } |
461 | 461 | ||
462 | // Resolve the download URLs now that we have all of the containers and payloads calculated. | ||
463 | { | ||
464 | var command = new ResolveDownloadUrlsCommand(this.Messaging, this.BackendExtensions, containers, payloadSymbols); | ||
465 | command.Execute(); | ||
466 | } | ||
467 | |||
462 | // Create the bundle manifest. | 468 | // Create the bundle manifest. |
463 | string manifestPath; | 469 | string manifestPath; |
464 | { | 470 | { |
465 | var executableName = Path.GetFileName(this.OutputPath); | 471 | var executableName = Path.GetFileName(this.OutputPath); |
466 | 472 | ||
467 | var command = new CreateBurnManifestCommand(this.Messaging, this.BackendExtensions, executableName, section, bundleSymbol, containers, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, packagesPayloads, orderedSearches, this.IntermediateFolder); | 473 | var command = new CreateBurnManifestCommand(executableName, section, bundleSymbol, containers, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, packagesPayloads, orderedSearches, this.IntermediateFolder); |
468 | command.Execute(); | 474 | command.Execute(); |
469 | 475 | ||
470 | manifestPath = command.OutputPath; | 476 | manifestPath = command.OutputPath; |
diff --git a/src/WixToolset.Core.Burn/Bind/ResolveDownloadUrlsCommand.cs b/src/WixToolset.Core.Burn/Bind/ResolveDownloadUrlsCommand.cs new file mode 100644 index 00000000..e41c1058 --- /dev/null +++ b/src/WixToolset.Core.Burn/Bind/ResolveDownloadUrlsCommand.cs | |||
@@ -0,0 +1,127 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Core.Burn.Bind | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using WixToolset.Data; | ||
8 | using WixToolset.Data.Symbols; | ||
9 | using WixToolset.Extensibility; | ||
10 | using WixToolset.Extensibility.Services; | ||
11 | |||
12 | internal class ResolveDownloadUrlsCommand | ||
13 | { | ||
14 | public ResolveDownloadUrlsCommand(IMessaging messaging, IEnumerable<IBurnBackendBinderExtension> backendExtensions, IEnumerable<WixBundleContainerSymbol> containers, Dictionary<string, WixBundlePayloadSymbol> payloadsById) | ||
15 | { | ||
16 | this.Messaging = messaging; | ||
17 | this.BackendExtensions = backendExtensions; | ||
18 | this.Containers = containers; | ||
19 | this.PayloadsById = payloadsById; | ||
20 | } | ||
21 | |||
22 | private IMessaging Messaging { get; } | ||
23 | |||
24 | private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; } | ||
25 | |||
26 | private IEnumerable<WixBundleContainerSymbol> Containers { get; } | ||
27 | |||
28 | private Dictionary<string, WixBundlePayloadSymbol> PayloadsById { get; } | ||
29 | |||
30 | public void Execute() | ||
31 | { | ||
32 | this.ResolveContainerUrls(); | ||
33 | |||
34 | this.ResolvePayloadUrls(); | ||
35 | } | ||
36 | |||
37 | private void ResolveContainerUrls() | ||
38 | { | ||
39 | foreach (var container in this.Containers) | ||
40 | { | ||
41 | if (container.Type == ContainerType.Detached) | ||
42 | { | ||
43 | var resolvedUrl = this.ResolveUrl(container.DownloadUrl, null, null, container.Id.Id, container.Name); | ||
44 | if (!String.IsNullOrEmpty(resolvedUrl)) | ||
45 | { | ||
46 | container.DownloadUrl = resolvedUrl; | ||
47 | } | ||
48 | } | ||
49 | else if (container.Type == ContainerType.Attached) | ||
50 | { | ||
51 | if (!String.IsNullOrEmpty(container.DownloadUrl)) | ||
52 | { | ||
53 | this.Messaging.Write(WarningMessages.DownloadUrlNotSupportedForAttachedContainers(container.SourceLineNumbers, container.Id.Id)); | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | private void ResolvePayloadUrls() | ||
60 | { | ||
61 | foreach (var payload in this.PayloadsById.Values) | ||
62 | { | ||
63 | if (payload.Packaging == PackagingType.External) | ||
64 | { | ||
65 | var packageId = payload.ParentPackagePayloadRef; | ||
66 | var parentUrl = payload.ParentPackagePayloadRef == null ? null : this.PayloadsById[payload.ParentPackagePayloadRef].DownloadUrl; | ||
67 | var resolvedUrl = this.ResolveUrl(payload.DownloadUrl, parentUrl, packageId, payload.Id.Id, payload.Name); | ||
68 | if (!String.IsNullOrEmpty(resolvedUrl)) | ||
69 | { | ||
70 | payload.DownloadUrl = resolvedUrl; | ||
71 | } | ||
72 | } | ||
73 | else if (payload.Packaging == PackagingType.Embedded) | ||
74 | { | ||
75 | if (!String.IsNullOrEmpty(payload.DownloadUrl)) | ||
76 | { | ||
77 | this.Messaging.Write(WarningMessages.DownloadUrlNotSupportedForEmbeddedPayloads(payload.SourceLineNumbers, payload.Id.Id)); | ||
78 | } | ||
79 | } | ||
80 | } | ||
81 | } | ||
82 | |||
83 | private string ResolveUrl(string url, string fallbackUrl, string packageId, string payloadId, string fileName) | ||
84 | { | ||
85 | string resolvedUrl = null; | ||
86 | |||
87 | foreach (var extension in this.BackendExtensions) | ||
88 | { | ||
89 | resolvedUrl = extension.ResolveUrl(url, fallbackUrl, packageId, payloadId, fileName); | ||
90 | if (!String.IsNullOrEmpty(resolvedUrl)) | ||
91 | { | ||
92 | break; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | if (String.IsNullOrEmpty(resolvedUrl)) | ||
97 | { | ||
98 | // If a URL was not specified but there is a fallback URL that has a format specifier in it | ||
99 | // then use the fallback URL formatter for this URL. | ||
100 | if (String.IsNullOrEmpty(url) && !String.IsNullOrEmpty(fallbackUrl)) | ||
101 | { | ||
102 | var formattedFallbackUrl = String.Format(fallbackUrl, packageId, payloadId, fileName); | ||
103 | if (!String.Equals(fallbackUrl, formattedFallbackUrl, StringComparison.OrdinalIgnoreCase)) | ||
104 | { | ||
105 | url = fallbackUrl; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | if (!String.IsNullOrEmpty(url)) | ||
110 | { | ||
111 | var formattedUrl = String.Format(url, packageId, payloadId, fileName); | ||
112 | |||
113 | if (Uri.TryCreate(formattedUrl, UriKind.Absolute, out var canonicalUri)) | ||
114 | { | ||
115 | resolvedUrl = canonicalUri.AbsoluteUri; | ||
116 | } | ||
117 | else | ||
118 | { | ||
119 | resolvedUrl = null; | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | return resolvedUrl; | ||
125 | } | ||
126 | } | ||
127 | } | ||
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs index 128c7a5f..a8a12c28 100644 --- a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs +++ b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs | |||
@@ -18,10 +18,8 @@ namespace WixToolset.Core.Burn.Bundles | |||
18 | 18 | ||
19 | internal class CreateBurnManifestCommand | 19 | internal class CreateBurnManifestCommand |
20 | { | 20 | { |
21 | public CreateBurnManifestCommand(IMessaging messaging, IEnumerable<IBurnBackendBinderExtension> backendExtensions, string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleContainerSymbol> containers, WixChainSymbol chainSymbol, IEnumerable<PackageFacade> orderedPackages, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<WixBundlePayloadSymbol> uxPayloads, Dictionary<string, WixBundlePayloadSymbol> allPayloadsById, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, IEnumerable<ISearchFacade> orderedSearches, string intermediateFolder) | 21 | public CreateBurnManifestCommand(string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleContainerSymbol> containers, WixChainSymbol chainSymbol, IEnumerable<PackageFacade> orderedPackages, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<WixBundlePayloadSymbol> uxPayloads, Dictionary<string, WixBundlePayloadSymbol> allPayloadsById, Dictionary<string, Dictionary<string, WixBundlePayloadSymbol>> packagesPayloads, IEnumerable<ISearchFacade> orderedSearches, string intermediateFolder) |
22 | { | 22 | { |
23 | this.Messaging = messaging; | ||
24 | this.BackendExtensions = backendExtensions; | ||
25 | this.ExecutableName = executableName; | 23 | this.ExecutableName = executableName; |
26 | this.Section = section; | 24 | this.Section = section; |
27 | this.BundleSymbol = bundleSymbol; | 25 | this.BundleSymbol = bundleSymbol; |
@@ -38,10 +36,6 @@ namespace WixToolset.Core.Burn.Bundles | |||
38 | 36 | ||
39 | public string OutputPath { get; private set; } | 37 | public string OutputPath { get; private set; } |
40 | 38 | ||
41 | private IMessaging Messaging { get; } | ||
42 | |||
43 | private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; } | ||
44 | |||
45 | private string ExecutableName { get; } | 39 | private string ExecutableName { get; } |
46 | 40 | ||
47 | private IntermediateSection Section { get; } | 41 | private IntermediateSection Section { get; } |
@@ -657,12 +651,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
657 | 651 | ||
658 | if (ContainerType.Detached == container.Type) | 652 | if (ContainerType.Detached == container.Type) |
659 | { | 653 | { |
660 | string resolvedUrl = this.ResolveUrl(container.DownloadUrl, null, null, container.Id.Id, container.Name); | 654 | if (!String.IsNullOrEmpty(container.DownloadUrl)) |
661 | if (!String.IsNullOrEmpty(resolvedUrl)) | ||
662 | { | ||
663 | writer.WriteAttributeString("DownloadUrl", resolvedUrl); | ||
664 | } | ||
665 | else if (!String.IsNullOrEmpty(container.DownloadUrl)) | ||
666 | { | 655 | { |
667 | writer.WriteAttributeString("DownloadUrl", container.DownloadUrl); | 656 | writer.WriteAttributeString("DownloadUrl", container.DownloadUrl); |
668 | } | 657 | } |
@@ -671,11 +660,6 @@ namespace WixToolset.Core.Burn.Bundles | |||
671 | } | 660 | } |
672 | else if (ContainerType.Attached == container.Type) | 661 | else if (ContainerType.Attached == container.Type) |
673 | { | 662 | { |
674 | if (!String.IsNullOrEmpty(container.DownloadUrl)) | ||
675 | { | ||
676 | this.Messaging.Write(WarningMessages.DownloadUrlNotSupportedForAttachedContainers(container.SourceLineNumbers, container.Id.Id)); | ||
677 | } | ||
678 | |||
679 | writer.WriteAttributeString("FilePath", executableName); // attached containers use the name of the bundle since they are attached to the executable. | 663 | writer.WriteAttributeString("FilePath", executableName); // attached containers use the name of the bundle since they are attached to the executable. |
680 | writer.WriteAttributeString("AttachedIndex", container.AttachedContainerIndex.Value.ToString(CultureInfo.InvariantCulture)); | 664 | writer.WriteAttributeString("AttachedIndex", container.AttachedContainerIndex.Value.ToString(CultureInfo.InvariantCulture)); |
681 | writer.WriteAttributeString("Attached", "yes"); | 665 | writer.WriteAttributeString("Attached", "yes"); |
@@ -700,11 +684,6 @@ namespace WixToolset.Core.Burn.Bundles | |||
700 | switch (payload.Packaging) | 684 | switch (payload.Packaging) |
701 | { | 685 | { |
702 | case PackagingType.Embedded: // this means it's in a container. | 686 | case PackagingType.Embedded: // this means it's in a container. |
703 | if (!String.IsNullOrEmpty(payload.DownloadUrl)) | ||
704 | { | ||
705 | this.Messaging.Write(WarningMessages.DownloadUrlNotSupportedForEmbeddedPayloads(payload.SourceLineNumbers, payload.Id.Id)); | ||
706 | } | ||
707 | |||
708 | writer.WriteAttributeString("Packaging", "embedded"); | 687 | writer.WriteAttributeString("Packaging", "embedded"); |
709 | writer.WriteAttributeString("SourcePath", payload.EmbeddedId); | 688 | writer.WriteAttributeString("SourcePath", payload.EmbeddedId); |
710 | 689 | ||
@@ -715,14 +694,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
715 | break; | 694 | break; |
716 | 695 | ||
717 | case PackagingType.External: | 696 | case PackagingType.External: |
718 | var packageId = payload.ParentPackagePayloadRef; | 697 | if (!String.IsNullOrEmpty(payload.DownloadUrl)) |
719 | var parentUrl = payload.ParentPackagePayloadRef == null ? null : allPayloads[payload.ParentPackagePayloadRef].DownloadUrl; | ||
720 | var resolvedUrl = this.ResolveUrl(payload.DownloadUrl, parentUrl, packageId, payload.Id.Id, payload.Name); | ||
721 | if (!String.IsNullOrEmpty(resolvedUrl)) | ||
722 | { | ||
723 | writer.WriteAttributeString("DownloadUrl", resolvedUrl); | ||
724 | } | ||
725 | else if (!String.IsNullOrEmpty(payload.DownloadUrl)) | ||
726 | { | 698 | { |
727 | writer.WriteAttributeString("DownloadUrl", payload.DownloadUrl); | 699 | writer.WriteAttributeString("DownloadUrl", payload.DownloadUrl); |
728 | } | 700 | } |
@@ -732,20 +704,5 @@ namespace WixToolset.Core.Burn.Bundles | |||
732 | break; | 704 | break; |
733 | } | 705 | } |
734 | } | 706 | } |
735 | |||
736 | private string ResolveUrl(string url, string fallbackUrl, string packageId, string payloadId, string fileName) | ||
737 | { | ||
738 | string resolved = null; | ||
739 | foreach (var extension in this.BackendExtensions) | ||
740 | { | ||
741 | resolved = extension.ResolveUrl(url, fallbackUrl, packageId, payloadId, fileName); | ||
742 | if (!String.IsNullOrEmpty(resolved)) | ||
743 | { | ||
744 | break; | ||
745 | } | ||
746 | } | ||
747 | |||
748 | return resolved; | ||
749 | } | ||
750 | } | 707 | } |
751 | } | 708 | } |
diff --git a/src/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs b/src/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs index 9bd33eac..e9e59b9e 100644 --- a/src/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs +++ b/src/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs | |||
@@ -143,7 +143,7 @@ namespace WixToolsetTest.CoreIntegration | |||
143 | } | 143 | } |
144 | } | 144 | } |
145 | 145 | ||
146 | [Fact(Skip = "Test demonstrates failure")] | 146 | [Fact] |
147 | public void ReplacesDownloadUrlPlaceholders() | 147 | public void ReplacesDownloadUrlPlaceholders() |
148 | { | 148 | { |
149 | var folder = TestData.Get(@"TestData"); | 149 | var folder = TestData.Get(@"TestData"); |