Adds environment variable feature for inprocess (#583)
This commit is contained in:
parent
1f6e2c8029
commit
21b1febf2b
|
|
@ -3,6 +3,15 @@
|
|||
|
||||
#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.
|
||||
//
|
||||
|
|
@ -69,13 +78,14 @@ private:
|
|||
class ENVIRONMENT_VAR_HASH : public HASH_TABLE<ENVIRONMENT_VAR_ENTRY, PWSTR>
|
||||
{
|
||||
public:
|
||||
ENVIRONMENT_VAR_HASH()
|
||||
{}
|
||||
ENVIRONMENT_VAR_HASH()
|
||||
{
|
||||
}
|
||||
|
||||
PWSTR
|
||||
ExtractKey(
|
||||
ENVIRONMENT_VAR_ENTRY * pEntry
|
||||
)
|
||||
)
|
||||
{
|
||||
return pEntry->QueryName();
|
||||
}
|
||||
|
|
@ -138,7 +148,7 @@ public:
|
|||
{
|
||||
// best effort copy, ignore the failure
|
||||
ENVIRONMENT_VAR_ENTRY * pNewEntry = new ENVIRONMENT_VAR_ENTRY();
|
||||
if (pNewEntry != NULL)
|
||||
if (pNewEntry != NULL)
|
||||
{
|
||||
pNewEntry->Initialize(pEntry->QueryName(), pEntry->QueryValue());
|
||||
ENVIRONMENT_VAR_HASH *pHash = static_cast<ENVIRONMENT_VAR_HASH *>(pvData);
|
||||
|
|
@ -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:
|
||||
ENVIRONMENT_VAR_HASH(const ENVIRONMENT_VAR_HASH &);
|
||||
void operator=(const ENVIRONMENT_VAR_HASH &);
|
||||
|
|
|
|||
|
|
@ -30,3 +30,4 @@
|
|||
#include "hostfxr_utility.h"
|
||||
#include "resources.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
|
||||
IN_PROCESS_APPLICATION::ExecuteApplication(
|
||||
VOID
|
||||
|
|
@ -634,7 +657,7 @@ IN_PROCESS_APPLICATION::ExecuteApplication(
|
|||
hr = ERROR_BAD_ENVIRONMENT;
|
||||
goto Finished;
|
||||
}
|
||||
|
||||
|
||||
// Get the entry point for main
|
||||
pProc = (hostfxr_main_fn)GetProcAddress(hModule, "hostfxr_main");
|
||||
if (pProc == NULL)
|
||||
|
|
@ -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
|
||||
// first place. This is happening in an execute request handler and everyone waits
|
||||
// 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
|
||||
// set the callbacks
|
||||
|
|
|
|||
|
|
@ -137,6 +137,11 @@ private:
|
|||
_In_ LPVOID pContext
|
||||
);
|
||||
|
||||
HRESULT
|
||||
SetEnvironementVariablesOnWorkerProcess(
|
||||
VOID
|
||||
);
|
||||
|
||||
static
|
||||
INT
|
||||
FilterException(unsigned int code, struct _EXCEPTION_POINTERS *ep);
|
||||
|
|
|
|||
|
|
@ -333,178 +333,6 @@ Finished:
|
|||
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
|
||||
SERVER_PROCESS::OutputEnvironmentVariables
|
||||
(
|
||||
|
|
@ -923,11 +751,16 @@ SERVER_PROCESS::StartProcess(
|
|||
//
|
||||
if (FAILED(hr = SetupCommandLine(&m_struCommandLine)))
|
||||
{
|
||||
pStrStage = L"SetupCommanLine";
|
||||
pStrStage = L"SetupCommandLine";
|
||||
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";
|
||||
goto Failure;
|
||||
|
|
|
|||
|
|
@ -13,14 +13,6 @@
|
|||
#define ASPNETCORE_APP_PATH_ENV_STR L"ASPNETCORE_APPL_PATH="
|
||||
#define ASPNETCORE_APP_TOKEN_ENV_STR L"ASPNETCORE_TOKEN="
|
||||
#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;
|
||||
|
||||
|
|
@ -182,11 +174,6 @@ private:
|
|||
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
|
||||
);
|
||||
|
||||
HRESULT
|
||||
InitEnvironmentVariablesTable(
|
||||
ENVIRONMENT_VAR_HASH** pEnvironmentVarTable
|
||||
);
|
||||
|
||||
HRESULT
|
||||
OutputEnvironmentVariables(
|
||||
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("/ResponseHeaders", ResponseHeaders);
|
||||
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)
|
||||
|
|
@ -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>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
|
||||
</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>
|
||||
</configuration>
|
||||
|
|
|
|||
Loading…
Reference in New Issue