Skip to content

Commit cc77a36

Browse files
committed
fix #128: graceful failure on configuration errors
1 parent 9335de0 commit cc77a36

10 files changed

+115
-8
lines changed

Diff for: src/iisnode/cmoduleconfiguration.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ class CModuleConfiguration : public IHttpStoredContext
3737
static HRESULT GetConfigSection(IHttpContext* context, IAppHostElement** section, OLECHAR* configElement = L"system.webServer/iisnode");
3838
static HRESULT GetString(IAppHostElement* section, LPCWSTR propertyName, LPWSTR* value);
3939
static HRESULT GetBOOL(IAppHostElement* section, LPCWSTR propertyName, BOOL* value);
40-
static HRESULT GetDWORD(IAppHostElement* section, LPCWSTR propertyName, DWORD* value);
41-
static HRESULT GetConfig(IHttpContext* context, CModuleConfiguration** config);
40+
static HRESULT GetDWORD(IAppHostElement* section, LPCWSTR propertyName, DWORD* value);
4241

4342
CModuleConfiguration();
4443
~CModuleConfiguration();
@@ -47,6 +46,8 @@ class CModuleConfiguration : public IHttpStoredContext
4746

4847
static HRESULT Initialize(IHttpServer* server, HTTP_MODULE_ID moduleId);
4948

49+
static HRESULT GetConfig(IHttpContext* context, CModuleConfiguration** config);
50+
5051
static DWORD GetAsyncCompletionThreadCount(IHttpContext* ctx);
5152
static DWORD GetNodeProcessCountPerApplication(IHttpContext* ctx);
5253
static LPCTSTR GetNodeProcessCommandLine(IHttpContext* ctx);

Diff for: src/iisnode/cnodeapplicationmanager.cpp

+14-6
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,25 @@ CNodeApplicationManager::CNodeApplicationManager(IHttpServer* server, HTTP_MODUL
1111
HRESULT CNodeApplicationManager::Initialize(IHttpContext* context)
1212
{
1313
HRESULT hr = S_OK;
14+
CModuleConfiguration *config;
1415

1516
if (!this->initialized)
1617
{
17-
ENTER_SRW_EXCLUSIVE(this->srwlock)
18+
if (S_OK != CModuleConfiguration::GetConfig(context, &config))
19+
{
20+
hr = IISNODE_ERROR_UNABLE_TO_READ_CONFIGURATION;
21+
}
22+
else
23+
{
24+
ENTER_SRW_EXCLUSIVE(this->srwlock)
1825

19-
if (!this->initialized)
20-
{
21-
hr = this->InitializeCore(context);
22-
}
26+
if (!this->initialized)
27+
{
28+
hr = this->InitializeCore(context);
29+
}
2330

24-
LEAVE_SRW_EXCLUSIVE(this->srwlock)
31+
LEAVE_SRW_EXCLUSIVE(this->srwlock)
32+
}
2533
}
2634

2735
return hr;

Diff for: src/iisnode/cprotocolbridge.cpp

+56
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,64 @@ HRESULT CProtocolBridge::PostponeProcessing(CNodeHttpStoredContext* context, DWO
1010
return async->SetTimer(context->GetAsyncContext(), &delay);
1111
}
1212

13+
#define LOCAL127 0x0100007F // 127.0.0.1
14+
15+
BOOL CProtocolBridge::IsLocalCall(IHttpContext* ctx)
16+
{
17+
PSOCKADDR src = ctx->GetRequest()->GetRemoteAddress();
18+
PSOCKADDR dest = ctx->GetRequest()->GetLocalAddress();
19+
20+
if (AF_INET == src->sa_family && AF_INET == dest->sa_family)
21+
{
22+
DWORD srcAddress = ntohl(((PSOCKADDR_IN)src)->sin_addr.s_addr);
23+
DWORD destAddress = ntohl(((PSOCKADDR_IN)dest)->sin_addr.s_addr);
24+
25+
return srcAddress == destAddress || LOCAL127 == srcAddress || LOCAL127 == destAddress;
26+
}
27+
else if (AF_INET6 == src->sa_family && AF_INET6 == dest->sa_family)
28+
{
29+
IN6_ADDR* srcAddress = &((PSOCKADDR_IN6)src)->sin6_addr;
30+
IN6_ADDR* destAddress = &((PSOCKADDR_IN6)dest)->sin6_addr;
31+
32+
if (0 == memcmp(srcAddress, destAddress, sizeof IN6_ADDR))
33+
{
34+
return TRUE;
35+
}
36+
37+
if (IN6_IS_ADDR_LOOPBACK(srcAddress) || IN6_IS_ADDR_LOOPBACK(destAddress))
38+
{
39+
return TRUE;
40+
}
41+
}
42+
43+
return FALSE;
44+
}
45+
1346
BOOL CProtocolBridge::SendIisnodeError(IHttpContext* httpCtx, HRESULT hr)
1447
{
48+
if (IISNODE_ERROR_UNABLE_TO_READ_CONFIGURATION == hr)
49+
{
50+
if (CProtocolBridge::IsLocalCall(httpCtx))
51+
{
52+
CProtocolBridge::SendSyncResponse(
53+
httpCtx,
54+
200,
55+
"OK",
56+
hr,
57+
TRUE,
58+
"iisnode was unable to read the configuration file. Make sure the web.config file syntax is correct. In particular, verify the "
59+
" <a href=""https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config"">"
60+
"iisnode configuration section</a> matches the expected schema. The schema of the iisnode section that your version of iisnode requiries is stored in the "
61+
"%systemroot%\\system32\\inetsrv\\config\\schema\\iisnode_schema.xml file.");
62+
63+
return TRUE;
64+
}
65+
else
66+
{
67+
return FALSE;
68+
}
69+
}
70+
1571
if (!CModuleConfiguration::GetDevErrorsEnabled(httpCtx))
1672
{
1773
return FALSE;

Diff for: src/iisnode/cprotocolbridge.h

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class CProtocolBridge
1212
static HRESULT PostponeProcessing(CNodeHttpStoredContext* context, DWORD dueTime);
1313
static HRESULT EnsureBuffer(CNodeHttpStoredContext* context);
1414
static HRESULT FinalizeResponseCore(CNodeHttpStoredContext * context, REQUEST_NOTIFICATION_STATUS status, HRESULT error, CNodeEventProvider* log, PCWSTR etw, UCHAR level);
15+
static BOOL IsLocalCall(IHttpContext* ctx);
1516

1617
// processing stages
1718
static void WINAPI ChildContextCompleted(DWORD error, DWORD bytesTransfered, LPOVERLAPPED overlapped);

Diff for: src/iisnode/errors.h

+1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
#define IISNODE_ERROR_UNABLE_TO_START_NODE_EXE 1028L
99
#define IISNODE_ERROR_UNABLE_TO_CREATE_LOG_FILE 1029L
1010
#define IISNODE_ERROR_UNABLE_TO_CREATE_DEBUGGER_FILES 1030L
11+
#define IISNODE_ERROR_UNABLE_TO_READ_CONFIGURATION 1031L
1112

1213
#endif

Diff for: src/iisnode/iisnode.vcxproj

+3
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ copy /y $(ProjectDir)\..\config\* $(ProjectDir)\..\..\build\$(Configuration)\$(P
249249
<None Include="..\..\test\functional\tests\112_dev_errors.js" />
250250
<None Include="..\..\test\functional\tests\113_encoding.js" />
251251
<None Include="..\..\test\functional\tests\115_customheaders.js" />
252+
<None Include="..\..\test\functional\tests\116_configerror.js" />
252253
<None Include="..\..\test\functional\tests\200_samples.bat" />
253254
<None Include="..\..\test\functional\tests\node_modules\iisnodeassert.js" />
254255
<None Include="..\..\test\functional\tests\parts\106_autoupdate_first.js" />
@@ -288,6 +289,8 @@ copy /y $(ProjectDir)\..\config\* $(ProjectDir)\..\..\build\$(Configuration)\$(P
288289
<None Include="..\..\test\functional\www\113_encoding\web.config" />
289290
<None Include="..\..\test\functional\www\115_customheaders\hello.js" />
290291
<None Include="..\..\test\functional\www\115_customheaders\web.config" />
292+
<None Include="..\..\test\functional\www\116_configerror\hello.js" />
293+
<None Include="..\..\test\functional\www\116_configerror\web.config" />
291294
<None Include="..\..\test\performance\client.bat" />
292295
<None Include="..\..\test\performance\localRun.bat" />
293296
<None Include="..\..\test\performance\readme.txt" />

Diff for: src/iisnode/iisnode.vcxproj.filters

+12
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@
114114
<Filter Include="Tests\functional\www\115_customheaders">
115115
<UniqueIdentifier>{994959e7-12c0-43f7-a10b-24899813a857}</UniqueIdentifier>
116116
</Filter>
117+
<Filter Include="Tests\functional\www\116_configerror">
118+
<UniqueIdentifier>{500f40cf-c2f5-4264-b061-b4f1e59f50f5}</UniqueIdentifier>
119+
</Filter>
117120
</ItemGroup>
118121
<ItemGroup>
119122
<ClCompile Include="main.cpp">
@@ -492,6 +495,15 @@
492495
<None Include="..\..\test\functional\www\115_customheaders\web.config">
493496
<Filter>Tests\functional\www\115_customheaders</Filter>
494497
</None>
498+
<None Include="..\..\test\functional\tests\116_configerror.js">
499+
<Filter>Tests\functional\tests</Filter>
500+
</None>
501+
<None Include="..\..\test\functional\www\116_configerror\hello.js">
502+
<Filter>Tests\functional\www\116_configerror</Filter>
503+
</None>
504+
<None Include="..\..\test\functional\www\116_configerror\web.config">
505+
<Filter>Tests\functional\www\116_configerror</Filter>
506+
</None>
495507
</ItemGroup>
496508
<ItemGroup>
497509
<ResourceCompile Include="iisnode.rc" />

Diff for: test/functional/tests/116_configerror.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
Local request to iisnode with a configuration syntax error returns a friendly 200 response
3+
*/
4+
5+
var iisnodeassert = require("iisnodeassert");
6+
7+
iisnodeassert.sequence([
8+
iisnodeassert.get(10000, "/116_configerror/hello.js", 200)
9+
]);

Diff for: test/functional/www/116_configerror/hello.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
var http = require('http');
2+
3+
http.createServer(function (req, res) {
4+
res.writeHead(200, {'Content-Type': 'text/html'});
5+
res.end('Hello, world!');
6+
}).listen(process.env.PORT);

Diff for: test/functional/www/116_configerror/web.config

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<configuration>
2+
<system.webServer>
3+
<handlers>
4+
<add name="iisnode" path="hello.js" verb="*" modules="iisnode" />
5+
</handlers>
6+
7+
<iisnode idontexist="12" />
8+
9+
</system.webServer>
10+
</configuration>

0 commit comments

Comments
 (0)