From 45d1c054b2bf1d4df33c98c5a3de88417c9cf1bd Mon Sep 17 00:00:00 2001
From: Pavel Krymets <pavel@krymets.com>
Date: Thu, 20 Dec 2018 15:29:49 -0800
Subject: [PATCH] Add IServerAddressesFeature support (#4685)

---
 src/Servers/IIS/IISIntegration.NoV1.sln       |   8 +-
 src/Servers/IIS/build/launchSettings.json     |   2 +-
 .../IIS/samples/NativeIISSample/Startup.cs    |  10 +
 .../AspNetCore/ApplicationFactory.h           |   5 +-
 .../CommonLib/BindingInformation.h            | 133 +++++++++++++
 .../CommonLib/CommonLib.vcxproj               |   1 +
 .../CommonLib/ConfigurationSection.cpp        |  22 +++
 .../CommonLib/ConfigurationSection.h          |   7 +-
 .../WebConfigConfigurationSection.cpp         |  39 ++--
 .../CommonLib/WebConfigConfigurationSection.h |   3 +-
 .../InProcessOptions.cpp                      |  10 +-
 .../InProcessOptions.h                        |  11 +-
 .../InProcessRequestHandler/dllmain.cpp       |   6 +-
 .../inprocessapplication.cpp                  |   4 +-
 .../inprocessapplication.h                    |   1 +
 .../managedexports.cpp                        |   3 +
 .../OutOfProcessRequestHandler/dllmain.cpp    |   3 +-
 .../processmanager.cpp                        |   3 +-
 .../serverprocess.cpp                         |   5 +-
 .../serverprocess.h                           |  16 +-
 .../environmentvariablehash.h                 |   1 +
 .../environmentvariablehelpers.h              |  22 +++
 .../requesthandler_config.cpp                 |  18 +-
 .../RequestHandlerLib/requesthandler_config.h |  11 +-
 .../Core/IISConfigurationData.cs              |   2 +
 .../Core/IISHttpServer.cs                     |  10 +-
 .../Core/IISServerSetupFilter.cs              |   4 +-
 .../Core/ServerAddressesFeature.cs            |  15 ++
 .../IISServerOptions.cs                       |   2 +
 .../WebHostBuilderIISExtensions.cs            |   5 +-
 .../test/Common.FunctionalTests/HttpsTests.cs | 177 ++++++++++++++++++
 .../Inprocess/FeatureCollectionTests.cs       |   9 +
 .../MultiApplicationTests.cs                  |  12 +-
 .../Utilities/Helpers.cs                      |  25 +++
 .../CommonLibTests/BindingInformationTest.cpp |  29 +++
 .../CommonLibTests/CommonLibTests.vcxproj     |   6 +-
 .../IISExpress.FunctionalTests/HttpsTests.cs  |  60 ------
 .../testassets/OutOfProcessWebSite/Startup.cs |  14 +-
 .../shared/SharedStartup/Startup.shared.cs    |   8 +
 39 files changed, 585 insertions(+), 137 deletions(-)
 create mode 100644 src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/BindingInformation.h
 create mode 100644 src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/ServerAddressesFeature.cs
 create mode 100644 src/Servers/IIS/test/Common.FunctionalTests/HttpsTests.cs
 create mode 100644 src/Servers/IIS/test/CommonLibTests/BindingInformationTest.cpp
 delete mode 100644 src/Servers/IIS/test/IISExpress.FunctionalTests/HttpsTests.cs

diff --git a/src/Servers/IIS/IISIntegration.NoV1.sln b/src/Servers/IIS/IISIntegration.NoV1.sln
index 883c9e7bb6e..11c3b8fa772 100644
--- a/src/Servers/IIS/IISIntegration.NoV1.sln
+++ b/src/Servers/IIS/IISIntegration.NoV1.sln
@@ -53,7 +53,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IISExpress.FunctionalTests"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeIISSample", "samples\NativeIISSample\NativeIISSample.csproj", "{9BC4AFCB-325D-4C81-8228-8CF301CE2F97}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InProcessWebSite", "test\WebSites\InProcessWebSite\InProcessWebSite.csproj", "{679FA2A2-898B-4320-884E-C2D294A97CE1}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InProcessWebSite", "test\testassets\InProcessWebSite\InProcessWebSite.csproj", "{679FA2A2-898B-4320-884E-C2D294A97CE1}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.IIS", "src\Microsoft.AspNetCore.Server.IIS\Microsoft.AspNetCore.Server.IIS.csproj", "{46A8612B-418B-4D70-B3A7-A21DD0627473}"
 	ProjectSection(ProjectDependencies) = postProject
@@ -63,7 +63,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server
 		{D57EA297-6DC2-4BC0-8C91-334863327863} = {D57EA297-6DC2-4BC0-8C91-334863327863}
 	EndProjectSection
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StressTestWebSite", "test\WebSites\StressTestWebSite\StressTestWebSite.csproj", "{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StressTestWebSite", "test\testassets\StressTestWebSite\StressTestWebSite.csproj", "{13FD8F12-FFBE-4D01-B4AC-444F2994B04F}"
 	ProjectSection(ProjectDependencies) = postProject
 		{46A8612B-418B-4D70-B3A7-A21DD0627473} = {46A8612B-418B-4D70-B3A7-A21DD0627473}
 	EndProjectSection
@@ -82,7 +82,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonLib", "src\AspNetCore
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IISLib", "src\AspNetCoreModuleV2\IISLib\IISLib.vcxproj", "{09D9D1D6-2951-4E14-BC35-76A23CF9391A}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OutOfProcessWebSite", "test\WebSites\OutOfProcessWebSite\OutOfProcessWebSite.csproj", "{42E60F88-E23F-417A-8143-0CCEC05E1D02}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OutOfProcessWebSite", "test\testassets\OutOfProcessWebSite\OutOfProcessWebSite.csproj", "{42E60F88-E23F-417A-8143-0CCEC05E1D02}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{622D35C9-627B-466E-8D15-752968CC79AF}"
 EndProject
@@ -114,7 +114,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.BackwardsCompatibility.
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IIS.ForwardsCompatibility.FunctionalTests", "test\IIS.ForwardsCompatibility.FunctionalTests\IIS.ForwardsCompatibility.FunctionalTests.csproj", "{D1EA5D99-28FD-4197-81DE-17098846B38B}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InProcessWebSite", "test\WebSites\InProcessForwardsCompatWebSite\InProcessWebSite.csproj", "{BBBC85B2-5D7A-4D09-90B1-8DBCC9059493}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InProcessWebSite", "test\testassets\InProcessForwardsCompatWebSite\InProcessWebSite.csproj", "{BBBC85B2-5D7A-4D09-90B1-8DBCC9059493}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/src/Servers/IIS/build/launchSettings.json b/src/Servers/IIS/build/launchSettings.json
index 246b7a0b47d..739ae702f59 100644
--- a/src/Servers/IIS/build/launchSettings.json
+++ b/src/Servers/IIS/build/launchSettings.json
@@ -16,7 +16,7 @@
         "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
         "ANCM_PATH": "$(AspNetCoreModuleV1ShimDll)",
         "ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)",
-        "ANCM_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)",
+        "ASPNETCORE_MODULE_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)",
         "LAUNCHER_ARGS": "$(TargetPath)",
         "ASPNETCORE_ENVIRONMENT": "Development",
         "LAUNCHER_PATH": "$(DotNetPath)",
diff --git a/src/Servers/IIS/samples/NativeIISSample/Startup.cs b/src/Servers/IIS/samples/NativeIISSample/Startup.cs
index 2b18ff895c2..f6a6faf6479 100644
--- a/src/Servers/IIS/samples/NativeIISSample/Startup.cs
+++ b/src/Servers/IIS/samples/NativeIISSample/Startup.cs
@@ -6,9 +6,12 @@ using System.Linq;
 using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.Hosting.Server.Features;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http.Features;
 using Microsoft.AspNetCore.Server.IIS;
+using Microsoft.Extensions.DependencyInjection;
 
 namespace NativeIISSample
 {
@@ -89,6 +92,13 @@ namespace NativeIISSample
                 {
                     await context.Response.WriteAsync("Websocket feature is disabled.");
                 }
+
+                await context.Response.WriteAsync(Environment.NewLine);
+                var addresses = context.RequestServices.GetService<IServer>().Features.Get<IServerAddressesFeature>();
+                foreach (var key in addresses.Addresses)
+                {
+                    await context.Response.WriteAsync(key + Environment.NewLine);
+                }
             });
         }
 
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h b/src/Servers/IIS/src/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h
index ed9733b68a5..23c5a67d409 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h
@@ -36,10 +36,11 @@ public:
     {
         // m_location.data() is const ptr copy to local to get mutable pointer
         auto location = m_location;
-        std::array<APPLICATION_PARAMETER, 2> parameters {
+        std::array<APPLICATION_PARAMETER, 3> parameters {
             {
                 {"InProcessExeLocation", location.data()},
-                {"TraceContext", pHttpContext->GetTraceContext()}
+                {"TraceContext", pHttpContext->GetTraceContext()},
+                {"Site", pHttpContext->GetSite()}
             }
         };
 
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/BindingInformation.h b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/BindingInformation.h
new file mode 100644
index 00000000000..d1813b842fa
--- /dev/null
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/BindingInformation.h
@@ -0,0 +1,133 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+#pragma once
+
+#include <string>
+#include "ConfigurationSource.h"
+#include "StringHelpers.h"
+#include "WebConfigConfigurationSource.h"
+
+#define CS_SITE_SECTION                         L"system.applicationHost/sites"
+#define CS_SITE_NAME                            L"name"
+#define CS_SITE_BINDINGS                        L"bindings"
+#define CS_SITE_BINDING_INFORMATION             L"bindingInformation"
+#define CS_SITE_BINDING_INFORMATION_ALL_HOSTS   L"*"
+#define CS_SITE_BINDING_PROTOCOL                L"protocol"
+#define CS_SITE_BINDING_PROTOCOL_HTTPS          L"https"
+#define CS_SITE_BINDING_INFORMATION_DELIMITER   L':'
+
+class BindingInformation
+{
+public:
+    BindingInformation(std::wstring protocol, std::wstring host, std::wstring port)
+    {
+        m_protocol = protocol;
+        m_host = host;
+        m_port = port;
+    }
+
+    BindingInformation(std::wstring protocol, std::wstring bindingInformation)
+    {
+        // Expected format:
+        // IP:PORT:HOST
+        // where IP or HOST can be empty
+
+        m_protocol = protocol;
+
+        const auto portStart = bindingInformation.find(CS_SITE_BINDING_INFORMATION_DELIMITER) + 1;
+        const auto lastColon = bindingInformation.find_last_of(CS_SITE_BINDING_INFORMATION_DELIMITER);
+        auto const hostStart = lastColon + 1;
+        m_host = bindingInformation.substr(hostStart, bindingInformation.length() - hostStart);
+        if (m_host.length() == 0)
+        {
+            m_host = CS_SITE_BINDING_INFORMATION_ALL_HOSTS;
+        }
+        m_port = bindingInformation.substr(portStart, lastColon - portStart);
+    }
+
+    std::wstring& QueryProtocol()
+    {
+        return m_protocol;
+    }
+
+    std::wstring& QueryPort()
+    {
+        return m_port;
+    }
+
+    std::wstring& QueryHost()
+    {
+        return m_host;
+    }
+
+    static
+    std::vector<BindingInformation>
+    Load(const ConfigurationSource &configurationSource, const IHttpSite& pSite)
+    {
+        std::vector<BindingInformation> items;
+
+        const std::wstring runningSiteName = pSite.GetSiteName();
+
+        auto const siteSection = configurationSource.GetRequiredSection(CS_SITE_SECTION);
+        auto sites = siteSection->GetCollection();
+        for (const auto& site: sites)
+        {
+            auto siteName = site->GetRequiredString(CS_SITE_NAME);
+            if (equals_ignore_case(runningSiteName, siteName))
+            {
+                auto bindings = site->GetRequiredSection(CS_SITE_BINDINGS)->GetCollection();
+                for (const auto& binding : bindings)
+                {
+                    items.emplace_back(
+                        binding->GetRequiredString(CS_SITE_BINDING_PROTOCOL),
+                        binding->GetRequiredString(CS_SITE_BINDING_INFORMATION)
+                        );
+                }
+            }
+        }
+
+        return items;
+    }
+
+    static
+    std::wstring Format(const std::vector<BindingInformation> & bindings, const std::wstring & basePath)
+    {
+        std::wstring result;
+
+        for (auto binding : bindings)
+        {
+            result += binding.QueryProtocol() + L"://" + binding.QueryHost() + L":" + binding.QueryPort() + basePath + L";";
+        }
+
+        return result;
+    }
+
+    static
+    std::wstring GetHttpsPort(const std::vector<BindingInformation> & bindings)
+    {
+        std::wstring selectedPort;
+        for (auto binding : bindings)
+        {
+            if (equals_ignore_case(binding.QueryProtocol(), CS_SITE_BINDING_PROTOCOL_HTTPS))
+            {
+                const auto bindingPort = binding.QueryPort();
+                if (selectedPort.empty())
+                {
+                    selectedPort = binding.QueryPort();
+                }
+                else if (selectedPort != bindingPort)
+                {
+                    // If there are multiple endpoints configured return empty port
+                    return L"";
+                }
+            }
+        }
+        return selectedPort;
+    }
+
+private:
+    std::wstring                   m_protocol;
+    std::wstring                   m_port;
+    std::wstring                   m_host;
+};
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj
index 2386dfc6ee6..066b4336760 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj
@@ -200,6 +200,7 @@
   <ItemGroup>
     <ClInclude Include="application.h" />
     <ClInclude Include="baseoutputmanager.h" />
+    <ClInclude Include="BindingInformation.h" />
     <ClInclude Include="ConfigurationSection.h" />
     <ClInclude Include="ConfigurationSource.h" />
     <ClInclude Include="config_utility.h" />
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.cpp
index 11e790cff7b..3d054244905 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.cpp
@@ -51,6 +51,28 @@ void ConfigurationSection::ThrowRequiredException(const std::wstring& name)
     throw ConfigurationLoadException(format(L"Attribute '%s' is required.", name.c_str()));
 }
 
+std::vector<std::pair<std::wstring, std::wstring>> ConfigurationSection::GetKeyValuePairs(const std::wstring& name) const
+{
+    std::vector<std::pair<std::wstring, std::wstring>> pairs;
+
+    for (auto const element : GetRequiredSection(name)->GetCollection())
+    {
+        pairs.emplace_back(element->GetRequiredString(CS_ASPNETCORE_COLLECTION_ITEM_NAME),
+                           element->GetString(CS_ASPNETCORE_COLLECTION_ITEM_VALUE).value_or(L""));
+    }
+    return pairs;
+}
+
+std::shared_ptr<ConfigurationSection> ConfigurationSection::GetRequiredSection(const std::wstring& name) const
+{
+    auto section = GetSection(name);
+    if (!section)
+    {
+        throw ConfigurationLoadException(format(L"Unable to get required configuration section '%s'. Possible reason is web.config authoring error.", name.c_str()));
+    }
+    return section.value();
+}
+
 std::optional<std::wstring> find_element(const std::vector<std::pair<std::wstring, std::wstring>>& pairs, const std::wstring& name)
 {
     const auto iter = std::find_if(
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.h b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.h
index 9b6fd2cb495..6ca4e475e35 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.h
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.h
@@ -37,12 +37,17 @@ public:
     virtual std::optional<DWORD> GetLong(const std::wstring& name) const = 0;
     virtual std::optional<DWORD> GetTimespan(const std::wstring& name) const = 0;
 
+    virtual std::optional<std::shared_ptr<ConfigurationSection>> GetSection(const std::wstring& name) const = 0;
+    virtual std::vector<std::shared_ptr<ConfigurationSection>> GetCollection() const = 0;
+
     std::wstring GetRequiredString(const std::wstring& name) const;
     bool GetRequiredBool(const std::wstring& name)  const;
     DWORD GetRequiredLong(const std::wstring& name)  const;
     DWORD GetRequiredTimespan(const std::wstring& name)  const;
 
-    virtual std::vector<std::pair<std::wstring, std::wstring>> GetKeyValuePairs(const std::wstring& name) const = 0;
+    virtual std::vector<std::pair<std::wstring, std::wstring>> GetKeyValuePairs(const std::wstring& name) const;
+
+    virtual std::shared_ptr<ConfigurationSection> GetRequiredSection(const std::wstring & name) const;
 
 protected:
     static void ThrowRequiredException(const std::wstring& name);
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.cpp
index 7003442f01d..71d53e187c5 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.cpp
@@ -50,43 +50,38 @@ std::optional<DWORD> WebConfigConfigurationSection::GetTimespan(const std::wstri
     return std::make_optional(static_cast<DWORD>(result / 10000ull));
 }
 
-std::vector<std::pair<std::wstring, std::wstring>> WebConfigConfigurationSection::GetKeyValuePairs(const std::wstring& name) const
+std::optional<std::shared_ptr<ConfigurationSection>> WebConfigConfigurationSection::GetSection(const std::wstring& name) const
 {
-    std::vector<std::pair<std::wstring, std::wstring>> pairs;
-    HRESULT findElementResult;
-    CComPtr<IAppHostElement>           element = nullptr;
-    CComPtr<IAppHostElementCollection> elementCollection = nullptr;
-    CComPtr<IAppHostElement>           collectionEntry = nullptr;
-    ENUM_INDEX                         index{};
+    CComPtr<IAppHostElement> element = nullptr;
 
     if (FAILED_LOG(GetElementChildByName(m_element, name.c_str(), &element)))
     {
-        return pairs;
+        return std::nullopt;
     }
 
-    THROW_IF_FAILED(element->get_Collection(&elementCollection));
+    return std::make_optional(std::make_shared<WebConfigConfigurationSection>(element.Detach()));
+}
+
+std::vector<std::shared_ptr<ConfigurationSection>> WebConfigConfigurationSection::GetCollection() const
+{
+    std::vector<std::shared_ptr<ConfigurationSection>> elements;
+    HRESULT findElementResult;
+    CComPtr<IAppHostElementCollection> elementCollection = nullptr;
+    CComPtr<IAppHostElement>           collectionEntry = nullptr;
+    ENUM_INDEX                         index{};
+
+    THROW_IF_FAILED(m_element->get_Collection(&elementCollection));
     THROW_IF_FAILED(findElementResult = FindFirstElement(elementCollection, &index, &collectionEntry));
 
     while (findElementResult != S_FALSE)
     {
-        CComBSTR strHandlerName;
-        if (LOG_IF_FAILED(GetElementStringProperty(collectionEntry, CS_ASPNETCORE_COLLECTION_ITEM_NAME, &strHandlerName.m_str)))
-        {
-            ThrowRequiredException(CS_ASPNETCORE_COLLECTION_ITEM_NAME);
-        }
-
-        CComBSTR strHandlerValue;
-        if (LOG_IF_FAILED(GetElementStringProperty(collectionEntry, CS_ASPNETCORE_COLLECTION_ITEM_VALUE, &strHandlerValue.m_str)))
-        {
-            ThrowRequiredException(CS_ASPNETCORE_COLLECTION_ITEM_VALUE);
-        }
 
-        pairs.emplace_back(strHandlerName, strHandlerValue);
+        elements.emplace_back(std::make_shared<WebConfigConfigurationSection>(collectionEntry.Detach()));
 
         collectionEntry.Release();
 
         THROW_IF_FAILED(findElementResult = FindNextElement(elementCollection, &index, &collectionEntry));
     }
 
-    return pairs;
+    return elements;
 }
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.h b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.h
index b206c020494..13a7415c1d2 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.h
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.h
@@ -19,7 +19,8 @@ public:
     std::optional<bool> GetBool(const std::wstring& name) const override;
     std::optional<DWORD> GetLong(const std::wstring& name) const override;
     std::optional<DWORD> GetTimespan(const std::wstring& name) const override;
-    std::vector<std::pair<std::wstring, std::wstring>> GetKeyValuePairs(const std::wstring& name) const override;
+    std::optional<std::shared_ptr<ConfigurationSection>> GetSection(const std::wstring& name) const override;
+    std::vector<std::shared_ptr<ConfigurationSection>> GetCollection() const override;
 
 private:
     CComPtr<IAppHostElement> m_element;
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.cpp
index a179884242e..48e401b2b8f 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.cpp
@@ -7,13 +7,14 @@
 
 HRESULT InProcessOptions::Create(
     IHttpServer& pServer,
+    IHttpSite* site,
     IHttpApplication& pHttpApplication,
     std::unique_ptr<InProcessOptions>& options)
 {
     try
     {
         const WebConfigConfigurationSource configurationSource(pServer.GetAdminManager(), pHttpApplication);
-        options = std::make_unique<InProcessOptions>(configurationSource);
+        options = std::make_unique<InProcessOptions>(configurationSource, site);
     }
     catch (InvalidOperationException& ex)
     {
@@ -38,7 +39,7 @@ HRESULT InProcessOptions::Create(
     return S_OK;
 }
 
-InProcessOptions::InProcessOptions(const ConfigurationSource &configurationSource) :
+InProcessOptions::InProcessOptions(const ConfigurationSource &configurationSource, IHttpSite* pSite) :
     m_fStdoutLogEnabled(false),
     m_fWindowsAuthEnabled(false),
     m_fBasicAuthEnabled(false),
@@ -68,4 +69,9 @@ InProcessOptions::InProcessOptions(const ConfigurationSource &configurationSourc
 
     const auto anonAuthSection = configurationSource.GetSection(CS_ANONYMOUS_AUTHENTICATION_SECTION);
     m_fAnonymousAuthEnabled = anonAuthSection && anonAuthSection->GetBool(CS_ENABLED).value_or(false);
+
+    if (pSite != nullptr)
+    {
+        m_bindingInformation = BindingInformation::Load(configurationSource, *pSite);
+    }
 }
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.h b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.h
index dbba6408f48..3068936eca2 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.h
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.h
@@ -4,6 +4,7 @@
 #pragma once
 
 #include <string>
+#include "BindingInformation.h"
 #include "ConfigurationSource.h"
 #include "WebConfigConfigurationSource.h"
 
@@ -92,11 +93,18 @@ public:
         return m_environmentVariables;
     }
 
-    InProcessOptions(const ConfigurationSource &configurationSource);
+    const std::vector<BindingInformation>&
+    QueryBindings() const
+    {
+        return m_bindingInformation;
+    }
+
+    InProcessOptions(const ConfigurationSource &configurationSource, IHttpSite* pSite);
 
     static
     HRESULT InProcessOptions::Create(
         IHttpServer& pServer,
+        IHttpSite* site,
         IHttpApplication& pHttpApplication,
         std::unique_ptr<InProcessOptions>& options);
 
@@ -113,6 +121,7 @@ private:
     DWORD                          m_dwStartupTimeLimitInMS;
     DWORD                          m_dwShutdownTimeLimitInMS;
     std::vector<std::pair<std::wstring, std::wstring>> m_environmentVariables;
+    std::vector<BindingInformation> m_bindingInformation;
 
 protected:
     InProcessOptions() = default;
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp
index eb84da28699..948a08950d2 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp
@@ -100,6 +100,8 @@ CreateApplication(
 )
 {
     TraceContextScope traceScope(FindParameter<IHttpTraceContext*>("TraceContext", pParameters, nParameters));
+    const auto pSite = FindParameter<IHttpSite*>("Site", pParameters, nParameters);
+
     try
     {
         HRESULT hr = S_OK;
@@ -117,14 +119,14 @@ CreateApplication(
         g_fInProcessApplicationCreated = true;
 
         std::unique_ptr<IN_PROCESS_APPLICATION, IAPPLICATION_DELETER> inProcessApplication;
-        if (!FAILED_LOG(hr = IN_PROCESS_APPLICATION::Start(*pServer, *pHttpApplication, pParameters, nParameters, inProcessApplication)))
+        if (!FAILED_LOG(hr = IN_PROCESS_APPLICATION::Start(*pServer, pSite, *pHttpApplication, pParameters, nParameters, inProcessApplication)))
         {
             *ppApplication = inProcessApplication.release();
         }
         else
         {
             std::unique_ptr<InProcessOptions> options;
-            THROW_IF_FAILED(InProcessOptions::Create(*pServer, *pHttpApplication, options));
+            THROW_IF_FAILED(InProcessOptions::Create(*pServer, pSite, *pHttpApplication, options));
             // Set the currently running application to a fake application that returns startup exceptions.
             auto pErrorApplication = std::make_unique<StartupExceptionApplication>(*pServer, *pHttpApplication, g_hServerModule, options->QueryDisableStartUpErrorPage(), hr);
 
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp
index 09f4dc3e5e3..4563965d73e 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp
@@ -344,6 +344,7 @@ void IN_PROCESS_APPLICATION::QueueStop()
 
 HRESULT IN_PROCESS_APPLICATION::Start(
     IHttpServer& pServer,
+    IHttpSite* pSite,
     IHttpApplication& pHttpApplication,
     APPLICATION_PARAMETER* pParameters,
     DWORD nParameters,
@@ -352,7 +353,7 @@ HRESULT IN_PROCESS_APPLICATION::Start(
     try
     {
         std::unique_ptr<InProcessOptions> options;
-        THROW_IF_FAILED(InProcessOptions::Create(pServer, pHttpApplication, options));
+        THROW_IF_FAILED(InProcessOptions::Create(pServer, pSite, pHttpApplication, options));
         application = std::unique_ptr<IN_PROCESS_APPLICATION, IAPPLICATION_DELETER>(
             new IN_PROCESS_APPLICATION(pServer, pHttpApplication, std::move(options), pParameters, nParameters));
         THROW_IF_FAILED(application->LoadManagedApplication());
@@ -444,6 +445,7 @@ IN_PROCESS_APPLICATION::SetEnvironmentVariablesOnWorkerProcess()
         m_pConfig->QueryBasicAuthEnabled(),
         m_pConfig->QueryAnonymousAuthEnabled(),
         QueryApplicationPhysicalPath().c_str(),
+        nullptr, /* pHttpsPort */
         &pHashTable));
 
     table.reset(pHashTable);
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h
index caf16193d66..1086c8182ed 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h
@@ -104,6 +104,7 @@ public:
     static
     HRESULT Start(
         IHttpServer& pServer,
+        IHttpSite* pSite,
         IHttpApplication& pHttpApplication,
         APPLICATION_PARAMETER* pParameters,
         DWORD nParameters,
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp
index 6085f658774..78b61f44463 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp
@@ -185,6 +185,7 @@ struct IISConfigurationData
     BOOL fWindowsAuthEnabled;
     BOOL fBasicAuthEnabled;
     BOOL fAnonymousAuthEnable;
+    BSTR pwzBindings;
 };
 
 EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
@@ -208,6 +209,8 @@ http_get_application_properties(
     pIISCofigurationData->fBasicAuthEnabled = pConfiguration.QueryBasicAuthEnabled();
     pIISCofigurationData->fAnonymousAuthEnable = pConfiguration.QueryAnonymousAuthEnabled();
 
+    auto const serverAddresses = BindingInformation::Format(pConfiguration.QueryBindings(), pInProcessApplication->QueryApplicationVirtualPath());
+    pIISCofigurationData->pwzBindings = SysAllocString(serverAddresses.c_str());
     return S_OK;
 }
 
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp
index 981e3acd366..62d33ca5e0e 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp
@@ -251,11 +251,12 @@ CreateApplication(
 )
 {
     TraceContextScope traceScope(FindParameter<IHttpTraceContext*>("TraceContext", pParameters, nParameters));
+    auto pSite = FindParameter<IHttpSite*>("Site", pParameters, nParameters);
 
     InitializeGlobalConfiguration(pServer);
 
     REQUESTHANDLER_CONFIG *pConfig = nullptr;
-    RETURN_IF_FAILED(REQUESTHANDLER_CONFIG::CreateRequestHandlerConfig(pServer, pHttpApplication, &pConfig));
+    RETURN_IF_FAILED(REQUESTHANDLER_CONFIG::CreateRequestHandlerConfig(pServer, pSite, pHttpApplication, &pConfig));
     std::unique_ptr<REQUESTHANDLER_CONFIG> pRequestHandlerConfig(pConfig);
 
     RETURN_IF_FAILED(EnsureOutOfProcessInitializtion(pHttpApplication));
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp
index 71d106fb778..80e70a187c2 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp
@@ -162,7 +162,8 @@ PROCESS_MANAGER::GetProcess(
                     pConfig->QueryStdoutLogFile(),
                     pConfig->QueryApplicationPhysicalPath(),   // physical path
                     pConfig->QueryApplicationPath(),           // app path
-                    pConfig->QueryApplicationVirtualPath()     // App relative virtual path
+                    pConfig->QueryApplicationVirtualPath(),     // App relative virtual path,
+                    pConfig->QueryBindings()
             ));
             RETURN_IF_FAILED(pSelectedServerProcess->StartProcess());
         }
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp
index 9b549e7bf6c..5446f977800 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp
@@ -30,7 +30,8 @@ SERVER_PROCESS::Initialize(
     STRU                  *pstruStdoutLogFile,
     STRU                  *pszAppPhysicalPath,
     STRU                  *pszAppPath,
-    STRU                  *pszAppVirtualPath
+    STRU                  *pszAppVirtualPath,
+    STRU                  *pszHttpsPort
 )
 {
     HRESULT hr = S_OK;
@@ -52,6 +53,7 @@ SERVER_PROCESS::Initialize(
         FAILED_LOG(hr = m_struAppFullPath.Copy(*pszAppPath))||
         FAILED_LOG(hr = m_struAppVirtualPath.Copy(*pszAppVirtualPath))||
         FAILED_LOG(hr = m_Arguments.Copy(*pszArguments)) ||
+        FAILED_LOG(hr = m_struHttpsPort.Copy(*pszHttpsPort)) ||
         FAILED_LOG(hr = SetupJobObject()))
     {
         goto Finished;
@@ -786,6 +788,7 @@ SERVER_PROCESS::StartProcess(
             m_fBasicAuthEnabled,
             m_fAnonymousAuthEnabled,
             m_struAppFullPath.QueryStr(),
+            m_struHttpsPort.QueryStr(),
             &pHashTable)))
         {
             pStrStage = L"InitEnvironmentVariablesTable";
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h b/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h
index 3073835e05f..028acd6e48e 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h
@@ -39,7 +39,8 @@ public:
         _In_ STRU                 *pstruStdoutLogFile,
         _In_ STRU                 *pszAppPhysicalPath,
         _In_ STRU                 *pszAppPath,
-        _In_ STRU                 *pszAppVirtualPath
+        _In_ STRU                 *pszAppVirtualPath,
+        _In_ STRU                 *pszHttpsPort
         );
 
     HRESULT
@@ -98,7 +99,7 @@ public:
         }
     }
 
-    virtual 
+    virtual
     ~SERVER_PROCESS();
 
     static
@@ -129,7 +130,7 @@ public:
     };
 
     VOID
-    SendSignal( 
+    SendSignal(
         VOID
     );
 
@@ -142,7 +143,7 @@ private:
        VOID
     );
 
-    BOOL 
+    BOOL
     IsDebuggerIsAttached(
         VOID
     );
@@ -164,13 +165,13 @@ private:
         _Out_ BOOL      * pfReady
     );
 
-    HRESULT 
+    HRESULT
     RegisterProcessWait(
         _In_ PHANDLE phWaitHandle,
         _In_ HANDLE  hProcessToWaitOn
     );
 
-    HRESULT 
+    HRESULT
     GetChildProcessHandles(
         VOID
     );
@@ -252,6 +253,7 @@ private:
     STRU                    m_struAppVirtualPath;  // e.g., '/' for site
     STRU                    m_struAppFullPath;     // e.g.,  /LM/W3SVC/4/ROOT/Inproc
     STRU                    m_struPhysicalPath;    // e.g., c:/test/mysite
+    STRU                    m_struHttpsPort;     // e.g.,  /LM/W3SVC/4/ROOT/Inproc
     STRU                    m_struPort;
     STRU                    m_struCommandLine;
 
@@ -281,7 +283,7 @@ private:
     HANDLE                  m_hProcessWaitHandle;
     HANDLE                  m_hShutdownHandle;
     //
-    // m_hChildProcessHandle is the handle to process created by 
+    // m_hChildProcessHandle is the handle to process created by
     // m_hProcessHandle process if it does.
     //
     HANDLE                  m_hChildProcessHandles[MAX_ACTIVE_CHILD_PROCESSES];
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehash.h b/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehash.h
index eb7c9ad5444..be1276fd484 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehash.h
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehash.h
@@ -9,6 +9,7 @@
 #define ASPNETCORE_IIS_AUTH_ENV_STR                 L"ASPNETCORE_IIS_HTTPAUTH="
 #define ASPNETCORE_IIS_WEBSOCKETS_SUPPORTED_ENV_STR L"ASPNETCORE_IIS_WEBSOCKETS_SUPPORTED="
 #define ASPNETCORE_IIS_PHYSICAL_PATH_ENV_STR        L"ASPNETCORE_IIS_PHYSICAL_PATH="
+#define ASPNETCORE_HTTPS_PORT_ENV_STR               L"ASPNETCORE_HTTPS_PORT="
 #define ASPNETCORE_IIS_AUTH_WINDOWS                 L"windows;"
 #define ASPNETCORE_IIS_AUTH_BASIC                   L"basic;"
 #define ASPNETCORE_IIS_AUTH_ANONYMOUS               L"anonymous;"
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h b/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h
index 17ab7603b42..f95feca6b9b 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h
@@ -192,6 +192,7 @@ public:
         _In_ BOOL                           fBasicAuthEnabled,
         _In_ BOOL                           fAnonymousAuthEnabled,
         _In_ PCWSTR                         pApplicationPhysicalPath,
+        _In_ PCWSTR                         pHttpsPort,
         _Out_ ENVIRONMENT_VAR_HASH**        ppEnvironmentVarTable
     )
     {
@@ -203,6 +204,7 @@ public:
         ENVIRONMENT_VAR_ENTRY* pHostingEntry = NULL;
         ENVIRONMENT_VAR_ENTRY* pIISAuthEntry = NULL;
         ENVIRONMENT_VAR_ENTRY* pIISPathEntry = NULL;
+        ENVIRONMENT_VAR_ENTRY* pIISHttpsPort = NULL;
         ENVIRONMENT_VAR_HASH* pEnvironmentVarTable = NULL;
 
         pEnvironmentVarTable = new ENVIRONMENT_VAR_HASH();
@@ -240,6 +242,26 @@ public:
             goto Finished;
         }
 
+        if (pHttpsPort != nullptr)
+        {
+            pEnvironmentVarTable->FindKey((PWSTR)ASPNETCORE_HTTPS_PORT_ENV_STR, &pIISHttpsPort);
+            if (pIISHttpsPort != NULL)
+            {
+                // user defined ASPNETCORE_HTTPS_PORT in configuration, don't override it
+                pIISHttpsPort->Dereference();
+            }
+            else
+            {
+                pIISHttpsPort = new ENVIRONMENT_VAR_ENTRY();
+
+                if (FAILED(hr = pIISHttpsPort->Initialize(ASPNETCORE_HTTPS_PORT_ENV_STR, pHttpsPort)) ||
+                    FAILED(hr = pEnvironmentVarTable->InsertRecord(pIISHttpsPort)))
+                {
+                    goto Finished;
+                }
+            }
+        }
+
         pEnvironmentVarTable->FindKey((PWSTR)ASPNETCORE_IIS_AUTH_ENV_STR, &pIISAuthEntry);
         if (pIISAuthEntry != NULL)
         {
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp b/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp
index 1a087d5c95b..68abb1b8f11 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp
@@ -8,7 +8,6 @@
 #include "exceptions.h"
 #include "config_utility.h"
 
-
 REQUESTHANDLER_CONFIG::~REQUESTHANDLER_CONFIG()
 {
     if (m_ppStrArguments != NULL)
@@ -28,6 +27,7 @@ REQUESTHANDLER_CONFIG::~REQUESTHANDLER_CONFIG()
 HRESULT
 REQUESTHANDLER_CONFIG::CreateRequestHandlerConfig(
     _In_  IHttpServer             *pHttpServer,
+    _In_  IHttpSite               *pSite,
     _In_  IHttpApplication        *pHttpApplication,
     _Out_ REQUESTHANDLER_CONFIG  **ppAspNetCoreConfig
 )
@@ -49,7 +49,7 @@ REQUESTHANDLER_CONFIG::CreateRequestHandlerConfig(
 
         pRequestHandlerConfig = new REQUESTHANDLER_CONFIG;
 
-        hr = pRequestHandlerConfig->Populate(pHttpServer, pHttpApplication);
+        hr = pRequestHandlerConfig->Populate(pHttpServer, pSite, pHttpApplication);
         if (FAILED(hr))
         {
             goto Finished;
@@ -85,6 +85,7 @@ Finished:
 HRESULT
 REQUESTHANDLER_CONFIG::Populate(
     IHttpServer    *pHttpServer,
+    IHttpSite      *pSite,
     IHttpApplication   *pHttpApplication
 )
 {
@@ -122,6 +123,19 @@ REQUESTHANDLER_CONFIG::Populate(
     }
 
     pAdminManager = pHttpServer->GetAdminManager();
+    if (pSite != nullptr)
+    {
+        try
+        {
+            WebConfigConfigurationSource source(pAdminManager, *pHttpApplication);
+            m_struHttpsPort.Copy(BindingInformation::GetHttpsPort(BindingInformation::Load(source, *pSite)).c_str());
+        }
+        catch (...)
+        {
+            FINISHED_IF_FAILED(OBSERVE_CAUGHT_EXCEPTION());
+        }
+    }
+
     hr = m_struConfigPath.Copy(pHttpApplication->GetAppConfigPath());
     if (FAILED(hr))
     {
diff --git a/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h b/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h
index 5ba8959317b..c757ab16c22 100644
--- a/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h
+++ b/src/Servers/IIS/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h
@@ -43,6 +43,7 @@
 
 #include "stdafx.h"
 #include "environmentvariablehash.h"
+#include "BindingInformation.h"
 
 enum APP_HOSTING_MODEL
 {
@@ -62,6 +63,7 @@ public:
     HRESULT
     CreateRequestHandlerConfig(
         _In_  IHttpServer             *pHttpServer,
+        _In_  IHttpSite               *pSite,
         _In_  IHttpApplication        *pHttpApplication,
         _Out_ REQUESTHANDLER_CONFIG  **ppAspNetCoreConfig
     );
@@ -114,6 +116,12 @@ public:
         return m_dwRequestTimeoutInMS;
     }
 
+    STRU*
+    QueryBindings()
+    {
+        return &m_struHttpsPort;
+    }
+
     STRU*
     QueryArguments(
         VOID
@@ -226,6 +234,7 @@ protected:
     HRESULT
     Populate(
         IHttpServer      *pHttpServer,
+        IHttpSite        *pSite,
         IHttpApplication *pHttpApplication
     );
 
@@ -252,5 +261,5 @@ protected:
     STRU                   m_struHostFxrLocation;
     PWSTR*                 m_ppStrArguments;
     DWORD                  m_dwArgc;
-
+    STRU                   m_struHttpsPort;
 };
diff --git a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISConfigurationData.cs b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISConfigurationData.cs
index 5c552677566..882651622e1 100644
--- a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISConfigurationData.cs
+++ b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISConfigurationData.cs
@@ -17,5 +17,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
         public bool fWindowsAuthEnabled;
         public bool fBasicAuthEnabled;
         public bool fAnonymousAuthEnable;
+        [MarshalAs(UnmanagedType.BStr)]
+        public string pwzBindings;
     }
 }
diff --git a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpServer.cs b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpServer.cs
index bfabf61bd77..70516418e68 100644
--- a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpServer.cs
+++ b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpServer.cs
@@ -1,5 +1,3 @@
-// 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.Buffers;
@@ -10,6 +8,7 @@ using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.Hosting.Server.Features;
 using Microsoft.AspNetCore.Http.Features;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
@@ -32,6 +31,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
         private readonly ILogger<IISHttpServer> _logger;
         private readonly IISServerOptions _options;
         private readonly IISNativeApplication _nativeApplication;
+        private readonly ServerAddressesFeature _serverAddressesFeature;
 
         private volatile int _stopping;
         private bool Stopping => _stopping == 1;
@@ -71,11 +71,14 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
             _applicationLifetime = applicationLifetime;
             _logger = logger;
             _options = options.Value;
+            _serverAddressesFeature = new ServerAddressesFeature();
 
             if (_options.ForwardWindowsAuthentication)
             {
                 authentication.AddScheme(new AuthenticationScheme(IISServerDefaults.AuthenticationScheme, _options.AuthenticationDisplayName, typeof(IISServerAuthenticationHandler)));
             }
+
+            Features.Set<IServerAddressesFeature>(_serverAddressesFeature);
         }
 
         public Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken)
@@ -84,6 +87,9 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
 
             _iisContextFactory = new IISContextFactory<TContext>(_memoryPool, application, _options, this, _logger);
             _nativeApplication.RegisterCallbacks(_requestHandler, _shutdownHandler, _onDisconnect, _onAsyncCompletion, (IntPtr)_httpServerHandle, (IntPtr)_httpServerHandle);
+
+            _serverAddressesFeature.Addresses = _options.ServerAddresses;
+
             return Task.CompletedTask;
         }
 
diff --git a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerSetupFilter.cs b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerSetupFilter.cs
index f3c36135659..e02fc844497 100644
--- a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerSetupFilter.cs
+++ b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerSetupFilter.cs
@@ -2,16 +2,18 @@
 // 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 Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.Hosting.Server.Features;
 using Microsoft.Extensions.DependencyInjection;
 
 namespace Microsoft.AspNetCore.Server.IIS.Core
 {
     internal class IISServerSetupFilter : IStartupFilter
     {
-        private string _virtualPath;
+        private readonly string _virtualPath;
 
         public IISServerSetupFilter(string virtualPath)
         {
diff --git a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/ServerAddressesFeature.cs b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/ServerAddressesFeature.cs
new file mode 100644
index 00000000000..42ccc974606
--- /dev/null
+++ b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/Core/ServerAddressesFeature.cs
@@ -0,0 +1,15 @@
+// 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 Microsoft.AspNetCore.Hosting.Server.Features;
+
+namespace Microsoft.AspNetCore.Server.IIS.Core
+{
+    internal class ServerAddressesFeature : IServerAddressesFeature
+    {
+        public ICollection<string> Addresses { get; set; } = Array.Empty<string>();
+        public bool PreferHostingUrls { get; set; }
+    }
+}
diff --git a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/IISServerOptions.cs b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/IISServerOptions.cs
index feed9180a55..f4390801953 100644
--- a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/IISServerOptions.cs
+++ b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/IISServerOptions.cs
@@ -22,5 +22,7 @@ namespace Microsoft.AspNetCore.Builder
         /// IIS has a non-anonymous authentication enabled, or for back compat with ANCMs that did not provide this information.
         /// </summary>
         internal bool ForwardWindowsAuthentication { get; set; } = true;
+
+        internal string[] ServerAddresses { get; set; }
     }
 }
diff --git a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs
index 146f9a50f5b..aac753dc752 100644
--- a/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs
+++ b/src/Servers/IIS/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs
@@ -43,7 +43,10 @@ namespace Microsoft.AspNetCore.Hosting
                         services.AddSingleton<IStartupFilter>(new IISServerSetupFilter(iisConfigData.pwzVirtualApplicationPath));
                         services.AddAuthenticationCore();
                         services.Configure<IISServerOptions>(
-                             options => { options.ForwardWindowsAuthentication = iisConfigData.fWindowsAuthEnabled || iisConfigData.fBasicAuthEnabled; }
+                            options => {
+                                options.ServerAddresses = iisConfigData.pwzBindings.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
+                                options.ForwardWindowsAuthentication = iisConfigData.fWindowsAuthEnabled || iisConfigData.fBasicAuthEnabled;
+                            }
                         );
                     });
             }
diff --git a/src/Servers/IIS/test/Common.FunctionalTests/HttpsTests.cs b/src/Servers/IIS/test/Common.FunctionalTests/HttpsTests.cs
new file mode 100644
index 00000000000..658aaf7a0b9
--- /dev/null
+++ b/src/Servers/IIS/test/Common.FunctionalTests/HttpsTests.cs
@@ -0,0 +1,177 @@
+// 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.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
+using Microsoft.AspNetCore.Server.IntegrationTesting;
+using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
+using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
+using Microsoft.AspNetCore.Testing.xunit;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
+{
+    [Collection(PublishedSitesCollection.Name)]
+    public class HttpsTests : IISFunctionalTestBase
+    {
+        private readonly PublishedSitesFixture _fixture;
+
+        public HttpsTests(PublishedSitesFixture fixture)
+        {
+            _fixture = fixture;
+        }
+
+        public static TestMatrix TestVariants
+            => TestMatrix.ForServers(DeployerSelector.ServerType)
+                .WithTfms(Tfm.NetCoreApp30)
+                .WithAllApplicationTypes()
+                .WithAllAncmVersions()
+                .WithAllHostingModels();
+
+        [ConditionalTheory]
+        [MemberData(nameof(TestVariants))]
+        public async Task HttpsHelloWorld(TestVariant variant)
+        {
+            var port = TestPortHelper.GetNextSSLPort();
+            var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
+            deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/";
+            deploymentParameters.AddHttpsToServerConfig();
+
+            var deploymentResult = await DeployAsync(deploymentParameters);
+
+            var handler = new HttpClientHandler
+            {
+                ServerCertificateCustomValidationCallback = (a, b, c, d) => true
+            };
+            var client = deploymentResult.CreateClient(handler);
+            var response = await client.GetAsync("HttpsHelloWorld");
+            var responseText = await response.Content.ReadAsStringAsync();
+            if (variant.HostingModel == HostingModel.OutOfProcess)
+            {
+                Assert.Equal("Scheme:https; Original:http", responseText);
+            }
+            else
+            {
+                Assert.Equal("Scheme:https; Original:", responseText);
+            }
+
+            if (variant.AncmVersion == AncmVersion.AspNetCoreModuleV2 &&
+                DeployerSelector.HasNewHandler &&
+                DeployerSelector.HasNewShim)
+            {
+                // We expect ServerAddress to be set for InProcess and HTTPS_PORT for OutOfProcess
+                if (variant.HostingModel == HostingModel.InProcess)
+                {
+                    Assert.Equal(deploymentParameters.ApplicationBaseUriHint, await client.GetStringAsync("/ServerAddresses"));
+                }
+                else
+                {
+                    Assert.Equal(port.ToString(), await client.GetStringAsync("/HTTPS_PORT"));
+                }
+            }
+        }
+
+        [ConditionalFact]
+        [RequiresNewHandler]
+        [RequiresNewShim]
+        public async Task ServerAddressesIncludesBaseAddress()
+        {
+            var appName = "\u041C\u043E\u0451\u041F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435";
+
+            var port = TestPortHelper.GetNextSSLPort();
+            var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.InProcess, publish: true);
+            deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/";
+            deploymentParameters.AddHttpsToServerConfig();
+            deploymentParameters.AddServerConfigAction(
+                (element, root) => {
+                    element.Descendants("site").Single().Element("application").SetAttributeValue("path", "/" + appName);
+                    Helpers.CreateEmptyApplication(element, root);
+                });
+
+            var deploymentResult = await DeployAsync(deploymentParameters);
+            Assert.Equal(deploymentParameters.ApplicationBaseUriHint + appName, await deploymentResult.HttpClient.GetStringAsync($"/{appName}/ServerAddresses"));
+        }
+
+        [ConditionalFact]
+        [RequiresNewHandler]
+        [RequiresNewShim]
+        public async Task HttpsPortCanBeOverriden()
+        {
+            var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
+
+            deploymentParameters.AddServerConfigAction(
+                element => {
+                    element.Descendants("bindings")
+                        .Single()
+                        .GetOrAdd("binding", "protocol", "https")
+                        .SetAttributeValue("bindingInformation", $":{TestPortHelper.GetNextSSLPort()}:localhost");
+                });
+
+            deploymentParameters.WebConfigBasedEnvironmentVariables["ASPNETCORE_HTTPS_PORT"] = "123";
+
+            var deploymentResult = await DeployAsync(deploymentParameters);
+            Assert.Equal("123", await deploymentResult.HttpClient.GetStringAsync("/HTTPS_PORT"));
+        }
+
+        [ConditionalFact]
+        [RequiresNewHandler]
+        [RequiresNewShim]
+        public async Task MultipleHttpsPortsProduceNoEnvVar()
+        {
+            var sslPort = GetNextSSLPort();
+            var anotherSslPort = GetNextSSLPort(sslPort);
+
+            var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true);
+
+            deploymentParameters.AddServerConfigAction(
+                element => {
+                    element.Descendants("bindings")
+                        .Single()
+                        .Add(
+                            new XElement("binding",
+                                new XAttribute("protocol", "https"),
+                                new XAttribute("bindingInformation",  $":{sslPort}:localhost")),
+                            new XElement("binding",
+                                new XAttribute("protocol", "https"),
+                                new XAttribute("bindingInformation",  $":{anotherSslPort}:localhost")));
+                });
+
+            var deploymentResult = await DeployAsync(deploymentParameters);
+            Assert.Equal("NOVALUE", await deploymentResult.HttpClient.GetStringAsync("/HTTPS_PORT"));
+        }
+
+        public static int GetNextSSLPort(int avoid = 0)
+        {
+            var next = 44300;
+            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            {
+                while (true)
+                {
+                    try
+                    {
+                        var port = next++;
+                        if (port == avoid)
+                        {
+                            continue;
+                        }
+                        socket.Bind(new IPEndPoint(IPAddress.Loopback, port));
+                        return port;
+                    }
+                    catch (SocketException)
+                    {
+                        // Retry unless exhausted
+                        if (next > 44399)
+                        {
+                            throw;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/Servers/IIS/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs b/src/Servers/IIS/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs
index e31dc3dbaa0..696a47e4208 100644
--- a/src/Servers/IIS/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs
+++ b/src/Servers/IIS/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs
@@ -1,6 +1,7 @@
 // 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.Threading.Tasks;
 using Microsoft.AspNetCore.Testing.xunit;
 using Xunit;
@@ -25,5 +26,13 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
         {
             Assert.Equal("Success", await _fixture.Client.GetStringAsync(path + "/path" + "?query"));
         }
+
+        [ConditionalFact]
+        [RequiresNewHandler]
+        [RequiresNewShim]
+        public async Task ExposesIServerAddressesFeature()
+        {
+            Assert.Equal(_fixture.Client.BaseAddress.ToString(), await _fixture.Client.GetStringAsync("/ServerAddresses"));
+        }
     }
 }
diff --git a/src/Servers/IIS/test/Common.FunctionalTests/MultiApplicationTests.cs b/src/Servers/IIS/test/Common.FunctionalTests/MultiApplicationTests.cs
index 3723369c89e..d9eda78e281 100644
--- a/src/Servers/IIS/test/Common.FunctionalTests/MultiApplicationTests.cs
+++ b/src/Servers/IIS/test/Common.FunctionalTests/MultiApplicationTests.cs
@@ -115,18 +115,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
             siteElement.Add(newApplication);
 
             // IIS Express requires root application to exist
-            var rootApplicationDirectory = new DirectoryInfo(contentRoot + "rootApp");
-            rootApplicationDirectory.Create();
 
-            _rootApplication = new PublishedApplication(rootApplicationDirectory.FullName, Logger);
-            File.WriteAllText(GetWebConfigLocation(rootApplicationDirectory.FullName), "<configuration></configuration>");
-
-            var rootApplication = new XElement(application);
-            rootApplication.SetAttributeValue("path", "/");
-            rootApplication.RequiredElement("virtualDirectory")
-                .SetAttributeValue("physicalPath", rootApplicationDirectory.FullName);
-
-            siteElement.Add(rootApplication);
+            _rootApplication = new PublishedApplication(Helpers.CreateEmptyApplication(config, contentRoot), Logger);
         }
 
         private static string GetWebConfigLocation(string siteRoot)
diff --git a/src/Servers/IIS/test/Common.FunctionalTests/Utilities/Helpers.cs b/src/Servers/IIS/test/Common.FunctionalTests/Utilities/Helpers.cs
index 7876403e654..560d475a7d6 100644
--- a/src/Servers/IIS/test/Common.FunctionalTests/Utilities/Helpers.cs
+++ b/src/Servers/IIS/test/Common.FunctionalTests/Utilities/Helpers.cs
@@ -237,5 +237,30 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
                 throw ex;
             }
         }
+
+        public static string CreateEmptyApplication(XElement config, string contentRoot)
+        {
+            var siteElement = config
+                .RequiredElement("system.applicationHost")
+                .RequiredElement("sites")
+                .RequiredElement("site");
+
+            var application = siteElement
+                .RequiredElement("application");
+
+            var rootApplicationDirectory = new DirectoryInfo(contentRoot + "rootApp");
+            rootApplicationDirectory.Create();
+
+            File.WriteAllText(Path.Combine(rootApplicationDirectory.FullName, "web.config"), "<configuration></configuration>");
+
+            var rootApplication = new XElement(application);
+            rootApplication.SetAttributeValue("path", "/");
+            rootApplication.RequiredElement("virtualDirectory")
+                .SetAttributeValue("physicalPath", rootApplicationDirectory.FullName);
+
+            siteElement.Add(rootApplication);
+
+            return rootApplicationDirectory.FullName;
+        }
     }
 }
diff --git a/src/Servers/IIS/test/CommonLibTests/BindingInformationTest.cpp b/src/Servers/IIS/test/CommonLibTests/BindingInformationTest.cpp
new file mode 100644
index 00000000000..90ca8523c01
--- /dev/null
+++ b/src/Servers/IIS/test/CommonLibTests/BindingInformationTest.cpp
@@ -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.
+
+#include "stdafx.h"
+
+namespace BindingInformationTest
+{
+    class BindingInformationTest : public testing::Test
+    {
+    protected:
+        void
+        ParseBindingInformation(std::wstring protocol, std::wstring info, std::wstring expectedHost, std::wstring expectedPort)
+        {
+            BindingInformation information(protocol, info);
+
+            EXPECT_STREQ(information.QueryHost().c_str(), expectedHost.c_str());
+            EXPECT_STREQ(information.QueryPort().c_str(), expectedPort.c_str());
+            EXPECT_STREQ(information.QueryProtocol().c_str(), protocol.c_str());
+        }
+    };
+
+    TEST_F(BindingInformationTest, ParsesInformationCorrectly)
+    {
+        ParseBindingInformation(L"https", L":80:", L"*", L"80");
+        ParseBindingInformation(L"https", L":80:host", L"host", L"80");
+        ParseBindingInformation(L"http", L":80:host", L"host", L"80");
+        ParseBindingInformation(L"http", L"RANDOM_IP:5:", L"*", L"5");
+    }
+}
diff --git a/src/Servers/IIS/test/CommonLibTests/CommonLibTests.vcxproj b/src/Servers/IIS/test/CommonLibTests/CommonLibTests.vcxproj
index b566c1c75e9..45726d91d0c 100644
--- a/src/Servers/IIS/test/CommonLibTests/CommonLibTests.vcxproj
+++ b/src/Servers/IIS/test/CommonLibTests/CommonLibTests.vcxproj
@@ -1,5 +1,4 @@
-
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
@@ -58,6 +57,7 @@
     <ClCompile Include="inprocess_application_tests.cpp" />
     <ClCompile Include="main.cpp" />
     <ClCompile Include="PipeOutputManagerTests.cpp" />
+    <ClCompile Include="BindingInformationTest.cpp" />
     <ClCompile Include="utility_tests.cpp" />
   </ItemGroup>
   <ItemGroup>
@@ -195,4 +195,4 @@
     </Lib>
   </ItemDefinitionGroup>
   <Import Project=".\NativeTests.targets" />
-</Project>
+</Project>
\ No newline at end of file
diff --git a/src/Servers/IIS/test/IISExpress.FunctionalTests/HttpsTests.cs b/src/Servers/IIS/test/IISExpress.FunctionalTests/HttpsTests.cs
deleted file mode 100644
index 7324bd76130..00000000000
--- a/src/Servers/IIS/test/IISExpress.FunctionalTests/HttpsTests.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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.Net.Http;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
-using Microsoft.AspNetCore.Server.IntegrationTesting;
-using Microsoft.AspNetCore.Server.IntegrationTesting.Common;
-using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
-using Microsoft.AspNetCore.Testing.xunit;
-using Xunit;
-
-namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
-{
-    [Collection(PublishedSitesCollection.Name)]
-    public class HttpsTests : IISFunctionalTestBase
-    {
-        private readonly PublishedSitesFixture _fixture;
-
-        public HttpsTests(PublishedSitesFixture fixture)
-        {
-            _fixture = fixture;
-        }
-
-        public static TestMatrix TestVariants
-            => TestMatrix.ForServers(DeployerSelector.ServerType)
-                .WithTfms(Tfm.NetCoreApp30)
-                .WithAllApplicationTypes()
-                .WithAllAncmVersions()
-                .WithAllHostingModels();
-
-        [ConditionalTheory]
-        [MemberData(nameof(TestVariants))]
-        public async Task HttpsHelloWorld(TestVariant variant)
-        {
-            var port = TestPortHelper.GetNextSSLPort();
-            var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant);
-            deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/";
-            deploymentParameters.AddHttpsToServerConfig();
-
-            var deploymentResult = await DeployAsync(deploymentParameters);
-
-            var handler = new HttpClientHandler
-            {
-                ServerCertificateCustomValidationCallback = (a, b, c, d) => true
-            };
-            var client = deploymentResult.CreateClient(handler);
-            var response = await client.GetAsync("HttpsHelloWorld");
-            var responseText = await response.Content.ReadAsStringAsync();
-            if (variant.HostingModel == HostingModel.OutOfProcess)
-            {
-                Assert.Equal("Scheme:https; Original:http", responseText);
-            }
-            else
-            {
-                Assert.Equal("Scheme:https; Original:", responseText);
-            }
-        }
-    }
-}
diff --git a/src/Servers/IIS/test/testassets/OutOfProcessWebSite/Startup.cs b/src/Servers/IIS/test/testassets/OutOfProcessWebSite/Startup.cs
index de54a85a8a3..394f248eb4e 100644
--- a/src/Servers/IIS/test/testassets/OutOfProcessWebSite/Startup.cs
+++ b/src/Servers/IIS/test/testassets/OutOfProcessWebSite/Startup.cs
@@ -4,16 +4,15 @@
 using System;
 using System.Diagnostics;
 using System.IO;
-using System.Linq;
 using System.Security.Principal;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting.Server.Features;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http.Features;
 using Microsoft.AspNetCore.IISIntegration.FunctionalTests;
 using Microsoft.AspNetCore.Server.IISIntegration;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Xunit;
 
@@ -21,13 +20,9 @@ namespace TestSite
 {
     public partial class Startup
     {
-        private IServerAddressesFeature _serverAddresses;
-
         public void Configure(IApplicationBuilder app)
         {
             TestStartup.Register(app, this);
-
-            _serverAddresses = app.ServerFeatures.Get<IServerAddressesFeature>();
         }
 
         public Task Path(HttpContext ctx) => ctx.Response.WriteAsync(ctx.Request.Path.Value);
@@ -36,7 +31,6 @@ namespace TestSite
 
         public Task BodyLimit(HttpContext ctx) => ctx.Response.WriteAsync(ctx.Features.Get<IHttpMaxRequestBodySizeFeature>()?.MaxRequestBodySize?.ToString() ?? "null");
 
-
         public Task HelloWorld(HttpContext ctx) => ctx.Response.WriteAsync("Hello World");
 
         public Task HttpsHelloWorld(HttpContext ctx) =>
@@ -97,9 +91,11 @@ namespace TestSite
             await context.Response.WriteAsync(Process.GetCurrentProcess().Id.ToString());
         }
 
-        private async Task ServerAddresses(HttpContext context)
+        public async Task HTTPS_PORT(HttpContext context)
         {
-            await context.Response.WriteAsync(string.Join(",", _serverAddresses.Addresses));
+            var httpsPort = context.RequestServices.GetService<IConfiguration>().GetValue<int?>("HTTPS_PORT");
+
+            await context.Response.WriteAsync(httpsPort.HasValue ? httpsPort.Value.ToString() : "NOVALUE");
         }
     }
 }
diff --git a/src/Servers/IIS/test/testassets/shared/SharedStartup/Startup.shared.cs b/src/Servers/IIS/test/testassets/shared/SharedStartup/Startup.shared.cs
index 851654966b8..f85f9e1fddc 100644
--- a/src/Servers/IIS/test/testassets/shared/SharedStartup/Startup.shared.cs
+++ b/src/Servers/IIS/test/testassets/shared/SharedStartup/Startup.shared.cs
@@ -11,6 +11,8 @@ using System.Threading.Tasks;
 using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.Hosting.Server.Features;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.DependencyInjection;
 
@@ -33,6 +35,12 @@ namespace TestSite
 
         private async Task ASPNETCORE_IIS_PHYSICAL_PATH(HttpContext ctx) => await ctx.Response.WriteAsync(Environment.GetEnvironmentVariable("ASPNETCORE_IIS_PHYSICAL_PATH"));
 
+        private async Task ServerAddresses(HttpContext ctx)
+        {
+            var serverAddresses = ctx.RequestServices.GetService<IServer>().Features.Get<IServerAddressesFeature>();
+            await ctx.Response.WriteAsync(string.Join(",", serverAddresses.Addresses));
+        }
+
         private async Task ConsoleWrite(HttpContext ctx)
         {
             Console.WriteLine("TEST MESSAGE");
-- 
GitLab