fix #128: graceful failure on configuration errors

This commit is contained in:
Tomasz Janczuk 2012-01-04 12:46:29 -08:00
Родитель 9335de0d50
Коммит cc77a365a8
10 изменённых файлов: 115 добавлений и 8 удалений

Просмотреть файл

@ -37,8 +37,7 @@ private:
static HRESULT GetConfigSection(IHttpContext* context, IAppHostElement** section, OLECHAR* configElement = L"system.webServer/iisnode");
static HRESULT GetString(IAppHostElement* section, LPCWSTR propertyName, LPWSTR* value);
static HRESULT GetBOOL(IAppHostElement* section, LPCWSTR propertyName, BOOL* value);
static HRESULT GetDWORD(IAppHostElement* section, LPCWSTR propertyName, DWORD* value);
static HRESULT GetConfig(IHttpContext* context, CModuleConfiguration** config);
static HRESULT GetDWORD(IAppHostElement* section, LPCWSTR propertyName, DWORD* value);
CModuleConfiguration();
~CModuleConfiguration();
@ -47,6 +46,8 @@ public:
static HRESULT Initialize(IHttpServer* server, HTTP_MODULE_ID moduleId);
static HRESULT GetConfig(IHttpContext* context, CModuleConfiguration** config);
static DWORD GetAsyncCompletionThreadCount(IHttpContext* ctx);
static DWORD GetNodeProcessCountPerApplication(IHttpContext* ctx);
static LPCTSTR GetNodeProcessCommandLine(IHttpContext* ctx);

Просмотреть файл

@ -11,17 +11,25 @@ CNodeApplicationManager::CNodeApplicationManager(IHttpServer* server, HTTP_MODUL
HRESULT CNodeApplicationManager::Initialize(IHttpContext* context)
{
HRESULT hr = S_OK;
CModuleConfiguration *config;
if (!this->initialized)
{
ENTER_SRW_EXCLUSIVE(this->srwlock)
if (S_OK != CModuleConfiguration::GetConfig(context, &config))
{
hr = IISNODE_ERROR_UNABLE_TO_READ_CONFIGURATION;
}
else
{
ENTER_SRW_EXCLUSIVE(this->srwlock)
if (!this->initialized)
{
hr = this->InitializeCore(context);
}
if (!this->initialized)
{
hr = this->InitializeCore(context);
}
LEAVE_SRW_EXCLUSIVE(this->srwlock)
LEAVE_SRW_EXCLUSIVE(this->srwlock)
}
}
return hr;

Просмотреть файл

@ -10,8 +10,64 @@ HRESULT CProtocolBridge::PostponeProcessing(CNodeHttpStoredContext* context, DWO
return async->SetTimer(context->GetAsyncContext(), &delay);
}
#define LOCAL127 0x0100007F // 127.0.0.1
BOOL CProtocolBridge::IsLocalCall(IHttpContext* ctx)
{
PSOCKADDR src = ctx->GetRequest()->GetRemoteAddress();
PSOCKADDR dest = ctx->GetRequest()->GetLocalAddress();
if (AF_INET == src->sa_family && AF_INET == dest->sa_family)
{
DWORD srcAddress = ntohl(((PSOCKADDR_IN)src)->sin_addr.s_addr);
DWORD destAddress = ntohl(((PSOCKADDR_IN)dest)->sin_addr.s_addr);
return srcAddress == destAddress || LOCAL127 == srcAddress || LOCAL127 == destAddress;
}
else if (AF_INET6 == src->sa_family && AF_INET6 == dest->sa_family)
{
IN6_ADDR* srcAddress = &((PSOCKADDR_IN6)src)->sin6_addr;
IN6_ADDR* destAddress = &((PSOCKADDR_IN6)dest)->sin6_addr;
if (0 == memcmp(srcAddress, destAddress, sizeof IN6_ADDR))
{
return TRUE;
}
if (IN6_IS_ADDR_LOOPBACK(srcAddress) || IN6_IS_ADDR_LOOPBACK(destAddress))
{
return TRUE;
}
}
return FALSE;
}
BOOL CProtocolBridge::SendIisnodeError(IHttpContext* httpCtx, HRESULT hr)
{
if (IISNODE_ERROR_UNABLE_TO_READ_CONFIGURATION == hr)
{
if (CProtocolBridge::IsLocalCall(httpCtx))
{
CProtocolBridge::SendSyncResponse(
httpCtx,
200,
"OK",
hr,
TRUE,
"iisnode was unable to read the configuration file. Make sure the web.config file syntax is correct. In particular, verify the "
" <a href=""https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config"">"
"iisnode configuration section</a> matches the expected schema. The schema of the iisnode section that your version of iisnode requiries is stored in the "
"%systemroot%\\system32\\inetsrv\\config\\schema\\iisnode_schema.xml file.");
return TRUE;
}
else
{
return FALSE;
}
}
if (!CModuleConfiguration::GetDevErrorsEnabled(httpCtx))
{
return FALSE;

Просмотреть файл

@ -12,6 +12,7 @@ private:
static HRESULT PostponeProcessing(CNodeHttpStoredContext* context, DWORD dueTime);
static HRESULT EnsureBuffer(CNodeHttpStoredContext* context);
static HRESULT FinalizeResponseCore(CNodeHttpStoredContext * context, REQUEST_NOTIFICATION_STATUS status, HRESULT error, CNodeEventProvider* log, PCWSTR etw, UCHAR level);
static BOOL IsLocalCall(IHttpContext* ctx);
// processing stages
static void WINAPI ChildContextCompleted(DWORD error, DWORD bytesTransfered, LPOVERLAPPED overlapped);

Просмотреть файл

@ -8,5 +8,6 @@
#define IISNODE_ERROR_UNABLE_TO_START_NODE_EXE 1028L
#define IISNODE_ERROR_UNABLE_TO_CREATE_LOG_FILE 1029L
#define IISNODE_ERROR_UNABLE_TO_CREATE_DEBUGGER_FILES 1030L
#define IISNODE_ERROR_UNABLE_TO_READ_CONFIGURATION 1031L
#endif

Просмотреть файл

@ -249,6 +249,7 @@ copy /y $(ProjectDir)\..\config\* $(ProjectDir)\..\..\build\$(Configuration)\$(P
<None Include="..\..\test\functional\tests\112_dev_errors.js" />
<None Include="..\..\test\functional\tests\113_encoding.js" />
<None Include="..\..\test\functional\tests\115_customheaders.js" />
<None Include="..\..\test\functional\tests\116_configerror.js" />
<None Include="..\..\test\functional\tests\200_samples.bat" />
<None Include="..\..\test\functional\tests\node_modules\iisnodeassert.js" />
<None Include="..\..\test\functional\tests\parts\106_autoupdate_first.js" />
@ -288,6 +289,8 @@ copy /y $(ProjectDir)\..\config\* $(ProjectDir)\..\..\build\$(Configuration)\$(P
<None Include="..\..\test\functional\www\113_encoding\web.config" />
<None Include="..\..\test\functional\www\115_customheaders\hello.js" />
<None Include="..\..\test\functional\www\115_customheaders\web.config" />
<None Include="..\..\test\functional\www\116_configerror\hello.js" />
<None Include="..\..\test\functional\www\116_configerror\web.config" />
<None Include="..\..\test\performance\client.bat" />
<None Include="..\..\test\performance\localRun.bat" />
<None Include="..\..\test\performance\readme.txt" />

Просмотреть файл

@ -114,6 +114,9 @@
<Filter Include="Tests\functional\www\115_customheaders">
<UniqueIdentifier>{994959e7-12c0-43f7-a10b-24899813a857}</UniqueIdentifier>
</Filter>
<Filter Include="Tests\functional\www\116_configerror">
<UniqueIdentifier>{500f40cf-c2f5-4264-b061-b4f1e59f50f5}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
@ -492,6 +495,15 @@
<None Include="..\..\test\functional\www\115_customheaders\web.config">
<Filter>Tests\functional\www\115_customheaders</Filter>
</None>
<None Include="..\..\test\functional\tests\116_configerror.js">
<Filter>Tests\functional\tests</Filter>
</None>
<None Include="..\..\test\functional\www\116_configerror\hello.js">
<Filter>Tests\functional\www\116_configerror</Filter>
</None>
<None Include="..\..\test\functional\www\116_configerror\web.config">
<Filter>Tests\functional\www\116_configerror</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="iisnode.rc" />

Просмотреть файл

@ -0,0 +1,9 @@
/*
Local request to iisnode with a configuration syntax error returns a friendly 200 response
*/
var iisnodeassert = require("iisnodeassert");
iisnodeassert.sequence([
iisnodeassert.get(10000, "/116_configerror/hello.js", 200)
]);

Просмотреть файл

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

Просмотреть файл

@ -0,0 +1,10 @@
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="hello.js" verb="*" modules="iisnode" />
</handlers>
<iisnode idontexist="12" />
</system.webServer>
</configuration>