зеркало из https://github.com/Azure/iisnode.git
fix #87: provide access to iis server variables to the node.js application
This commit is contained in:
Родитель
b5f955727b
Коммит
6e68c03e5b
|
@ -52,5 +52,6 @@ Details at http://learn.iis.net/page.aspx/241/configuration-extensibility/
|
|||
<attribute name="flushResponse" type="bool" defaultValue="false"/>
|
||||
<attribute name="watchedFiles" type="string" defaultValue="*.js"/>
|
||||
<attribute name="enableXFF" type="bool" defaultValue="false"/>
|
||||
<attribute name="promoteServerVars" type="string" defaultValue=""/>
|
||||
</sectionSchema>
|
||||
</configSchema>
|
||||
|
|
|
@ -52,5 +52,6 @@ Details at http://learn.iis.net/page.aspx/241/configuration-extensibility/
|
|||
<attribute name="flushResponse" type="bool" defaultValue="false"/>
|
||||
<attribute name="watchedFiles" type="string" defaultValue="*.js"/>
|
||||
<attribute name="enableXFF" type="bool" defaultValue="false"/>
|
||||
<attribute name="promoteServerVars" type="string" defaultValue=""/>
|
||||
</sectionSchema>
|
||||
</configSchema>
|
||||
|
|
|
@ -94,6 +94,8 @@ HRESULT CHttpProtocol::SerializeRequestHeaders(CNodeHttpStoredContext* ctx, void
|
|||
DWORD remoteHostSize = INET6_ADDRSTRLEN + 1;
|
||||
char remoteHost[INET6_ADDRSTRLEN + 1];
|
||||
BOOL addXFF;
|
||||
char** serverVars;
|
||||
int serverVarCount;
|
||||
|
||||
CheckNull(ctx);
|
||||
CheckNull(result);
|
||||
|
@ -107,7 +109,8 @@ HRESULT CHttpProtocol::SerializeRequestHeaders(CNodeHttpStoredContext* ctx, void
|
|||
IHttpRequest* request = context->GetRequest();
|
||||
HTTP_REQUEST* raw = request->GetRawHttpRequest();
|
||||
USHORT major, minor;
|
||||
char tmp[256];
|
||||
const int tmpSize = 256;
|
||||
char tmp[tmpSize];
|
||||
PCSTR method = request->GetHttpMethod();
|
||||
|
||||
ErrorIf(NULL == (*result = context->AllocateRequestMemory(bufferLength)), ERROR_NOT_ENOUGH_MEMORY);
|
||||
|
@ -192,6 +195,24 @@ HRESULT CHttpProtocol::SerializeRequestHeaders(CNodeHttpStoredContext* ctx, void
|
|||
CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset));
|
||||
}
|
||||
|
||||
// promote server variables
|
||||
|
||||
CheckError(CModuleConfiguration::GetPromoteServerVars(context, &serverVars, &serverVarCount));
|
||||
while (serverVarCount)
|
||||
{
|
||||
serverVarCount--;
|
||||
PCSTR varValue;
|
||||
DWORD varValueLength;
|
||||
if (S_OK == context->GetServerVariable(serverVars[serverVarCount], &varValue, &varValueLength))
|
||||
{
|
||||
CheckError(CHttpProtocol::Append(context, "X-iisnode-", 10, result, &bufferLength, &offset));
|
||||
CheckError(CHttpProtocol::Append(context, serverVars[serverVarCount], 0, result, &bufferLength, &offset));
|
||||
CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset));
|
||||
CheckError(CHttpProtocol::Append(context, varValue, varValueLength, result, &bufferLength, &offset));
|
||||
CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset));
|
||||
}
|
||||
}
|
||||
|
||||
// CRLF
|
||||
|
||||
CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset));
|
||||
|
|
|
@ -7,7 +7,7 @@ HTTP_MODULE_ID CModuleConfiguration::moduleId = NULL;
|
|||
CModuleConfiguration::CModuleConfiguration()
|
||||
: nodeProcessCommandLine(NULL), logDirectoryNameSuffix(NULL), debuggerPathSegment(NULL),
|
||||
debugPortRange(NULL), debugPortStart(0), debugPortEnd(0), node_env(NULL), watchedFiles(NULL),
|
||||
enableXFF(FALSE)
|
||||
enableXFF(FALSE), promoteServerVars(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,20 @@ CModuleConfiguration::~CModuleConfiguration()
|
|||
delete this->watchedFiles;
|
||||
this->watchedFiles = NULL;
|
||||
}
|
||||
|
||||
if (NULL != this->promoteServerVars)
|
||||
{
|
||||
for (int i = 0; i < this->promoteServerVarsCount; i++)
|
||||
{
|
||||
if (this->promoteServerVars[i])
|
||||
{
|
||||
delete [] this->promoteServerVars[i];
|
||||
}
|
||||
}
|
||||
|
||||
delete [] this->promoteServerVars;
|
||||
this->promoteServerVars = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CModuleConfiguration::Initialize(IHttpServer* server, HTTP_MODULE_ID moduleId)
|
||||
|
@ -430,7 +444,10 @@ HRESULT CModuleConfiguration::GetConfig(IHttpContext* context, CModuleConfigurat
|
|||
IAppHostElement* section = NULL;
|
||||
LPWSTR commandLine = NULL;
|
||||
size_t i;
|
||||
|
||||
size_t varLength;
|
||||
LPWSTR serverVars = NULL;
|
||||
LPWSTR start, end;
|
||||
wchar_t terminator;
|
||||
CheckNull(config);
|
||||
|
||||
*config = (CModuleConfiguration*)context->GetMetadata()->GetModuleContextContainer()->GetModuleContext(moduleId);
|
||||
|
@ -461,15 +478,80 @@ HRESULT CModuleConfiguration::GetConfig(IHttpContext* context, CModuleConfigurat
|
|||
CheckError(GetBOOL(section, L"debuggingEnabled", &c->debuggingEnabled));
|
||||
CheckError(GetString(section, L"node_env", &c->node_env));
|
||||
CheckError(GetString(section, L"debuggerPortRange", &c->debugPortRange));
|
||||
CheckError(GetString(section, L"watchedFiles", &c->watchedFiles));
|
||||
CheckError(GetBOOL(section, L"enableXFF", &c->enableXFF));
|
||||
|
||||
// debuggerPathSegment
|
||||
|
||||
CheckError(GetString(section, L"debuggerPathSegment", &c->debuggerPathSegment));
|
||||
c->debuggerPathSegmentLength = wcslen(c->debuggerPathSegment);
|
||||
|
||||
// nodeProcessCommandLine
|
||||
|
||||
CheckError(GetString(section, L"nodeProcessCommandLine", &commandLine));
|
||||
ErrorIf(NULL == (c->nodeProcessCommandLine = new char[MAX_PATH]), ERROR_NOT_ENOUGH_MEMORY);
|
||||
ErrorIf(0 != wcstombs_s(&i, c->nodeProcessCommandLine, (size_t)MAX_PATH, commandLine, _TRUNCATE), ERROR_INVALID_PARAMETER);
|
||||
delete [] commandLine;
|
||||
commandLine = NULL;
|
||||
CheckError(GetString(section, L"watchedFiles", &c->watchedFiles));
|
||||
CheckError(GetBOOL(section, L"enableXFF", &c->enableXFF));
|
||||
|
||||
// promoteServerVars
|
||||
|
||||
CheckError(GetString(section, L"promoteServerVars", &serverVars));
|
||||
if (*serverVars == L'\0')
|
||||
{
|
||||
c->promoteServerVarsCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine number of server variables
|
||||
|
||||
c->promoteServerVarsCount = 1;
|
||||
start = serverVars;
|
||||
while (*start)
|
||||
{
|
||||
if (L',' == *start)
|
||||
{
|
||||
c->promoteServerVarsCount++;
|
||||
}
|
||||
|
||||
start++;
|
||||
}
|
||||
|
||||
// tokenize server variable names (comma delimited list)
|
||||
|
||||
ErrorIf(NULL == (c->promoteServerVars = new char*[c->promoteServerVarsCount]), ERROR_NOT_ENOUGH_MEMORY);
|
||||
RtlZeroMemory(c->promoteServerVars, c->promoteServerVarsCount * sizeof(char*));
|
||||
|
||||
i = 0;
|
||||
end = serverVars;
|
||||
while (*end)
|
||||
{
|
||||
start = end;
|
||||
while (*end && L',' != *end)
|
||||
{
|
||||
end++;
|
||||
}
|
||||
|
||||
if (start != end)
|
||||
{
|
||||
terminator = *end;
|
||||
*end = L'\0';
|
||||
ErrorIf(0 != wcstombs_s(&varLength, NULL, 0, start, _TRUNCATE), ERROR_CAN_NOT_COMPLETE);
|
||||
ErrorIf(NULL == (c->promoteServerVars[i] = new char[varLength]), ERROR_NOT_ENOUGH_MEMORY);
|
||||
ErrorIf(0 != wcstombs_s(&varLength, c->promoteServerVars[i], varLength, start, _TRUNCATE), ERROR_CAN_NOT_COMPLETE);
|
||||
i++;
|
||||
*end = terminator;
|
||||
}
|
||||
|
||||
if (*end)
|
||||
{
|
||||
end++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete [] serverVars;
|
||||
serverVars = NULL;
|
||||
|
||||
section->Release();
|
||||
section = NULL;
|
||||
|
@ -518,6 +600,12 @@ Error:
|
|||
commandLine = NULL;
|
||||
}
|
||||
|
||||
if (NULL != serverVars)
|
||||
{
|
||||
delete [] serverVars;
|
||||
serverVars = NULL;
|
||||
}
|
||||
|
||||
if (NULL != c)
|
||||
{
|
||||
delete c;
|
||||
|
@ -670,7 +758,7 @@ HRESULT CModuleConfiguration::GetDebugPortRange(IHttpContext* ctx, DWORD* start,
|
|||
CheckNull(end);
|
||||
|
||||
CModuleConfiguration* c = NULL;
|
||||
GetConfig(ctx, &c);
|
||||
CheckError(GetConfig(ctx, &c));
|
||||
|
||||
if (0 == c->debugPortStart)
|
||||
{
|
||||
|
@ -705,3 +793,21 @@ Error:
|
|||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CModuleConfiguration::GetPromoteServerVars(IHttpContext* ctx, char*** vars, int* count)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
CheckNull(vars);
|
||||
CheckNull(count);
|
||||
|
||||
CModuleConfiguration* c = NULL;
|
||||
CheckError(GetConfig(ctx, &c));
|
||||
|
||||
*vars = c->promoteServerVars;
|
||||
*count = c->promoteServerVarsCount;
|
||||
|
||||
return S_OK;
|
||||
Error:
|
||||
return hr;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ private:
|
|||
DWORD maxNamedPipeConnectionPoolSize;
|
||||
DWORD maxNamedPipePooledConnectionAge;
|
||||
BOOL enableXFF;
|
||||
char** promoteServerVars;
|
||||
int promoteServerVarsCount;
|
||||
|
||||
static IHttpServer* server;
|
||||
static HTTP_MODULE_ID moduleId;
|
||||
|
@ -78,6 +80,7 @@ public:
|
|||
static DWORD GetMaxNamedPipeConnectionPoolSize(IHttpContext* ctx);
|
||||
static DWORD GetMaxNamedPipePooledConnectionAge(IHttpContext* ctx);
|
||||
static BOOL GetEnableXFF(IHttpContext* ctx);
|
||||
static HRESULT GetPromoteServerVars(IHttpContext* ctx, char*** vars, int* count);
|
||||
|
||||
static HRESULT CreateNodeEnvironment(IHttpContext* ctx, DWORD debugPort, PCH namedPipe, PCH* env);
|
||||
|
||||
|
|
|
@ -251,6 +251,8 @@ copy /y $(ProjectDir)\..\config\* $(ProjectDir)\..\..\build\$(Configuration)\$(P
|
|||
<None Include="..\..\test\functional\tests\115_customheaders.js" />
|
||||
<None Include="..\..\test\functional\tests\116_configerror.js" />
|
||||
<None Include="..\..\test\functional\tests\117_autoupdate_dependency.bat" />
|
||||
<None Include="..\..\test\functional\tests\118_xff.js" />
|
||||
<None Include="..\..\test\functional\tests\119_servervars.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" />
|
||||
|
@ -298,6 +300,10 @@ copy /y $(ProjectDir)\..\config\* $(ProjectDir)\..\..\build\$(Configuration)\$(P
|
|||
<None Include="..\..\test\functional\www\117_autoupdate_dependency\hello_first.js" />
|
||||
<None Include="..\..\test\functional\www\117_autoupdate_dependency\hello_second.js" />
|
||||
<None Include="..\..\test\functional\www\117_autoupdate_dependency\web.config" />
|
||||
<None Include="..\..\test\functional\www\118_xff\hello.js" />
|
||||
<None Include="..\..\test\functional\www\118_xff\web.config" />
|
||||
<None Include="..\..\test\functional\www\119_servervars\hello.js" />
|
||||
<None Include="..\..\test\functional\www\119_servervars\web.config" />
|
||||
<None Include="..\..\test\performance\client.bat" />
|
||||
<None Include="..\..\test\performance\localRun.bat" />
|
||||
<None Include="..\..\test\performance\readme.txt" />
|
||||
|
|
|
@ -120,6 +120,12 @@
|
|||
<Filter Include="Tests\functional\www\117_autoupdate_dependency">
|
||||
<UniqueIdentifier>{ac86a901-4e59-4b58-82ce-a7674d8c587c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Tests\functional\www\118_xff">
|
||||
<UniqueIdentifier>{dd3b1edf-b406-49ff-988a-4b417fe9ce3c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Tests\functional\www\119_servervars">
|
||||
<UniqueIdentifier>{4595469d-4085-4631-836b-08584244a9e7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
|
@ -528,6 +534,24 @@
|
|||
<None Include="..\..\test\functional\www\117_autoupdate_dependency\web.config">
|
||||
<Filter>Tests\functional\www\117_autoupdate_dependency</Filter>
|
||||
</None>
|
||||
<None Include="..\..\test\functional\tests\118_xff.js">
|
||||
<Filter>Tests\functional\tests</Filter>
|
||||
</None>
|
||||
<None Include="..\..\test\functional\www\118_xff\hello.js">
|
||||
<Filter>Tests\functional\www\118_xff</Filter>
|
||||
</None>
|
||||
<None Include="..\..\test\functional\www\118_xff\web.config">
|
||||
<Filter>Tests\functional\www\118_xff</Filter>
|
||||
</None>
|
||||
<None Include="..\..\test\functional\tests\119_servervars.js">
|
||||
<Filter>Tests\functional\tests</Filter>
|
||||
</None>
|
||||
<None Include="..\..\test\functional\www\119_servervars\hello.js">
|
||||
<Filter>Tests\functional\www\119_servervars</Filter>
|
||||
</None>
|
||||
<None Include="..\..\test\functional\www\119_servervars\web.config">
|
||||
<Filter>Tests\functional\www\119_servervars</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="iisnode.rc" />
|
||||
|
|
|
@ -125,6 +125,10 @@ console.log('Application started at location ' + process.env.PORT);</pre>
|
|||
CPU cost but may improve latency in streaming scenarios
|
||||
|
||||
* enableXFF - controls whether iisnode adds or modifies the X-Forwarded-For request HTTP header with the IP address of the remote host
|
||||
|
||||
* promoteServerVars - comma delimited list of IIS server variables that will be propagated to the node.exe process in the form of
|
||||
x-iisnode-<server_variable_name> HTTP request headers; for a list of IIS server variables available see
|
||||
http://msdn.microsoft.com/en-us/library/ms524602(v=vs.90).aspx; for example "AUTH_USER,AUTH_TYPE"
|
||||
|
||||
-->
|
||||
|
||||
|
@ -152,6 +156,7 @@ console.log('Application started at location ' + process.env.PORT);</pre>
|
|||
devErrorsEnabled="true"
|
||||
flushResponse="false"
|
||||
enableXFF="false"
|
||||
promoteServerVars=""
|
||||
/>
|
||||
|
||||
<!--
|
||||
|
|
|
@ -91,6 +91,10 @@
|
|||
CPU cost but may improve latency in streaming scenarios
|
||||
|
||||
* enableXFF - controls whether iisnode adds or modifies the X-Forwarded-For request HTTP header with the IP address of the remote host
|
||||
|
||||
* promoteServerVars - comma delimited list of IIS server variables that will be propagated to the node.exe process in the form of
|
||||
x-iisnode-<server_variable_name> HTTP request headers; for a list of IIS server variables available see
|
||||
http://msdn.microsoft.com/en-us/library/ms524602(v=vs.90).aspx; for example "AUTH_USER,AUTH_TYPE"
|
||||
|
||||
-->
|
||||
|
||||
|
@ -119,6 +123,7 @@
|
|||
devErrorsEnabled="true"
|
||||
flushResponse="false"
|
||||
enableXFF="false"
|
||||
promoteServerVars=""
|
||||
/>
|
||||
|
||||
<!--
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
Server variables specified in the iisnode\@promoteServerVars configuration section are promoted to X-iisnode-* headers
|
||||
*/
|
||||
|
||||
var iisnodeassert = require("iisnodeassert");
|
||||
|
||||
iisnodeassert.sequence([
|
||||
iisnodeassert.get(10000, "/119_servervars/hello.js", 200, "x-iisnode-request_method: GET")
|
||||
]);
|
|
@ -0,0 +1,6 @@
|
|||
var http = require('http');
|
||||
|
||||
http.createServer(function (req, res) {
|
||||
res.writeHead(200, {'Content-Type': 'text/html'});
|
||||
res.end('x-iisnode-request_method: ' + req.headers['x-iisnode-request_method']);
|
||||
}).listen(process.env.PORT);
|
|
@ -0,0 +1,11 @@
|
|||
<configuration>
|
||||
<system.webServer>
|
||||
|
||||
<handlers>
|
||||
<add name="iisnode" path="hello.js" verb="*" modules="iisnode" />
|
||||
</handlers>
|
||||
|
||||
<iisnode promoteServerVars="REQUEST_METHOD,AUTH_USER" />
|
||||
|
||||
</system.webServer>
|
||||
</configuration>
|
Загрузка…
Ссылка в новой задаче