Skip to content

Commit 6bf7a3c

Browse files
committed
Feedback
1 parent bb407d9 commit 6bf7a3c

17 files changed

+56
-60
lines changed

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
<Link>
112112
<SubSystem>Windows</SubSystem>
113113
<GenerateDebugInformation>true</GenerateDebugInformation>
114-
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib</AdditionalDependencies>
114+
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib</AdditionalDependencies>
115115
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
116116
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
117117
</Link>
@@ -147,7 +147,7 @@
147147
<Link>
148148
<SubSystem>Windows</SubSystem>
149149
<GenerateDebugInformation>true</GenerateDebugInformation>
150-
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib</AdditionalDependencies>
150+
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib</AdditionalDependencies>
151151
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
152152
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
153153
</Link>
@@ -188,7 +188,7 @@
188188
<AdditionalOptions>/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions)</AdditionalOptions>
189189
<OptimizeReferences>true</OptimizeReferences>
190190
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
191-
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib</AdditionalDependencies>
191+
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib</AdditionalDependencies>
192192
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
193193
</Link>
194194
<ResourceCompile>
@@ -228,7 +228,7 @@
228228
<AdditionalOptions>/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions)</AdditionalOptions>
229229
<OptimizeReferences>true</OptimizeReferences>
230230
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
231-
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib</AdditionalDependencies>
231+
<AdditionalDependencies>kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib</AdditionalDependencies>
232232
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
233233
</Link>
234234
<ResourceCompile>
@@ -317,4 +317,4 @@
317317
</ItemGroup>
318318
<WriteLinesToFile File="$(InstallersOutputPath)aspnetcoremodule.version" Lines="@(VersionFileContents)" OverWrite="true" WriteOnlyWhenDifferent="True" />
319319
</Target>
320-
</Project>
320+
</Project>

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ HandlerResolver::HandlerResolver(HMODULE hModule, const IHttpServer &pServer)
2929

3030
HRESULT
3131
HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication,
32-
std::filesystem::path shadowCopyPath,
32+
const std::filesystem::path& shadowCopyPath,
3333
const ShimOptions& pConfiguration,
3434
std::unique_ptr<ApplicationFactory>& pApplicationFactory,
3535
ErrorContext& errorContext)
@@ -126,7 +126,7 @@ HandlerResolver::LoadRequestHandlerAssembly(const IHttpApplication &pApplication
126126
}
127127

128128
HRESULT
129-
HandlerResolver::GetApplicationFactory(const IHttpApplication& pApplication, std::filesystem::path shadowCopyPath, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext)
129+
HandlerResolver::GetApplicationFactory(const IHttpApplication& pApplication, const std::filesystem::path& shadowCopyPath, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext)
130130
{
131131
SRWExclusiveLock lock(m_requestHandlerLoadLock);
132132
if (m_loadedApplicationHostingModel != HOSTING_UNKNOWN)

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ class HandlerResolver
1515
{
1616
public:
1717
HandlerResolver(HMODULE hModule, const IHttpServer &pServer);
18-
HRESULT GetApplicationFactory(const IHttpApplication &pApplication, std::filesystem::path shadowCopyPath, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext);
18+
HRESULT GetApplicationFactory(const IHttpApplication &pApplication, const std::filesystem::path& shadowCopyPath, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext);
1919
void ResetHostingModel();
2020
APP_HOSTING_MODEL GetHostingModel();
2121

2222
private:
23-
HRESULT LoadRequestHandlerAssembly(const IHttpApplication &pApplication, std::filesystem::path shadowCopyPath, const ShimOptions& pConfiguration, std::unique_ptr<ApplicationFactory>& pApplicationFactory, ErrorContext& errorContext);
23+
HRESULT LoadRequestHandlerAssembly(const IHttpApplication &pApplication, const std::filesystem::path& shadowCopyPath, const ShimOptions& pConfiguration, std::unique_ptr<ApplicationFactory>& pApplicationFactory, ErrorContext& errorContext);
2424
HRESULT FindNativeAssemblyFromGlobalLocation(const ShimOptions& pConfiguration, PCWSTR libraryName, std::wstring& handlerDllPath);
2525
HRESULT FindNativeAssemblyFromHostfxr(
2626
const HostFxrResolutionResult& hostfxrOptions,

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ShimOptions.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ ShimOptions::ShimOptions(const ConfigurationSource &configurationSource) :
4747
auto cleanShadowCopyDirectory = find_element(handlerSettings, CS_ASPNETCORE_CLEAN_SHADOW_DIRECTORY_CONTENT).value_or(std::wstring());
4848
m_fCleanShadowCopyDirectory = equals_ignore_case(L"true", cleanShadowCopyDirectory);
4949

50-
m_strShadowCopyingDirectory = find_element(handlerSettings, CS_ASPNETCORE_SHADOW_COPY_DIRECTORY).value_or(std::wstring());
50+
m_strShadowCopyingDirectory = find_element(handlerSettings, CS_ASPNETCORE_SHADOW_COPY_DIRECTORY)
51+
.value_or(m_fEnableShadowCopying ? L"ShadowCopyDirectory" : std::wstring());
5152

5253
m_strProcessPath = section->GetRequiredString(CS_ASPNETCORE_PROCESS_EXE_PATH);
5354
m_strArguments = section->GetString(CS_ASPNETCORE_PROCESS_ARGUMENTS).value_or(CS_ASPNETCORE_PROCESS_ARGUMENTS_DEFAULT);

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "file_utility.h"
2121

2222
extern HINSTANCE g_hServerModule;
23-
extern BOOL g_fInAppOfflineShutdown;
23+
extern BOOL g_fInAppOfflineShutdown;
2424

2525
HRESULT
2626
APPLICATION_INFO::CreateHandler(
@@ -83,24 +83,24 @@ APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext)
8383
return S_OK;
8484
}
8585

86-
if (g_fInAppOfflineShutdown)
87-
{
88-
m_pApplication = make_application<ServerErrorApplication>(
89-
pHttpApplication,
90-
E_FAIL,
91-
false /* disableStartupPage */,
92-
"" /* responseContent */,
93-
503i16 /* statusCode */,
94-
0i16 /* subStatusCode */,
95-
"Application Shutting Down");
96-
return S_OK;
97-
}
98-
9986
try
10087
{
10188
const WebConfigConfigurationSource configurationSource(m_pServer.GetAdminManager(), pHttpApplication);
10289
ShimOptions options(configurationSource);
10390

91+
if (g_fInAppOfflineShutdown)
92+
{
93+
m_pApplication = make_application<ServerErrorApplication>(
94+
pHttpApplication,
95+
E_FAIL,
96+
false /* disableStartupPage */,
97+
"" /* responseContent */,
98+
503i16 /* statusCode */,
99+
0i16 /* subStatusCode */,
100+
"Application Shutting Down");
101+
return S_OK;
102+
}
103+
104104
ErrorContext errorContext;
105105
errorContext.statusCode = 500i16;
106106
errorContext.subStatusCode = 0i16;
@@ -198,10 +198,11 @@ APPLICATION_INFO::TryCreateApplication(IHttpContext& pHttpContext, const ShimOpt
198198
LOG_INFO(L"Creating handler application");
199199

200200
IAPPLICATION * newApplication;
201+
std::wstring shadowCopyWstring = shadowCopyPath.wstring();
201202
RETURN_IF_FAILED(m_pApplicationFactory->Execute(
202203
&m_pServer,
203204
&pHttpContext,
204-
shadowCopyPath,
205+
shadowCopyWstring,
205206
&newApplication));
206207

207208
m_pApplication.reset(newApplication);
@@ -287,12 +288,11 @@ APPLICATION_INFO::HandleShadowCopy(const ShimOptions& options, IHttpContext& pHt
287288
{
288289
try
289290
{
290-
std::string::size_type size;
291-
int intFileName = std::stoi(entry.path().filename().string(), &size);
291+
int intFileName = std::stoi(entry.path().filename().string());
292292
if (intFileName > directoryName)
293293
{
294294
directoryName = intFileName;
295-
directoryNameStr = std::string(entry.path().string());
295+
directoryNameStr = entry.path().filename().string();
296296
}
297297
}
298298
catch (...)
@@ -303,7 +303,7 @@ APPLICATION_INFO::HandleShadowCopy(const ShimOptions& options, IHttpContext& pHt
303303
}
304304
}
305305

306-
shadowCopyPath = shadowCopyPath / std::filesystem::path(directoryNameStr);
306+
shadowCopyPath = shadowCopyPath / directoryNameStr;
307307
HRESULT hr = Environment::CopyToDirectory(physicalPath, shadowCopyPath, options.QueryCleanShadowCopyDirectory(), shadowCopyBaseDirectory.path().parent_path());
308308
if (hr != S_OK)
309309
{

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationinfo.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ class APPLICATION_INFO: NonCopyable
6666
return false;
6767
}
6868

69-
7069
private:
7170

7271
HRESULT

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ APPLICATION_MANAGER::RecycleApplicationFromManager(
109109
if (itr->second->ConfigurationPathApplies(configurationPath))
110110
{
111111
applicationsToRecycle.emplace_back(itr->second);
112-
// Delete after shutting the application down to avoid creating
112+
// Delay deleting an in-process app until after shutting the application down to avoid creating
113113
// another application info, which would just return app_offline.
114114
if (m_handlerResolver.GetHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
115115
{

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/Environment.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ bool Environment::IsRunning64BitProcess()
152152
return systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
153153
}
154154

155-
HRESULT Environment::CopyToDirectory(std::wstring source, std::filesystem::path destination, bool cleanDest, std::filesystem::path directoryToIgnore)
155+
HRESULT Environment::CopyToDirectory(const std::wstring& source, const std::filesystem::path& destination, bool cleanDest, const std::filesystem::path& directoryToIgnore)
156156
{
157157
if (cleanDest && std::filesystem::exists(destination))
158158
{
@@ -201,7 +201,7 @@ void Environment::CopyToDirectoryInner(const std::filesystem::path& source, cons
201201
}
202202
}
203203

204-
bool Environment::CheckUpToDate(std::wstring source, std::filesystem::path destination, const std::wstring& extension, const std::filesystem::path& directoryToIgnore)
204+
bool Environment::CheckUpToDate(const std::wstring& source, const std::filesystem::path& destination, const std::wstring& extension, const std::filesystem::path& directoryToIgnore)
205205
{
206206
for (auto& path : std::filesystem::directory_iterator(source))
207207
{

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/Environment.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ class Environment
2323
static
2424
bool IsRunning64BitProcess();
2525
static
26-
HRESULT CopyToDirectory(std::wstring source, std::filesystem::path destination, bool cleanDest, std::filesystem::path directoryToIgnore);
26+
HRESULT CopyToDirectory(const std::wstring& source, const std::filesystem::path& destination, bool cleanDest, const std::filesystem::path& directoryToIgnore);
2727
static
28-
bool CheckUpToDate(std::wstring source, std::filesystem::path destination, const std::wstring& extension, const std::filesystem::path& directoryToIgnore);
28+
bool CheckUpToDate(const std::wstring& source, const std::filesystem::path& destination, const std::wstring& extension, const std::filesystem::path& directoryToIgnore);
2929
private:
3030
static
3131
void CopyToDirectoryInner(const std::filesystem::path& source_folder, const std::filesystem::path& target_folder, const std::filesystem::path& directoryToIgnore);

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/sttimer.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,11 @@ class STTIMER
118118
VOID
119119
CALLBACK
120120
TimerCallback(
121-
_In_ PTP_CALLBACK_INSTANCE Instance,
121+
_In_ PTP_CALLBACK_INSTANCE ,
122122
_In_ PVOID Context,
123-
_In_ PTP_TIMER Timer
123+
_In_ PTP_TIMER
124124
)
125125
{
126-
Instance;
127-
Timer;
128126
STRU* pstruLogFilePath = (STRU*)Context;
129127
HANDLE hStdoutHandle = NULL;
130128
SECURITY_ATTRIBUTES saAttr = { 0 };

src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,14 @@ IN_PROCESS_APPLICATION::IN_PROCESS_APPLICATION(
3838
m_dotnetExeKnownLocation = knownLocation;
3939
}
4040

41-
const auto shadowCopyDirectory = FindParameter<PCWSTR>("ShadowCopyDirectory", pParameters, nParameters);
41+
const auto shadowCopyDirectory = FindParameter<PCWSTR>(s_shadowCopyDirectoryName, pParameters, nParameters);
4242
if (shadowCopyDirectory != nullptr)
4343
{
4444
m_shadowCopyDirectory = shadowCopyDirectory;
4545
}
4646

47+
m_shutdownTimeout = m_pConfig.get()->QueryShutdownTimeLimitInMS();
48+
4749
m_stringRedirectionOutput = std::make_shared<StringStreamRedirectionOutput>();
4850
}
4951

@@ -109,7 +111,6 @@ IN_PROCESS_APPLICATION::StopClr()
109111

110112
if (m_folderCleanupThread.joinable())
111113
{
112-
// Worker thread would wait for clr to finish and log error if required
113114
m_folderCleanupThread.join();
114115
}
115116

src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class IN_PROCESS_APPLICATION : public InProcessApplicationBase
179179
std::shared_ptr<StringStreamRedirectionOutput> m_stringRedirectionOutput;
180180

181181
inline static const LPCSTR s_exeLocationParameterName = "InProcessExeLocation";
182+
inline static const LPCSTR s_shadowCopyDirectoryName = "ShadowCopyDirectory";
182183

183184
VOID
184185
UnexpectedThreadExit(const ExecuteClrContext& context) const;

src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ HRESULT AppOfflineTrackingApplication::StartMonitoringAppOflineImpl()
4545
RETURN_IF_FAILED(m_fileWatcher->Create(m_applicationPath.c_str(),
4646
L"app_offline.htm",
4747
m_shadowCopyDirectory,
48-
this));
48+
this,
49+
m_shutdownTimeout));
4950

5051
return S_OK;
5152
}

src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class AppOfflineTrackingApplication: public APPLICATION
1515
: APPLICATION(application),
1616
m_applicationPath(application.GetApplicationPhysicalPath()),
1717
m_fileWatcher(nullptr),
18-
m_fAppOfflineProcessed(false)
18+
m_fAppOfflineProcessed(false),
19+
m_shutdownTimeout(120000) // default to 2 minutes
1920
{
2021
}
2122

@@ -40,6 +41,7 @@ class AppOfflineTrackingApplication: public APPLICATION
4041
// TODO protected
4142
bool m_detectedAppOffline;
4243
std::wstring m_shadowCopyDirectory;
44+
DWORD m_shutdownTimeout;
4345
private:
4446
HRESULT
4547
StartMonitoringAppOflineImpl();

src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ HRESULT
6565
FILE_WATCHER::Create(
6666
_In_ PCWSTR pszDirectoryToMonitor,
6767
_In_ PCWSTR pszFileNameToMonitor,
68-
_In_ std::wstring shadowCopyPath,
69-
_In_ AppOfflineTrackingApplication* pApplication
68+
_In_ const std::wstring& shadowCopyPath,
69+
_In_ AppOfflineTrackingApplication* pApplication,
70+
_In_ DWORD shutdownTimeout
7071
)
7172
{
7273
m_shadowCopyPath = shadowCopyPath;
@@ -309,7 +310,7 @@ HRESULT
309310
// Reset timer for dll checks
310311
LOG_INFO(L"Detected dll change, resetting timer callback which will eventually trigger shutdown.");
311312
m_Timer.CancelTimer();
312-
m_Timer.InitializeTimer(FILE_WATCHER::TimerCallback, this, 5000, 3000);
313+
m_Timer.InitializeTimer(FILE_WATCHER::TimerCallback, this, 5000, INFINITE);
313314
}
314315

315316
return S_OK;
@@ -329,10 +330,8 @@ FILE_WATCHER::TimerCallback(
329330
CopyAndShutdown((FILE_WATCHER*)Context);
330331
}
331332

332-
DWORD WINAPI FILE_WATCHER::CopyAndShutdown(LPVOID arg)
333+
DWORD WINAPI FILE_WATCHER::CopyAndShutdown(FILE_WATCHER* watcher)
333334
{
334-
auto watcher = (FILE_WATCHER*)arg;
335-
336335
// Only copy and shutdown once
337336
SRWExclusiveLock lock(watcher->m_copyLock);
338337
if (watcher->m_copied)
@@ -443,7 +442,7 @@ FILE_WATCHER::StopMonitor()
443442
PostQueuedCompletionStatus(m_hCompletionPort, 0, FILE_WATCHER_SHUTDOWN_KEY, NULL);
444443
WaitForMonitor(200);
445444

446-
if (m_fShadowCopyEnabled && m_pDoneCopyEvent != nullptr)
445+
if (m_fShadowCopyEnabled)
447446
{
448447
// If we are shadow copying, wait for the copying to finish.
449448
WaitForSingleObject(m_pDoneCopyEvent, 30000);

src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,10 @@ class FILE_WATCHER{
2828

2929
HRESULT Create(
3030
_In_ PCWSTR pszDirectoryToMonitor,
31-
3231
_In_ PCWSTR pszFileNameToMonitor,
33-
34-
_In_ std::wstring shadowCopyPath,
35-
36-
_In_ AppOfflineTrackingApplication *pApplication
32+
_In_ const std::wstring& shadowCopyPath,
33+
_In_ AppOfflineTrackingApplication *pApplication,
34+
_In_ DWORD shutdownTimeout
3735
);
3836

3937
static
@@ -50,7 +48,7 @@ class FILE_WATCHER{
5048
_In_ PVOID Context,
5149
_In_ PTP_TIMER Timer);
5250

53-
static DWORD WINAPI CopyAndShutdown(LPVOID);
51+
static DWORD WINAPI CopyAndShutdown(FILE_WATCHER* watcher);
5452

5553
HRESULT HandleChangeCompletion(DWORD cbCompletion);
5654

src/Servers/IIS/copyToIIS.ps1

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

0 commit comments

Comments
 (0)