Skip to content

Commit de562c6

Browse files
committed
make this feature good
1 parent 7e0a0e2 commit de562c6

File tree

17 files changed

+1214
-1259
lines changed

17 files changed

+1214
-1259
lines changed

src/Hosting/Hosting/src/Microsoft.AspNetCore.Hosting.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<ItemGroup>
1313
<Compile Include="$(SharedSourceRoot)RazorViews\*.cs" />
1414
<Compile Include="$(SharedSourceRoot)StackTrace\**\*.cs" />
15+
<Compile Include="$(SharedSourceRoot)ErrorPage\**\*.cs" />
1516
</ItemGroup>
1617

1718
<ItemGroup>

src/Hosting/Hosting/src/Resources.resx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,6 @@
117117
<resheader name="writer">
118118
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119119
</resheader>
120-
<data name="ErrorPageHtml_Title" xml:space="preserve">
121-
<value>Internal Server Error</value>
122-
</data>
123-
<data name="ErrorPageHtml_UnhandledException" xml:space="preserve">
124-
<value>An error occurred while starting the application.</value>
125-
</data>
126-
<data name="ErrorPageHtml_UnknownLocation" xml:space="preserve">
127-
<value>Unknown location</value>
128-
</data>
129120
<data name="WebHostBuilder_SingleInstance" xml:space="preserve">
130121
<value>WebHostBuilder allows creation only of a single instance of WebHost</value>
131122
</data>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class ServerErrorApplication : public PollingAppOfflineApplication
2727

2828
HRESULT CreateHandler(IHttpContext *pHttpContext, IREQUEST_HANDLER ** pRequestHandler) override
2929
{
30-
auto handler = std::make_unique<ServerErrorHandler>(*pHttpContext, 500ui16, 0ui16, "Internal Server Error", m_HR, m_moduleInstance, m_disableStartupPage, m_page, "");
30+
auto handler = std::make_unique<ServerErrorHandler>(*pHttpContext, 500ui16, 0ui16, "Internal Server Error", m_HR, m_moduleInstance, m_disableStartupPage, m_page, nullptr, 0);
3131
*pRequestHandler = handler.release();
3232
return S_OK;
3333
}

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

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@
1010
class ServerErrorHandler : public REQUEST_HANDLER
1111
{
1212
public:
13-
ServerErrorHandler(IHttpContext& pContext, USHORT statusCode, USHORT subStatusCode, std::string statusText, HRESULT hr, HINSTANCE module, bool disableStartupPage, int page, std::string errorPageContent) noexcept
13+
ServerErrorHandler(IHttpContext& pContext, USHORT statusCode, USHORT subStatusCode, std::string statusText, HRESULT hr, HINSTANCE module, bool disableStartupPage, int page, BYTE* content, int length) noexcept
1414
: REQUEST_HANDLER(pContext),
15-
m_pContext(pContext),
16-
m_HR(hr),
17-
m_disableStartupPage(disableStartupPage),
18-
m_statusCode(statusCode),
19-
m_subStatusCode(subStatusCode),
20-
m_statusText(std::move(statusText)),
21-
m_ExceptionInfoContent(std::move(errorPageContent)),
22-
m_page(page),
23-
m_moduleInstance(module)
15+
m_pContext(pContext),
16+
m_HR(hr),
17+
m_disableStartupPage(disableStartupPage),
18+
m_statusCode(statusCode),
19+
m_subStatusCode(subStatusCode),
20+
m_statusText(std::move(statusText)),
21+
m_ExceptionInfoContent(content),
22+
m_length(length),
23+
m_page(page),
24+
m_moduleInstance(module)
2425
{
2526
}
2627

@@ -34,14 +35,32 @@ class ServerErrorHandler : public REQUEST_HANDLER
3435
}
3536

3637
private:
37-
void WriteStaticResponse(IHttpContext& pContext, std::string &page, HRESULT hr, bool disableStartupErrorPage) const
38+
void WriteStaticResponse(IHttpContext& pContext, std::string& page, HRESULT hr, bool disableStartupErrorPage) const
3839
{
3940
if (disableStartupErrorPage)
4041
{
4142
pContext.GetResponse()->SetStatus(m_statusCode, m_statusText.c_str(), m_subStatusCode, E_FAIL);
4243
return;
4344
}
4445

46+
if (m_length > 0)
47+
{
48+
// TODO cleanup
49+
HTTP_DATA_CHUNK dataChunk = {};
50+
IHttpResponse* pResponse = pContext.GetResponse();
51+
pResponse->SetStatus(m_statusCode, m_statusText.c_str(), m_subStatusCode, hr, nullptr, true);
52+
pResponse->SetHeader("Content-Type",
53+
"text/html",
54+
(USHORT)strlen("text/html"),
55+
FALSE
56+
);
57+
dataChunk.DataChunkType = HttpDataChunkFromMemory;
58+
dataChunk.FromMemory.pBuffer = m_ExceptionInfoContent;
59+
dataChunk.FromMemory.BufferLength = static_cast<ULONG>(m_length);
60+
pResponse->WriteEntityChunkByReference(&dataChunk);
61+
return;
62+
}
63+
4564
HTTP_DATA_CHUNK dataChunk = {};
4665
IHttpResponse* pResponse = pContext.GetResponse();
4766
pResponse->SetStatus(m_statusCode, m_statusText.c_str(), m_subStatusCode, hr, nullptr, true);
@@ -74,22 +93,15 @@ class ServerErrorHandler : public REQUEST_HANDLER
7493
THROW_LAST_ERROR_IF_NULL(pTempData = static_cast<const char*>(LockResource(rcData)));
7594
data = std::string(pTempData, size);
7695

77-
if (page == 101) // TODO
78-
{
79-
auto additionalErrorLink = Environment::GetEnvironmentVariableValue(L"ANCM_ADDITIONAL_ERROR_PAGE_LINK");
80-
std::string additionalHtml;
81-
82-
if (additionalErrorLink.has_value())
83-
{
84-
additionalHtml = format("<a href=\"%S\"> <cite> %S </cite></a> and ", additionalErrorLink->c_str(), additionalErrorLink->c_str());
85-
}
96+
auto additionalErrorLink = Environment::GetEnvironmentVariableValue(L"ANCM_ADDITIONAL_ERROR_PAGE_LINK");
97+
std::string additionalHtml;
8698

87-
return format(data, additionalHtml.c_str());
88-
}
89-
else
99+
if (additionalErrorLink.has_value())
90100
{
91-
return format(data, m_ExceptionInfoContent.c_str());
101+
additionalHtml = format("<a href=\"%S\"> <cite> %S </cite></a> and ", additionalErrorLink->c_str(), additionalErrorLink->c_str());
92102
}
103+
104+
return format(data, additionalHtml.c_str());
93105
}
94106
catch (...)
95107
{
@@ -98,13 +110,14 @@ class ServerErrorHandler : public REQUEST_HANDLER
98110
}
99111
}
100112

101-
IHttpContext &m_pContext;
113+
IHttpContext& m_pContext;
102114
HRESULT m_HR;
103115
bool m_disableStartupPage;
104116
int m_page;
105117
HINSTANCE m_moduleInstance;
106118
USHORT m_statusCode;
107119
USHORT m_subStatusCode;
108120
std::string m_statusText;
109-
std::string m_ExceptionInfoContent;
121+
byte* m_ExceptionInfoContent;
122+
int m_length;
110123
};

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ class StartupExceptionApplication : public InProcessApplicationBase
1616
HINSTANCE moduleInstance,
1717
BOOL disableLogs,
1818
HRESULT hr,
19-
std::wstring errorPageContent)
19+
BYTE* errorPageContent,
20+
int length)
2021
: m_disableLogs(disableLogs),
2122
m_HR(hr),
2223
m_moduleInstance(moduleInstance),
2324
m_errorPageContent(errorPageContent),
25+
m_length(length),
2426
InProcessApplicationBase(pServer, pApplication)
2527
{
2628
}
@@ -29,22 +31,23 @@ class StartupExceptionApplication : public InProcessApplicationBase
2931

3032
HRESULT CreateHandler(IHttpContext *pHttpContext, IREQUEST_HANDLER ** pRequestHandler)
3133
{
32-
if (m_errorPageContent.length() > 0)
34+
if (m_length > 0)
3335
{
34-
*pRequestHandler = new ServerErrorHandler(*pHttpContext, 500, 30, "Internal Server Error", m_HR, m_moduleInstance, m_disableLogs, IN_PROCESS_RH_EXCEPTION_PAGE_HTML, to_multi_byte_string(m_errorPageContent, CP_UTF8));
36+
*pRequestHandler = new ServerErrorHandler(*pHttpContext, 500, 30, "Internal Server Error", m_HR, m_moduleInstance, m_disableLogs, IN_PROCESS_RH_EXCEPTION_PAGE_HTML, m_errorPageContent, m_length);
3537
}
3638
else
3739
{
38-
*pRequestHandler = new ServerErrorHandler(*pHttpContext, 500, 30, "Internal Server Error", m_HR, m_moduleInstance, m_disableLogs, IN_PROCESS_RH_STATIC_HTML, "");
40+
*pRequestHandler = new ServerErrorHandler(*pHttpContext, 500, 30, "Internal Server Error", m_HR, m_moduleInstance, m_disableLogs, IN_PROCESS_RH_STATIC_HTML, nullptr, 0);
3941
}
4042

4143
return S_OK;
4244
}
4345

4446
private:
45-
std::wstring m_errorPageContent;
47+
BYTE* m_errorPageContent;
4648
BOOL m_disableLogs;
4749
HRESULT m_HR;
4850
HINSTANCE m_moduleInstance;
51+
int m_length;
4952
};
5053

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ HINSTANCE g_hWinHttpModule;
2828
HINSTANCE g_hAspNetCoreModule;
2929
HANDLE g_hEventLog = NULL;
3030
bool g_fInProcessApplicationCreated = false;
31-
std::wstring g_errorPageContent;
31+
BYTE* g_errorPageContent;
32+
int g_errorPageLength;
3233
HINSTANCE g_hServerModule;
3334

3435
HRESULT
@@ -129,7 +130,7 @@ CreateApplication(
129130
std::unique_ptr<InProcessOptions> options;
130131
THROW_IF_FAILED(InProcessOptions::Create(*pServer, pSite, *pHttpApplication, options));
131132
// Set the currently running application to a fake application that returns startup exceptions.
132-
auto pErrorApplication = std::make_unique<StartupExceptionApplication>(*pServer, *pHttpApplication, g_hServerModule, options->QueryDisableStartUpErrorPage(), hr, g_errorPageContent);
133+
auto pErrorApplication = std::make_unique<StartupExceptionApplication>(*pServer, *pHttpApplication, g_hServerModule, options->QueryDisableStartUpErrorPage(), hr, g_errorPageContent, g_errorPageLength);
133134

134135
RETURN_IF_FAILED(pErrorApplication->StartMonitoringAppOffline());
135136
*ppApplication = pErrorApplication.release();

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
#include "requesthandler_config.h"
77

88
extern bool g_fInProcessApplicationCreated;
9-
extern std::wstring g_errorPageContent;
9+
extern BYTE* g_errorPageContent;
10+
extern int g_errorPageLength;
1011

1112
//
1213
// Initialization export
@@ -507,9 +508,11 @@ set_main_handler(_In_ hostfxr_main_fn main)
507508

508509
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
509510
VOID
510-
http_set_startup_error_page_content(_In_ LPCWSTR errorPageContent)
511+
http_set_startup_error_page_content(_In_ byte* errorPageContent, int length)
511512
{
512-
g_errorPageContent = std::wstring(errorPageContent);
513+
g_errorPageContent = new BYTE[length];
514+
g_errorPageLength = length;
515+
memcpy(g_errorPageContent, errorPageContent, length);
513516
}
514517

515518
// End of export

src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ FORWARDING_HANDLER::ExecuteRequestHandler()
302302
}
303303
else if (fFailedToStartKestrel && !m_pApplication->QueryConfig()->QueryDisableStartUpErrorPage())
304304
{
305-
ServerErrorHandler handler(*m_pW3Context, 502, 5, "Bad Gateway", hr, g_hOutOfProcessRHModule, m_pApplication->QueryConfig()->QueryDisableStartUpErrorPage(), OUT_OF_PROCESS_RH_STATIC_HTML, "");
305+
ServerErrorHandler handler(*m_pW3Context, 502, 5, "Bad Gateway", hr, g_hOutOfProcessRHModule, m_pApplication->QueryConfig()->QueryDisableStartUpErrorPage(), OUT_OF_PROCESS_RH_STATIC_HTML, nullptr, 0);
306306
handler.ExecuteRequestHandler();
307307
}
308308
else

src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
<Reference Include="System.IO.Pipelines" />
3838
<Reference Include="System.Security.Principal.Windows" />
3939
<Compile Include="$(SharedSourceRoot)StackTrace\**\*.cs" />
40+
<Compile Include="$(SharedSourceRoot)RazorViews\*.cs" />
41+
<Compile Include="$(SharedSourceRoot)ErrorPage\*.cs" />
4042
</ItemGroup>
4143

4244
<Import Project="..\..\build\assets.props" />

src/Servers/IIS/IIS/src/NativeMethods.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ private static extern unsafe int http_websockets_write_bytes(
148148
private static extern int http_get_authentication_information(IntPtr pInProcessHandler, [MarshalAs(UnmanagedType.BStr)] out string authType, out IntPtr token);
149149

150150
[DllImport(AspNetCoreModuleDll)]
151-
private static extern int http_set_startup_error_page_content([MarshalAs(UnmanagedType.LPWStr)]string content);
151+
private static extern unsafe int http_set_startup_error_page_content(byte* content, int contentLength);
152152

153153
public static void HttpPostCompletion(IntPtr pInProcessHandler, int cbBytes)
154154
{
@@ -300,9 +300,12 @@ public static void HttpGetAuthenticationInformation(IntPtr pInProcessHandler, ou
300300
Validate(http_get_authentication_information(pInProcessHandler, out authType, out token));
301301
}
302302

303-
public static void HttpSetStartupErrorPageContent(string content)
303+
public static unsafe void HttpSetStartupErrorPageContent(byte[] content)
304304
{
305-
http_set_startup_error_page_content(content);
305+
fixed(byte* bytePtr = content)
306+
{
307+
http_set_startup_error_page_content(bytePtr, content.Length);
308+
}
306309
}
307310

308311
private static void Validate(int hr)

0 commit comments

Comments
 (0)