Adds environment variable feature for inprocess (#583)
This commit is contained in:
parent
1f6e2c8029
commit
21b1febf2b
|
|
@ -3,6 +3,15 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define HOSTING_STARTUP_ASSEMBLIES_ENV_STR L"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES"
|
||||||
|
#define HOSTING_STARTUP_ASSEMBLIES_NAME L"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES="
|
||||||
|
#define HOSTING_STARTUP_ASSEMBLIES_VALUE L"Microsoft.AspNetCore.Server.IISIntegration"
|
||||||
|
#define ASPNETCORE_IIS_AUTH_ENV_STR L"ASPNETCORE_IIS_HTTPAUTH="
|
||||||
|
#define ASPNETCORE_IIS_AUTH_WINDOWS L"windows;"
|
||||||
|
#define ASPNETCORE_IIS_AUTH_BASIC L"basic;"
|
||||||
|
#define ASPNETCORE_IIS_AUTH_ANONYMOUS L"anonymous;"
|
||||||
|
#define ASPNETCORE_IIS_AUTH_NONE L"none"
|
||||||
|
|
||||||
//
|
//
|
||||||
// The key used for hash-table lookups, consists of the port on which the http process is created.
|
// The key used for hash-table lookups, consists of the port on which the http process is created.
|
||||||
//
|
//
|
||||||
|
|
@ -70,12 +79,13 @@ class ENVIRONMENT_VAR_HASH : public HASH_TABLE<ENVIRONMENT_VAR_ENTRY, PWSTR>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ENVIRONMENT_VAR_HASH()
|
ENVIRONMENT_VAR_HASH()
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
PWSTR
|
PWSTR
|
||||||
ExtractKey(
|
ExtractKey(
|
||||||
ENVIRONMENT_VAR_ENTRY * pEntry
|
ENVIRONMENT_VAR_ENTRY * pEntry
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return pEntry->QueryName();
|
return pEntry->QueryName();
|
||||||
}
|
}
|
||||||
|
|
@ -149,6 +159,314 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
AppendEnvironmentVariables
|
||||||
|
(
|
||||||
|
ENVIRONMENT_VAR_ENTRY * pEntry,
|
||||||
|
PVOID pvData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(pvData);
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD dwResult = 0;
|
||||||
|
DWORD dwError = 0;
|
||||||
|
STRU struNameBuffer;
|
||||||
|
STACK_STRU(struValueBuffer, 300);
|
||||||
|
BOOL fFound = FALSE;
|
||||||
|
|
||||||
|
// pEntry->QueryName includes the trailing =, remove it before calling stru
|
||||||
|
if (FAILED(hr = struNameBuffer.Copy(pEntry->QueryName())))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
dwResult = struNameBuffer.LastIndexOf(L'=');
|
||||||
|
if (dwResult != -1)
|
||||||
|
{
|
||||||
|
struNameBuffer.QueryStr()[dwResult] = L'\0';
|
||||||
|
if (FAILED(hr = struNameBuffer.SyncWithBuffer()))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dwResult = GetEnvironmentVariable(struNameBuffer.QueryStr(), struValueBuffer.QueryStr(), struValueBuffer.QuerySizeCCH());
|
||||||
|
if (dwResult == 0)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
// Windows API (e.g., CreateProcess) allows variable with empty string value
|
||||||
|
// in such case dwResult will be 0 and dwError will also be 0
|
||||||
|
// As UI and CMD does not allow empty value, ignore this environment var
|
||||||
|
if (dwError != ERROR_ENVVAR_NOT_FOUND && dwError != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(dwError);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dwResult > struValueBuffer.QuerySizeCCH())
|
||||||
|
{
|
||||||
|
// have to increase the buffer and try get environment var again
|
||||||
|
struValueBuffer.Reset();
|
||||||
|
struValueBuffer.Resize(dwResult + (DWORD)wcslen(pEntry->QueryValue()) + 2); // for null char and semicolon
|
||||||
|
dwResult = GetEnvironmentVariable(struNameBuffer.QueryStr(),
|
||||||
|
struValueBuffer.QueryStr(),
|
||||||
|
struValueBuffer.QuerySizeCCH());
|
||||||
|
if (struValueBuffer.IsEmpty())
|
||||||
|
{
|
||||||
|
hr = E_UNEXPECTED;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
fFound = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fFound = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = struValueBuffer.SyncWithBuffer()))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fFound)
|
||||||
|
{
|
||||||
|
if (FAILED(hr = struValueBuffer.Append(L";")))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FAILED(hr = struValueBuffer.Append(pEntry->QueryValue())))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = pEntry->Initialize(pEntry->QueryName(), struValueBuffer.QueryStr())))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
// TODO besides calling SetLastError, is there anyway to propagate failures to set the environment variable?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
SetEnvironmentVariables
|
||||||
|
(
|
||||||
|
ENVIRONMENT_VAR_ENTRY * pEntry,
|
||||||
|
PVOID pvData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(pvData);
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD dwResult = 0;
|
||||||
|
STRU struNameBuffer;
|
||||||
|
|
||||||
|
// pEntry->QueryName includes the trailing =, remove it before calling SetEnvironmentVariable.
|
||||||
|
if (FAILED(hr = struNameBuffer.Copy(pEntry->QueryName())))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
dwResult = struNameBuffer.LastIndexOf(L'=');
|
||||||
|
if (dwResult != -1)
|
||||||
|
{
|
||||||
|
struNameBuffer.QueryStr()[dwResult] = L'\0';
|
||||||
|
if (FAILED(hr = struNameBuffer.SyncWithBuffer()))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dwResult = SetEnvironmentVariable(struNameBuffer.QueryStr(), pEntry->QueryValue());
|
||||||
|
if (dwResult == 0)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
InitEnvironmentVariablesTable
|
||||||
|
(
|
||||||
|
_In_ ENVIRONMENT_VAR_HASH* pInEnvironmentVarTable,
|
||||||
|
BOOL fWindowsAuthEnabled,
|
||||||
|
BOOL fBasicAuthEnabled,
|
||||||
|
BOOL fAnonymousAuthEnabled,
|
||||||
|
ENVIRONMENT_VAR_HASH** ppEnvironmentVarTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
BOOL fFound = FALSE;
|
||||||
|
DWORD dwResult, dwError;
|
||||||
|
STRU strIisAuthEnvValue;
|
||||||
|
STACK_STRU(strStartupAssemblyEnv, 1024);
|
||||||
|
ENVIRONMENT_VAR_ENTRY* pHostingEntry = NULL;
|
||||||
|
ENVIRONMENT_VAR_ENTRY* pIISAuthEntry = NULL;
|
||||||
|
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable = NULL;
|
||||||
|
|
||||||
|
pEnvironmentVarTable = new ENVIRONMENT_VAR_HASH();
|
||||||
|
if (pEnvironmentVarTable == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// few environment variables expected, small bucket size for hash table
|
||||||
|
//
|
||||||
|
if (FAILED(hr = pEnvironmentVarTable->Initialize(37 /*prime*/)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the envirable hash table (from configuration) to a temp one as we may need to remove elements
|
||||||
|
pInEnvironmentVarTable->Apply(ENVIRONMENT_VAR_HASH::CopyToTable, pEnvironmentVarTable);
|
||||||
|
if (pEnvironmentVarTable->Count() != pInEnvironmentVarTable->Count())
|
||||||
|
{
|
||||||
|
// hash table copy failed
|
||||||
|
hr = E_UNEXPECTED;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pEnvironmentVarTable->FindKey((PWSTR)ASPNETCORE_IIS_AUTH_ENV_STR, &pIISAuthEntry);
|
||||||
|
if (pIISAuthEntry != NULL)
|
||||||
|
{
|
||||||
|
// user defined ASPNETCORE_IIS_HTTPAUTH in configuration, wipe it off
|
||||||
|
pIISAuthEntry->Dereference();
|
||||||
|
pEnvironmentVarTable->DeleteKey((PWSTR)ASPNETCORE_IIS_AUTH_ENV_STR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fWindowsAuthEnabled)
|
||||||
|
{
|
||||||
|
strIisAuthEnvValue.Copy(ASPNETCORE_IIS_AUTH_WINDOWS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fBasicAuthEnabled)
|
||||||
|
{
|
||||||
|
strIisAuthEnvValue.Append(ASPNETCORE_IIS_AUTH_BASIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fAnonymousAuthEnabled)
|
||||||
|
{
|
||||||
|
strIisAuthEnvValue.Append(ASPNETCORE_IIS_AUTH_ANONYMOUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strIisAuthEnvValue.IsEmpty())
|
||||||
|
{
|
||||||
|
strIisAuthEnvValue.Copy(ASPNETCORE_IIS_AUTH_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pIISAuthEntry = new ENVIRONMENT_VAR_ENTRY();
|
||||||
|
if (pIISAuthEntry == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
if (FAILED(hr = pIISAuthEntry->Initialize(ASPNETCORE_IIS_AUTH_ENV_STR, strIisAuthEnvValue.QueryStr())) ||
|
||||||
|
FAILED(hr = pEnvironmentVarTable->InsertRecord(pIISAuthEntry)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compiler is complaining about conversion between PCWSTR and PWSTR here.
|
||||||
|
// Explictly casting.
|
||||||
|
pEnvironmentVarTable->FindKey((PWSTR)HOSTING_STARTUP_ASSEMBLIES_NAME, &pHostingEntry);
|
||||||
|
if (pHostingEntry != NULL)
|
||||||
|
{
|
||||||
|
// user defined ASPNETCORE_HOSTINGSTARTUPASSEMBLIES in configuration
|
||||||
|
// the value will be used in OutputEnvironmentVariables. Do nothing here
|
||||||
|
pHostingEntry->Dereference();
|
||||||
|
pHostingEntry = NULL;
|
||||||
|
goto Skipped;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check whether ASPNETCORE_HOSTINGSTARTUPASSEMBLIES is defined in system
|
||||||
|
dwResult = GetEnvironmentVariable(HOSTING_STARTUP_ASSEMBLIES_ENV_STR,
|
||||||
|
strStartupAssemblyEnv.QueryStr(),
|
||||||
|
strStartupAssemblyEnv.QuerySizeCCH());
|
||||||
|
if (dwResult == 0)
|
||||||
|
{
|
||||||
|
dwError = GetLastError();
|
||||||
|
// Windows API (e.g., CreateProcess) allows variable with empty string value
|
||||||
|
// in such case dwResult will be 0 and dwError will also be 0
|
||||||
|
// As UI and CMD does not allow empty value, ignore this environment var
|
||||||
|
if (dwError != ERROR_ENVVAR_NOT_FOUND && dwError != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(dwError);
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dwResult > strStartupAssemblyEnv.QuerySizeCCH())
|
||||||
|
{
|
||||||
|
// have to increase the buffer and try get environment var again
|
||||||
|
strStartupAssemblyEnv.Reset();
|
||||||
|
strStartupAssemblyEnv.Resize(dwResult + (DWORD)wcslen(HOSTING_STARTUP_ASSEMBLIES_VALUE) + 1);
|
||||||
|
dwResult = GetEnvironmentVariable(HOSTING_STARTUP_ASSEMBLIES_ENV_STR,
|
||||||
|
strStartupAssemblyEnv.QueryStr(),
|
||||||
|
strStartupAssemblyEnv.QuerySizeCCH());
|
||||||
|
if (strStartupAssemblyEnv.IsEmpty())
|
||||||
|
{
|
||||||
|
hr = E_UNEXPECTED;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
fFound = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fFound = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
strStartupAssemblyEnv.SyncWithBuffer();
|
||||||
|
if (fFound)
|
||||||
|
{
|
||||||
|
strStartupAssemblyEnv.Append(L";");
|
||||||
|
}
|
||||||
|
strStartupAssemblyEnv.Append(HOSTING_STARTUP_ASSEMBLIES_VALUE);
|
||||||
|
|
||||||
|
// the environment variable was not defined, create it and add to hashtable
|
||||||
|
pHostingEntry = new ENVIRONMENT_VAR_ENTRY();
|
||||||
|
if (pHostingEntry == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
if (FAILED(hr = pHostingEntry->Initialize(HOSTING_STARTUP_ASSEMBLIES_NAME, strStartupAssemblyEnv.QueryStr())) ||
|
||||||
|
FAILED(hr = pEnvironmentVarTable->InsertRecord(pHostingEntry)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
Skipped:
|
||||||
|
*ppEnvironmentVarTable = pEnvironmentVarTable;
|
||||||
|
pEnvironmentVarTable = NULL;
|
||||||
|
|
||||||
|
Finished:
|
||||||
|
if (pHostingEntry != NULL)
|
||||||
|
{
|
||||||
|
pHostingEntry->Dereference();
|
||||||
|
pHostingEntry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pIISAuthEntry != NULL)
|
||||||
|
{
|
||||||
|
pIISAuthEntry->Dereference();
|
||||||
|
pIISAuthEntry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEnvironmentVarTable != NULL)
|
||||||
|
{
|
||||||
|
pEnvironmentVarTable->Clear();
|
||||||
|
delete pEnvironmentVarTable;
|
||||||
|
pEnvironmentVarTable = NULL;
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ENVIRONMENT_VAR_HASH(const ENVIRONMENT_VAR_HASH &);
|
ENVIRONMENT_VAR_HASH(const ENVIRONMENT_VAR_HASH &);
|
||||||
void operator=(const ENVIRONMENT_VAR_HASH &);
|
void operator=(const ENVIRONMENT_VAR_HASH &);
|
||||||
|
|
|
||||||
|
|
@ -30,3 +30,4 @@
|
||||||
#include "hostfxr_utility.h"
|
#include "hostfxr_utility.h"
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
#include "aspnetcore_msg.h"
|
#include "aspnetcore_msg.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -615,6 +615,29 @@ IN_PROCESS_APPLICATION::ExecuteAspNetCoreProcess(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
IN_PROCESS_APPLICATION::SetEnvironementVariablesOnWorkerProcess(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
ENVIRONMENT_VAR_HASH* pHashTable = NULL;
|
||||||
|
if (FAILED(hr = ENVIRONMENT_VAR_HASH::InitEnvironmentVariablesTable(
|
||||||
|
m_pConfig->QueryEnvironmentVariables(),
|
||||||
|
m_pConfig->QueryWindowsAuthEnabled(),
|
||||||
|
m_pConfig->QueryBasicAuthEnabled(),
|
||||||
|
m_pConfig->QueryAnonymousAuthEnabled(),
|
||||||
|
&pHashTable)))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
pHashTable->Apply(ENVIRONMENT_VAR_HASH::AppendEnvironmentVariables, NULL);
|
||||||
|
pHashTable->Apply(ENVIRONMENT_VAR_HASH::SetEnvironmentVariables, NULL);
|
||||||
|
Finished:
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
IN_PROCESS_APPLICATION::ExecuteApplication(
|
IN_PROCESS_APPLICATION::ExecuteApplication(
|
||||||
VOID
|
VOID
|
||||||
|
|
@ -647,6 +670,10 @@ IN_PROCESS_APPLICATION::ExecuteApplication(
|
||||||
// loaded in the process but we need to get config information to boot it up in the
|
// loaded in the process but we need to get config information to boot it up in the
|
||||||
// first place. This is happening in an execute request handler and everyone waits
|
// first place. This is happening in an execute request handler and everyone waits
|
||||||
// until this initialization is done.
|
// until this initialization is done.
|
||||||
|
if (FAILED(hr = SetEnvironementVariablesOnWorkerProcess()))
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
// We set a static so that managed code can call back into this instance and
|
// We set a static so that managed code can call back into this instance and
|
||||||
// set the callbacks
|
// set the callbacks
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,11 @@ private:
|
||||||
_In_ LPVOID pContext
|
_In_ LPVOID pContext
|
||||||
);
|
);
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
SetEnvironementVariablesOnWorkerProcess(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
static
|
static
|
||||||
INT
|
INT
|
||||||
FilterException(unsigned int code, struct _EXCEPTION_POINTERS *ep);
|
FilterException(unsigned int code, struct _EXCEPTION_POINTERS *ep);
|
||||||
|
|
|
||||||
|
|
@ -333,178 +333,6 @@ Finished:
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
SERVER_PROCESS::InitEnvironmentVariablesTable(
|
|
||||||
ENVIRONMENT_VAR_HASH** ppEnvironmentVarTable
|
|
||||||
)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
BOOL fFound = FALSE;
|
|
||||||
DWORD dwResult, dwError;
|
|
||||||
STRU strIisAuthEnvValue;
|
|
||||||
STACK_STRU(strStartupAssemblyEnv, 1024);
|
|
||||||
ENVIRONMENT_VAR_ENTRY* pHostingEntry = NULL;
|
|
||||||
ENVIRONMENT_VAR_ENTRY* pIISAuthEntry = NULL;
|
|
||||||
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable = NULL;
|
|
||||||
|
|
||||||
pEnvironmentVarTable = new ENVIRONMENT_VAR_HASH();
|
|
||||||
if (pEnvironmentVarTable == NULL)
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// few environment variables expected, small bucket size for hash table
|
|
||||||
//
|
|
||||||
if (FAILED(hr = pEnvironmentVarTable->Initialize(37 /*prime*/)))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy the envirable hash table (from configuration) to a temp one as we may need to remove elements
|
|
||||||
m_pEnvironmentVarTable->Apply(ENVIRONMENT_VAR_HASH::CopyToTable, pEnvironmentVarTable);
|
|
||||||
if (pEnvironmentVarTable->Count() != m_pEnvironmentVarTable->Count())
|
|
||||||
{
|
|
||||||
// hash table copy failed
|
|
||||||
hr = E_UNEXPECTED;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
pEnvironmentVarTable->FindKey(ASPNETCORE_IIS_AUTH_ENV_STR, &pIISAuthEntry);
|
|
||||||
if (pIISAuthEntry != NULL)
|
|
||||||
{
|
|
||||||
// user defined ASPNETCORE_IIS_HTTPAUTH in configuration, wipe it off
|
|
||||||
pIISAuthEntry->Dereference();
|
|
||||||
pEnvironmentVarTable->DeleteKey(ASPNETCORE_IIS_AUTH_ENV_STR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_fWindowsAuthEnabled)
|
|
||||||
{
|
|
||||||
strIisAuthEnvValue.Copy(ASPNETCORE_IIS_AUTH_WINDOWS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_fBasicAuthEnabled)
|
|
||||||
{
|
|
||||||
strIisAuthEnvValue.Append(ASPNETCORE_IIS_AUTH_BASIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_fAnonymousAuthEnabled)
|
|
||||||
{
|
|
||||||
strIisAuthEnvValue.Append(ASPNETCORE_IIS_AUTH_ANONYMOUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strIisAuthEnvValue.IsEmpty())
|
|
||||||
{
|
|
||||||
strIisAuthEnvValue.Copy(ASPNETCORE_IIS_AUTH_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
pIISAuthEntry = new ENVIRONMENT_VAR_ENTRY();
|
|
||||||
if (pIISAuthEntry == NULL)
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
if (FAILED(hr = pIISAuthEntry->Initialize(ASPNETCORE_IIS_AUTH_ENV_STR, strIisAuthEnvValue.QueryStr())) ||
|
|
||||||
FAILED(hr = pEnvironmentVarTable->InsertRecord(pIISAuthEntry)))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pEnvironmentVarTable->FindKey(HOSTING_STARTUP_ASSEMBLIES_NAME, &pHostingEntry);
|
|
||||||
if (pHostingEntry != NULL)
|
|
||||||
{
|
|
||||||
// user defined ASPNETCORE_HOSTINGSTARTUPASSEMBLIES in configuration
|
|
||||||
// the value will be used in OutputEnvironmentVariables. Do nothing here
|
|
||||||
pHostingEntry->Dereference();
|
|
||||||
pHostingEntry = NULL;
|
|
||||||
goto Skipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
//check whether ASPNETCORE_HOSTINGSTARTUPASSEMBLIES is defined in system
|
|
||||||
dwResult = GetEnvironmentVariable(HOSTING_STARTUP_ASSEMBLIES_ENV_STR,
|
|
||||||
strStartupAssemblyEnv.QueryStr(),
|
|
||||||
strStartupAssemblyEnv.QuerySizeCCH());
|
|
||||||
if (dwResult == 0)
|
|
||||||
{
|
|
||||||
dwError = GetLastError();
|
|
||||||
// Windows API (e.g., CreateProcess) allows variable with empty string value
|
|
||||||
// in such case dwResult will be 0 and dwError will also be 0
|
|
||||||
// As UI and CMD does not allow empty value, ignore this environment var
|
|
||||||
if (dwError != ERROR_ENVVAR_NOT_FOUND && dwError != ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
hr = HRESULT_FROM_WIN32(dwError);
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (dwResult > strStartupAssemblyEnv.QuerySizeCCH())
|
|
||||||
{
|
|
||||||
// have to increase the buffer and try get environment var again
|
|
||||||
strStartupAssemblyEnv.Reset();
|
|
||||||
strStartupAssemblyEnv.Resize(dwResult + (DWORD)wcslen(HOSTING_STARTUP_ASSEMBLIES_VALUE) + 1);
|
|
||||||
dwResult = GetEnvironmentVariable(HOSTING_STARTUP_ASSEMBLIES_ENV_STR,
|
|
||||||
strStartupAssemblyEnv.QueryStr(),
|
|
||||||
strStartupAssemblyEnv.QuerySizeCCH());
|
|
||||||
if (strStartupAssemblyEnv.IsEmpty())
|
|
||||||
{
|
|
||||||
hr = E_UNEXPECTED;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
fFound = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fFound = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
strStartupAssemblyEnv.SyncWithBuffer();
|
|
||||||
if (fFound)
|
|
||||||
{
|
|
||||||
strStartupAssemblyEnv.Append(L";");
|
|
||||||
}
|
|
||||||
strStartupAssemblyEnv.Append(HOSTING_STARTUP_ASSEMBLIES_VALUE);
|
|
||||||
|
|
||||||
// the environment variable was not defined, create it and add to hashtable
|
|
||||||
pHostingEntry = new ENVIRONMENT_VAR_ENTRY();
|
|
||||||
if (pHostingEntry == NULL)
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
if (FAILED(hr = pHostingEntry->Initialize(HOSTING_STARTUP_ASSEMBLIES_NAME, strStartupAssemblyEnv.QueryStr())) ||
|
|
||||||
FAILED(hr = pEnvironmentVarTable->InsertRecord(pHostingEntry)))
|
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
Skipped:
|
|
||||||
*ppEnvironmentVarTable = pEnvironmentVarTable;
|
|
||||||
pEnvironmentVarTable = NULL;
|
|
||||||
|
|
||||||
Finished:
|
|
||||||
if (pHostingEntry != NULL)
|
|
||||||
{
|
|
||||||
pHostingEntry->Dereference();
|
|
||||||
pHostingEntry = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pIISAuthEntry != NULL)
|
|
||||||
{
|
|
||||||
pIISAuthEntry->Dereference();
|
|
||||||
pIISAuthEntry = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pEnvironmentVarTable != NULL)
|
|
||||||
{
|
|
||||||
pEnvironmentVarTable->Clear();
|
|
||||||
delete pEnvironmentVarTable;
|
|
||||||
pEnvironmentVarTable = NULL;
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
SERVER_PROCESS::OutputEnvironmentVariables
|
SERVER_PROCESS::OutputEnvironmentVariables
|
||||||
(
|
(
|
||||||
|
|
@ -923,11 +751,16 @@ SERVER_PROCESS::StartProcess(
|
||||||
//
|
//
|
||||||
if (FAILED(hr = SetupCommandLine(&m_struCommandLine)))
|
if (FAILED(hr = SetupCommandLine(&m_struCommandLine)))
|
||||||
{
|
{
|
||||||
pStrStage = L"SetupCommanLine";
|
pStrStage = L"SetupCommandLine";
|
||||||
goto Failure;
|
goto Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr = InitEnvironmentVariablesTable(&pHashTable)))
|
if (FAILED(hr = ENVIRONMENT_VAR_HASH::InitEnvironmentVariablesTable(
|
||||||
|
m_pEnvironmentVarTable,
|
||||||
|
m_fWindowsAuthEnabled,
|
||||||
|
m_fBasicAuthEnabled,
|
||||||
|
m_fAnonymousAuthEnabled,
|
||||||
|
&pHashTable)))
|
||||||
{
|
{
|
||||||
pStrStage = L"InitEnvironmentVariablesTable";
|
pStrStage = L"InitEnvironmentVariablesTable";
|
||||||
goto Failure;
|
goto Failure;
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,6 @@
|
||||||
#define ASPNETCORE_APP_PATH_ENV_STR L"ASPNETCORE_APPL_PATH="
|
#define ASPNETCORE_APP_PATH_ENV_STR L"ASPNETCORE_APPL_PATH="
|
||||||
#define ASPNETCORE_APP_TOKEN_ENV_STR L"ASPNETCORE_TOKEN="
|
#define ASPNETCORE_APP_TOKEN_ENV_STR L"ASPNETCORE_TOKEN="
|
||||||
#define ASPNETCORE_APP_PATH_ENV_STR L"ASPNETCORE_APPL_PATH="
|
#define ASPNETCORE_APP_PATH_ENV_STR L"ASPNETCORE_APPL_PATH="
|
||||||
#define HOSTING_STARTUP_ASSEMBLIES_ENV_STR L"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES"
|
|
||||||
#define HOSTING_STARTUP_ASSEMBLIES_NAME L"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES="
|
|
||||||
#define HOSTING_STARTUP_ASSEMBLIES_VALUE L"Microsoft.AspNetCore.Server.IISIntegration"
|
|
||||||
#define ASPNETCORE_IIS_AUTH_ENV_STR L"ASPNETCORE_IIS_HTTPAUTH="
|
|
||||||
#define ASPNETCORE_IIS_AUTH_WINDOWS L"windows;"
|
|
||||||
#define ASPNETCORE_IIS_AUTH_BASIC L"basic;"
|
|
||||||
#define ASPNETCORE_IIS_AUTH_ANONYMOUS L"anonymous;"
|
|
||||||
#define ASPNETCORE_IIS_AUTH_NONE L"none"
|
|
||||||
|
|
||||||
class PROCESS_MANAGER;
|
class PROCESS_MANAGER;
|
||||||
|
|
||||||
|
|
@ -182,11 +174,6 @@ private:
|
||||||
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
|
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT
|
|
||||||
InitEnvironmentVariablesTable(
|
|
||||||
ENVIRONMENT_VAR_HASH** pEnvironmentVarTable
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
OutputEnvironmentVariables(
|
OutputEnvironmentVariables(
|
||||||
MULTISZ* pmszOutput,
|
MULTISZ* pmszOutput,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
|
||||||
|
{
|
||||||
|
[Collection(IISTestSiteCollection.Name)]
|
||||||
|
public class EnvironmentVariableTests
|
||||||
|
{
|
||||||
|
private readonly IISTestSiteFixture _fixture;
|
||||||
|
|
||||||
|
public EnvironmentVariableTests(IISTestSiteFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task GetUniqueEnvironmentVariable()
|
||||||
|
{
|
||||||
|
Assert.Equal("foobar", await _fixture.Client.GetStringAsync("/CheckEnvironmentVariable"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task GetLongEnvironmentVariable()
|
||||||
|
{
|
||||||
|
Assert.Equal(
|
||||||
|
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||||
|
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||||
|
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||||
|
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||||
|
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" +
|
||||||
|
"AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative",
|
||||||
|
await _fixture.Client.GetStringAsync("/CheckEnvironmentLongValueVariable"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task GetExistingEnvironmentVariable()
|
||||||
|
{
|
||||||
|
Assert.Contains(";foobarbaz", await _fixture.Client.GetStringAsync("/CheckAppendedEnvironmentVariable"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task AuthHeaderEnvironmentVariableRemoved()
|
||||||
|
{
|
||||||
|
Assert.DoesNotContain("shouldberemoved", await _fixture.Client.GetStringAsync("/CheckRemoveAuthEnvironmentVariable"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,6 +31,10 @@ namespace IISTestSite
|
||||||
app.Map("/LargeResponseBody", LargeResponseBody);
|
app.Map("/LargeResponseBody", LargeResponseBody);
|
||||||
app.Map("/ResponseHeaders", ResponseHeaders);
|
app.Map("/ResponseHeaders", ResponseHeaders);
|
||||||
app.Map("/ResponseInvalidOrdering", ResponseInvalidOrdering);
|
app.Map("/ResponseInvalidOrdering", ResponseInvalidOrdering);
|
||||||
|
app.Map("/CheckEnvironmentVariable", CheckEnvironmentVariable);
|
||||||
|
app.Map("/CheckEnvironmentLongValueVariable", CheckEnvironmentLongValueVariable);
|
||||||
|
app.Map("/CheckAppendedEnvironmentVariable", CheckAppendedEnvironmentVariable);
|
||||||
|
app.Map("/CheckRemoveAuthEnvironmentVariable", CheckRemoveAuthEnvironmentVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ServerVariable(IApplicationBuilder app)
|
private void ServerVariable(IApplicationBuilder app)
|
||||||
|
|
@ -285,5 +289,41 @@ namespace IISTestSite
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CheckEnvironmentVariable(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
var variable = Environment.GetEnvironmentVariable("ASPNETCORE_INPROCESS_TESTING_VALUE");
|
||||||
|
await context.Response.WriteAsync(variable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckEnvironmentLongValueVariable(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
var variable = Environment.GetEnvironmentVariable("ASPNETCORE_INPROCESS_TESTING_LONG_VALUE");
|
||||||
|
await context.Response.WriteAsync(variable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckAppendedEnvironmentVariable(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
var variable = Environment.GetEnvironmentVariable("ProgramFiles");
|
||||||
|
await context.Response.WriteAsync(variable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckRemoveAuthEnvironmentVariable(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
var variable = Environment.GetEnvironmentVariable("ASPNETCORE_IIS_HTTPAUTH");
|
||||||
|
await context.Response.WriteAsync(variable);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,13 @@
|
||||||
<handlers>
|
<handlers>
|
||||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||||
</handlers>
|
</handlers>
|
||||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" hostingModel="inprocess"/>
|
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" hostingModel="inprocess">
|
||||||
|
<environmentVariables>
|
||||||
|
<environmentVariable name="ASPNETCORE_INPROCESS_TESTING_VALUE" value="foobar" />
|
||||||
|
<environmentVariable name="ASPNETCORE_INPROCESS_TESTING_LONG_VALUE" value="AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNativeAReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNativeAReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNativeAReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNativeAReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNativeAReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" />
|
||||||
|
<environmentVariable name="ProgramFiles" value="foobarbaz" />
|
||||||
|
<environmentVariable name="ASPNETCORE_IIS_HTTPAUTH" value="shouldberemoved"/>
|
||||||
|
</environmentVariables>
|
||||||
|
</aspNetCore>
|
||||||
</system.webServer>
|
</system.webServer>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue