add features: flowing authentication info, hosting environment variable support; fix client disconnect and app_offline issues (#102)

resubmit
This commit is contained in:
pan-wang 2017-05-23 17:25:45 -07:00 committed by GitHub
parent 88cc1c14d0
commit bce531f61a
18 changed files with 2254 additions and 1825 deletions

View File

@ -157,7 +157,7 @@
<ClInclude Include="Inc\application.h" /> <ClInclude Include="Inc\application.h" />
<ClInclude Include="Inc\applicationmanager.h" /> <ClInclude Include="Inc\applicationmanager.h" />
<ClInclude Include="Inc\aspnetcoreconfig.h" /> <ClInclude Include="Inc\aspnetcoreconfig.h" />
<ClInclude Include="Inc\aspnetcoreutils.h" /> <ClInclude Include="Inc\environmentvariablehash.h" />
<ClInclude Include="Inc\debugutil.h" /> <ClInclude Include="Inc\debugutil.h" />
<ClInclude Include="Inc\filewatcher.h" /> <ClInclude Include="Inc\filewatcher.h" />
<ClInclude Include="Inc\forwarderconnection.h" /> <ClInclude Include="Inc\forwarderconnection.h" />
@ -177,7 +177,6 @@
<ClCompile Include="Src\application.cxx" /> <ClCompile Include="Src\application.cxx" />
<ClCompile Include="Src\applicationmanager.cxx" /> <ClCompile Include="Src\applicationmanager.cxx" />
<ClCompile Include="Src\aspnetcoreconfig.cxx" /> <ClCompile Include="Src\aspnetcoreconfig.cxx" />
<ClCompile Include="Src\aspnetcoreutils.cxx" />
<ClCompile Include="Src\dllmain.cpp" /> <ClCompile Include="Src\dllmain.cpp" />
<ClCompile Include="Src\filewatcher.cxx" /> <ClCompile Include="Src\filewatcher.cxx" />
<ClCompile Include="Src\forwarderconnection.cxx" /> <ClCompile Include="Src\forwarderconnection.cxx" />

View File

@ -70,10 +70,12 @@ public:
VOID VOID
) )
{ {
BOOL fResult = FALSE; BOOL fResult = TRUE;
LARGE_INTEGER li = {0}; LARGE_INTEGER li = {0};
CHAR *pszBuff = NULL; CHAR *pszBuff = NULL;
HANDLE handle = CreateFile( m_Path.QueryStr(), HANDLE handle = INVALID_HANDLE_VALUE;
handle = CreateFile( m_Path.QueryStr(),
GENERIC_READ, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, NULL,
@ -81,8 +83,15 @@ public:
FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL,
NULL ); NULL );
if( handle == NULL ) if( handle == INVALID_HANDLE_VALUE )
{ {
if ( GetLastError() == ERROR_FILE_NOT_FOUND )
{
fResult = FALSE;
}
// This Load() member function is supposed be called only when the change notification event of file creation or file modification happens.
// If file is currenlty locked exclusively by other processes, we might get INVALID_HANDLE_VALUE even though the file exists. In that case, we should return TRUE here.
goto Finished; goto Finished;
} }
@ -91,8 +100,6 @@ public:
goto Finished; goto Finished;
} }
fResult = TRUE;
if( li.HighPart != 0 ) if( li.HighPart != 0 )
{ {
// > 4gb file size not supported // > 4gb file size not supported
@ -113,10 +120,10 @@ public:
} }
Finished: Finished:
if( handle ) if( handle != INVALID_HANDLE_VALUE )
{ {
CloseHandle(handle); CloseHandle(handle);
handle = NULL; handle = INVALID_HANDLE_VALUE;
} }
if( pszBuff != NULL ) if( pszBuff != NULL )

View File

@ -5,6 +5,10 @@
#define CS_ROOTWEB_CONFIG L"MACHINE/WEBROOT/APPHOST/" #define CS_ROOTWEB_CONFIG L"MACHINE/WEBROOT/APPHOST/"
#define CS_ROOTWEB_CONFIG_LEN _countof(CS_ROOTWEB_CONFIG)-1 #define CS_ROOTWEB_CONFIG_LEN _countof(CS_ROOTWEB_CONFIG)-1
#define CS_ASPNETCORE_SECTION L"system.webServer/aspNetCore" #define CS_ASPNETCORE_SECTION L"system.webServer/aspNetCore"
#define CS_WINDOWS_AUTHENTICATION_SECTION L"system.webServer/security/authentication/windowsAuthentication"
#define CS_BASIC_AUTHENTICATION_SECTION L"system.webServer/security/authentication/basicAuthentication"
#define CS_ANONYMOUS_AUTHENTICATION_SECTION L"system.webServer/security/authentication/anonymousAuthentication"
#define CS_AUTHENTICATION_ENABLED L"enabled"
#define CS_ASPNETCORE_PROCESS_EXE_PATH L"processPath" #define CS_ASPNETCORE_PROCESS_EXE_PATH L"processPath"
#define CS_ASPNETCORE_PROCESS_ARGUMENTS L"arguments" #define CS_ASPNETCORE_PROCESS_ARGUMENTS L"arguments"
#define CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT L"startupTimeLimit" #define CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT L"startupTimeLimit"
@ -34,7 +38,6 @@
extern HTTP_MODULE_ID g_pModuleId; extern HTTP_MODULE_ID g_pModuleId;
extern IHttpServer * g_pHttpServer; extern IHttpServer * g_pHttpServer;
class ASPNETCORE_CONFIG : IHttpStoredContext class ASPNETCORE_CONFIG : IHttpStoredContext
{ {
public: public:
@ -54,13 +57,13 @@ public:
_In_ IHttpContext *pHttpContext, _In_ IHttpContext *pHttpContext,
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig _Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
); );
MULTISZ* ENVIRONMENT_VAR_HASH*
QueryEnvironmentVariables( QueryEnvironmentVariables(
VOID VOID
) )
{ {
return &m_mszEnvironment; return m_pEnvironmentVariables;
} }
DWORD DWORD
@ -139,6 +142,24 @@ public:
return m_fForwardWindowsAuthToken; return m_fForwardWindowsAuthToken;
} }
BOOL
QueryWindowsAuthEnabled()
{
return m_fWindowsAuthEnabled;
}
BOOL
QueryBasicAuthEnabled()
{
return m_fBasicAuthEnabled;
}
BOOL
QueryAnonymousAuthEnabled()
{
return m_fAnonymousAuthEnabled;
}
BOOL BOOL
QueryDisableStartUpErrorPage() QueryDisableStartUpErrorPage()
{ {
@ -155,10 +176,10 @@ private:
// //
// private constructor // private constructor
// //
ASPNETCORE_CONFIG(): ASPNETCORE_CONFIG():
m_fStdoutLogEnabled( FALSE ) m_fStdoutLogEnabled( FALSE ),
m_pEnvironmentVariables( NULL )
{ {
} }
@ -167,18 +188,20 @@ private:
IHttpContext *pHttpContext IHttpContext *pHttpContext
); );
DWORD m_dwRequestTimeoutInMS; DWORD m_dwRequestTimeoutInMS;
DWORD m_dwStartupTimeLimitInMS; DWORD m_dwStartupTimeLimitInMS;
DWORD m_dwShutdownTimeLimitInMS; DWORD m_dwShutdownTimeLimitInMS;
MULTISZ m_mszEnvironment; DWORD m_dwRapidFailsPerMinute;
DWORD m_dwRapidFailsPerMinute; DWORD m_dwProcessesPerApplication;
STRU m_struApplication; STRU m_struApplication;
STRU m_struArguments; STRU m_struArguments;
STRU m_struProcessPath; STRU m_struProcessPath;
BOOL m_fStdoutLogEnabled; STRU m_struStdoutLogFile;
STRU m_struStdoutLogFile; BOOL m_fStdoutLogEnabled;
DWORD m_dwProcessesPerApplication; BOOL m_fForwardWindowsAuthToken;
BOOL m_fForwardWindowsAuthToken; BOOL m_fDisableStartUpErrorPage;
BOOL m_fDisableStartUpErrorPage; BOOL m_fWindowsAuthEnabled;
MULTISZ m_mszRecycleOnFileChangeFiles; BOOL m_fBasicAuthEnabled;
BOOL m_fAnonymousAuthEnabled;
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
}; };

View File

@ -1,25 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
class ASPNETCORE_UTILS
{
public:
static
HRESULT
ReplacePlaceHolderWithValue(
_Inout_ LPWSTR pszStr,
_In_ LPWSTR pszPlaceholder,
_In_ DWORD cchPlaceholder,
_In_ DWORD dwValue,
_In_ DWORD dwNumDigitsInValue,
_Out_ BOOL *pfReplaced
);
private:
ASPNETCORE_UTILS()
{
}
};

View File

@ -0,0 +1,146 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once
//
// The key used for hash-table lookups, consists of the port on which the http process is created.
//
class ENVIRONMENT_VAR_ENTRY
{
public:
ENVIRONMENT_VAR_ENTRY():
_cRefs(1)
{
}
HRESULT
Initialize(
PCWSTR pszName,
PCWSTR pszValue
)
{
HRESULT hr = S_OK;
if (FAILED(hr = _strName.Copy(pszName)) ||
FAILED(hr = _strValue.Copy(pszValue)))
{
}
return hr;
}
VOID
Reference() const
{
InterlockedIncrement(&_cRefs);
}
VOID
Dereference() const
{
if (InterlockedDecrement(&_cRefs) == 0)
{
delete this;
}
}
PWSTR const
QueryName()
{
return _strName.QueryStr();
}
PWSTR const
QueryValue()
{
return _strValue.QueryStr();
}
private:
~ENVIRONMENT_VAR_ENTRY()
{
}
STRU _strName;
STRU _strValue;
mutable LONG _cRefs;
};
class ENVIRONMENT_VAR_HASH : public HASH_TABLE<ENVIRONMENT_VAR_ENTRY, PWSTR>
{
public:
ENVIRONMENT_VAR_HASH()
{}
PWSTR
ExtractKey(
ENVIRONMENT_VAR_ENTRY * pEntry
)
{
return pEntry->QueryName();
}
DWORD
CalcKeyHash(
PWSTR pszName
)
{
return HashStringNoCase(pszName);
}
BOOL
EqualKeys(
PWSTR pszName1,
PWSTR pszName2
)
{
return (_wcsicmp(pszName1, pszName2) == 0);
}
VOID
ReferenceRecord(
ENVIRONMENT_VAR_ENTRY * pEntry
)
{
pEntry->Reference();
}
VOID
DereferenceRecord(
ENVIRONMENT_VAR_ENTRY * pEntry
)
{
pEntry->Dereference();
}
static
VOID
CopyToMultiSz(
ENVIRONMENT_VAR_ENTRY * pEntry,
PVOID pvData
)
{
STRU strTemp;
MULTISZ *pMultiSz = static_cast<MULTISZ *>(pvData);
strTemp.Copy(pEntry->QueryName());
strTemp.Append(pEntry->QueryValue());
pMultiSz->Append(strTemp.QueryStr());
}
static
VOID
CopyToTable(
ENVIRONMENT_VAR_ENTRY * pEntry,
PVOID pvData
)
{
ENVIRONMENT_VAR_ENTRY * pNewEntry = new ENVIRONMENT_VAR_ENTRY();
pNewEntry->Initialize(pEntry->QueryName(), pEntry->QueryValue());
ENVIRONMENT_VAR_HASH *pHash = static_cast<ENVIRONMENT_VAR_HASH *>(pvData);
pHash->InsertRecord(pNewEntry);
}
private:
ENVIRONMENT_VAR_HASH(const ENVIRONMENT_VAR_HASH &);
void operator=(const ENVIRONMENT_VAR_HASH &);
};

View File

@ -1,19 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#pragma once #pragma once
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
forwardinghandler.h
Abstract:
Handler for handling URLs from out-of-box.
--*/
#include "forwarderconnection.h" #include "forwarderconnection.h"
#include "protocolconfig.h" #include "protocolconfig.h"
#include "serverprocess.h" #include "serverprocess.h"
@ -109,7 +98,13 @@ public:
DWORD dwStatusInformationLength DWORD dwStatusInformationLength
) )
{ {
FORWARDING_HANDLER * pThis = static_cast<FORWARDING_HANDLER *>(reinterpret_cast<PVOID>(dwContext)); FORWARDING_HANDLER * pThis = static_cast<FORWARDING_HANDLER *>(reinterpret_cast<PVOID>(dwContext));
if (pThis == NULL)
{
//error happened, nothing can be done here
return;
}
DBG_ASSERT(pThis->m_Signature == FORWARDING_HANDLER_SIGNATURE); DBG_ASSERT(pThis->m_Signature == FORWARDING_HANDLER_SIGNATURE);
pThis->OnWinHttpCompletionInternal(hRequest, pThis->OnWinHttpCompletionInternal(hRequest,
dwInternetStatus, dwInternetStatus,
@ -186,7 +181,6 @@ private:
__in const PROTOCOL_CONFIG * pProtocol, __in const PROTOCOL_CONFIG * pProtocol,
__in HINTERNET hConnect, __in HINTERNET hConnect,
__inout STRU * pstrUrl, __inout STRU * pstrUrl,
const STRU& strDestination,
ASPNETCORE_CONFIG* pAspNetCoreConfig, ASPNETCORE_CONFIG* pAspNetCoreConfig,
SERVER_PROCESS* pServerProcess SERVER_PROCESS* pServerProcess
); );
@ -201,7 +195,6 @@ private:
HRESULT HRESULT
GetHeaders( GetHeaders(
const PROTOCOL_CONFIG * pProtocol, const PROTOCOL_CONFIG * pProtocol,
PCWSTR pszDestination,
PCWSTR * ppszHeaders, PCWSTR * ppszHeaders,
DWORD * pcchHeaders, DWORD * pcchHeaders,
ASPNETCORE_CONFIG* pAspNetCoreConfig, ASPNETCORE_CONFIG* pAspNetCoreConfig,
@ -325,6 +318,10 @@ private:
bool m_fHandleClosedDueToClient; bool m_fHandleClosedDueToClient;
bool m_fResponseHeadersReceivedAndSet; bool m_fResponseHeadersReceivedAndSet;
BOOL m_fDoReverseRewriteHeaders; BOOL m_fDoReverseRewriteHeaders;
BOOL m_fErrorHandled;
BOOL m_fWebSocketUpgrade;
BOOL m_fFinishRequest;
BOOL m_fClientDisconnected;
DWORD m_msStartTime; DWORD m_msStartTime;
DWORD m_BytesToReceive; DWORD m_BytesToReceive;

View File

@ -33,12 +33,6 @@ class PROTOCOL_CONFIG
return m_msTimeout; return m_msTimeout;
} }
BOOL
QueryPreserveHostHeader() const
{
return m_fPreserveHostHeader;
}
BOOL BOOL
QueryReverseRewriteHeaders() const QueryReverseRewriteHeaders() const
{ {
@ -90,7 +84,6 @@ class PROTOCOL_CONFIG
private: private:
BOOL m_fKeepAlive; BOOL m_fKeepAlive;
BOOL m_fPreserveHostHeader;
BOOL m_fReverseRewriteHeaders; BOOL m_fReverseRewriteHeaders;
BOOL m_fIncludePortInXForwardedFor; BOOL m_fIncludePortInXForwardedFor;

View File

@ -6,14 +6,21 @@
#define MIN_PORT 1025 #define MIN_PORT 1025
#define MAX_PORT 48000 #define MAX_PORT 48000
#define MAX_RETRY 10 #define MAX_RETRY 10
#define MAX_ACTIVE_CHILD_PROCESSES 16
#define LOCALHOST "127.0.0.1" #define LOCALHOST "127.0.0.1"
#define ASPNETCORE_PORT_STR L"ASPNETCORE_PORT" #define ASPNETCORE_PORT_STR L"ASPNETCORE_PORT"
#define ASPNETCORE_PORT_PLACEHOLDER L"%ASPNETCORE_PORT%" #define ASPNETCORE_PORT_ENV_STR L"ASPNETCORE_PORT="
#define ASPNETCORE_PORT_PLACEHOLDER_CCH 17 #define ASPNETCORE_APP_PATH_ENV_STR L"ASPNETCORE_APPL_PATH="
#define ASPNETCORE_DEBUG_PORT_STR L"ASPNETCORE_DEBUG_PORT" #define ASPNETCORE_APP_TOKEN_ENV_STR L"ASPNETCORE_TOKEN="
#define ASPNETCORE_DEBUG_PORT_PLACEHOLDER L"%ASPNETCORE_DEBUG_PORT%" #define ASPNETCORE_APP_PATH_ENV_STR L"ASPNETCORE_APPL_PATH="
#define ASPNETCORE_DEBUG_PORT_PLACEHOLDER_CCH 23 #define HOSTING_STARTUP_ASSEMBLIES_ENV_STR L"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES"
#define MAX_ACTIVE_CHILD_PROCESSES 16 #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;
class FORWARDER_CONNECTION; class FORWARDER_CONNECTION;
@ -25,14 +32,17 @@ public:
HRESULT HRESULT
Initialize( Initialize(
_In_ PROCESS_MANAGER *pProcessManager, _In_ PROCESS_MANAGER *pProcessManager,
_In_ STRU *pszProcessExePath, _In_ STRU *pszProcessExePath,
_In_ STRU *pszArguments, _In_ STRU *pszArguments,
_In_ DWORD dwStartupTimeLimitInMS, _In_ DWORD dwStartupTimeLimitInMS,
_In_ DWORD dwShtudownTimeLimitInMS, _In_ DWORD dwShtudownTimeLimitInMS,
_In_ MULTISZ *pszEnvironment, _In_ BOOL fWindowsAuthEnabled,
_In_ BOOL fStdoutLogEnabled, _In_ BOOL fBasicAuthEnabled,
_In_ STRU *pstruStdoutLogFile _In_ BOOL fAnonymousAuthEnabled,
_In_ ENVIRONMENT_VAR_HASH* pEnvironmentVariables,
_In_ BOOL fStdoutLogEnabled,
_In_ STRU *pstruStdoutLogFile
); );
@ -66,12 +76,6 @@ public:
return m_dwPort; return m_dwPort;
} }
DWORD
GetDebugPort()
{
return m_dwDebugPort;
}
VOID VOID
ReferenceServerProcess( ReferenceServerProcess(
VOID VOID
@ -118,6 +122,12 @@ public:
_In_ PTP_TIMER Timer _In_ PTP_TIMER Timer
); );
LPCWSTR
QueryPortStr()
{
return m_struPort.QueryStr();
}
LPCWSTR LPCWSTR
QueryFullLogPath() QueryFullLogPath()
{ {
@ -159,12 +169,6 @@ private:
_In_ LPSTARTUPINFOW pStartupInfo _In_ LPSTARTUPINFOW pStartupInfo
); );
HRESULT
CheckIfServerIsUp(
_In_ DWORD dwPort,
_Out_ BOOL *pfReady
);
HRESULT HRESULT
CheckIfServerIsUp( CheckIfServerIsUp(
_In_ DWORD dwPort, _In_ DWORD dwPort,
@ -182,13 +186,49 @@ private:
GetChildProcessHandles( GetChildProcessHandles(
); );
DWORD HRESULT
GenerateRandomPort( SetupListenPort(
VOID ENVIRONMENT_VAR_HASH *pEnvironmentVarTable
) );
{
return (rand() % (MAX_PORT - MIN_PORT)) + MIN_PORT + 1; HRESULT
} SetupAppPath(
IHttpContext* pContext,
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
);
HRESULT
SetupAppToken(
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
);
HRESULT
InitEnvironmentVariablesTable(
ENVIRONMENT_VAR_HASH** pEnvironmentVarTable
);
HRESULT
OutputEnvironmentVariables(
MULTISZ* pmszOutput,
ENVIRONMENT_VAR_HASH* pEnvironmentVarTable
);
HRESULT
SetupCommandLine(
STRU* pstrCommandLine
);
HRESULT
PostStartCheck(
const STRU* const pStruCommandline,
STRU* pStruErrorMessage
);
HRESULT
GetRandomPort(
DWORD* pdwPickedPort,
DWORD dwExcludedPort
);
DWORD DWORD
GetNumberOfDigits( GetNumberOfDigits(
@ -213,44 +253,51 @@ private:
} }
FORWARDER_CONNECTION *m_pForwarderConnection; FORWARDER_CONNECTION *m_pForwarderConnection;
HANDLE m_hJobObject;
BOOL m_fStdoutLogEnabled; BOOL m_fStdoutLogEnabled;
BOOL m_fWindowsAuthEnabled;
BOOL m_fBasicAuthEnabled;
BOOL m_fAnonymousAuthEnabled;
STTIMER m_Timer;
SOCKET m_socket;
STRU m_struLogFile; STRU m_struLogFile;
STRU m_struFullLogFile; STRU m_struFullLogFile;
STTIMER m_Timer;
HANDLE m_hStdoutHandle;
volatile LONG m_lStopping;
volatile BOOL m_fReady;
CRITICAL_SECTION m_csLock;
SOCKET m_socket;
DWORD m_dwPort;
DWORD m_dwDebugPort;
STRU m_ProcessPath; STRU m_ProcessPath;
STRU m_Arguments; STRU m_Arguments;
STRU m_struAppPath;
STRU m_struAppFullPath;
STRU m_struPort;
STRU m_pszRootApplicationPath;
volatile LONG m_lStopping;
volatile BOOL m_fReady;
mutable LONG m_cRefs;
DWORD m_dwPort;
DWORD m_dwStartupTimeLimitInMS; DWORD m_dwStartupTimeLimitInMS;
DWORD m_dwShutdownTimeLimitInMS; DWORD m_dwShutdownTimeLimitInMS;
MULTISZ m_Environment;
mutable LONG m_cRefs;
HANDLE m_hProcessWaitHandle;
DWORD m_cChildProcess; DWORD m_cChildProcess;
HANDLE m_hChildProcessWaitHandles[MAX_ACTIVE_CHILD_PROCESSES]; DWORD m_dwChildProcessIds[MAX_ACTIVE_CHILD_PROCESSES];
DWORD m_dwProcessId; DWORD m_dwProcessId;
DWORD m_dwListeningProcessId; DWORD m_dwListeningProcessId;
STRA m_straGuid; STRA m_straGuid;
HANDLE m_hJobObject;
HANDLE m_hStdoutHandle;
// //
// m_hProcessHandle is the handle to process this object creates. // m_hProcessHandle is the handle to process this object creates.
// //
HANDLE m_hProcessHandle; HANDLE m_hProcessHandle;
HANDLE m_hListeningProcessHandle; HANDLE m_hListeningProcessHandle;
HANDLE m_hProcessWaitHandle;
// //
// m_hChildProcessHandle is the handle to process created by // m_hChildProcessHandle is the handle to process created by
// m_hProcessHandle process if it does. // m_hProcessHandle process if it does.
// //
HANDLE m_hChildProcessHandles[MAX_ACTIVE_CHILD_PROCESSES]; HANDLE m_hChildProcessHandles[MAX_ACTIVE_CHILD_PROCESSES];
DWORD m_dwChildProcessIds[MAX_ACTIVE_CHILD_PROCESSES]; HANDLE m_hChildProcessWaitHandles[MAX_ACTIVE_CHILD_PROCESSES];
PROCESS_MANAGER *m_pProcessManager; PROCESS_MANAGER *m_pProcessManager;
ENVIRONMENT_VAR_HASH *m_pEnvironmentVarTable ;
}; };

View File

@ -5,6 +5,12 @@
APPLICATION::~APPLICATION() APPLICATION::~APPLICATION()
{ {
if (m_pAppOfflineHtm != NULL)
{
m_pAppOfflineHtm->DereferenceAppOfflineHtm();
m_pAppOfflineHtm = NULL;
}
if (m_pFileWatcherEntry != NULL) if (m_pFileWatcherEntry != NULL)
{ {
// Mark the entry as invalid, // Mark the entry as invalid,
@ -109,6 +115,7 @@ APPLICATION::UpdateAppOfflineFileHandle()
STRU strFilePath; STRU strFilePath;
PATH::ConvertPathToFullPath(L".\\app_offline.htm", m_strAppPhysicalPath.QueryStr(), &strFilePath); PATH::ConvertPathToFullPath(L".\\app_offline.htm", m_strAppPhysicalPath.QueryStr(), &strFilePath);
APP_OFFLINE_HTM *pOldAppOfflineHtm = NULL; APP_OFFLINE_HTM *pOldAppOfflineHtm = NULL;
APP_OFFLINE_HTM *pNewAppOfflineHtm = NULL;
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFilePath.QueryStr()) && GetLastError() == ERROR_FILE_NOT_FOUND) if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFilePath.QueryStr()) && GetLastError() == ERROR_FILE_NOT_FOUND)
{ {
@ -117,30 +124,41 @@ APPLICATION::UpdateAppOfflineFileHandle()
else else
{ {
m_fAppOfflineFound = TRUE; m_fAppOfflineFound = TRUE;
APP_OFFLINE_HTM *pNewAppOfflineHtm = new APP_OFFLINE_HTM(strFilePath.QueryStr());
DBG_ASSERT(pNewAppOfflineHtm != NULL); //
// send shutdown signal
//
if (pNewAppOfflineHtm->Load()) // The reason why we send the shutdown signal before loading the new app_offline file is because we want to make some delay
// before reading the appoffline.htm so that the file change can be done on time.
if (m_pProcessManager != NULL)
{ {
// m_pProcessManager->SendShutdownSignal();
// loaded new app offline htm }
//
pOldAppOfflineHtm = (APP_OFFLINE_HTM *)InterlockedExchangePointer((VOID**)&m_pAppOfflineHtm, pNewAppOfflineHtm);
// pNewAppOfflineHtm = new APP_OFFLINE_HTM(strFilePath.QueryStr());
// send shutdown signal to the app
// if ( pNewAppOfflineHtm != NULL )
if (m_pProcessManager != NULL) {
if (pNewAppOfflineHtm->Load())
{ {
m_pProcessManager->SendShutdownSignal(); //
// loaded the new app_offline.htm
//
pOldAppOfflineHtm = (APP_OFFLINE_HTM *)InterlockedExchangePointer((VOID**)&m_pAppOfflineHtm, pNewAppOfflineHtm);
if (pOldAppOfflineHtm != NULL)
{
pOldAppOfflineHtm->DereferenceAppOfflineHtm();
pOldAppOfflineHtm = NULL;
}
}
else
{
// ignored the new app_offline file because the file does not exist.
pNewAppOfflineHtm->DereferenceAppOfflineHtm();
pNewAppOfflineHtm = NULL;
} }
} }
} }
if (pOldAppOfflineHtm != NULL)
{
pOldAppOfflineHtm->DereferenceAppOfflineHtm();
pOldAppOfflineHtm = NULL;
}
} }

View File

@ -12,6 +12,12 @@ ASPNETCORE_CONFIG::~ASPNETCORE_CONFIG()
{ {
APPLICATION_MANAGER::GetInstance()->RecycleApplication(m_struApplication.QueryStr()); APPLICATION_MANAGER::GetInstance()->RecycleApplication(m_struApplication.QueryStr());
} }
if(m_pEnvironmentVariables != NULL)
{
m_pEnvironmentVariables->Clear();
delete m_pEnvironmentVariables;
m_pEnvironmentVariables = NULL;
}
} }
HRESULT HRESULT
@ -24,7 +30,7 @@ ASPNETCORE_CONFIG::GetConfig(
IHttpApplication *pHttpApplication = pHttpContext->GetApplication(); IHttpApplication *pHttpApplication = pHttpContext->GetApplication();
ASPNETCORE_CONFIG *pAspNetCoreConfig = NULL; ASPNETCORE_CONFIG *pAspNetCoreConfig = NULL;
if( ppAspNetCoreConfig == NULL) if (ppAspNetCoreConfig == NULL)
{ {
hr = E_INVALIDARG; hr = E_INVALIDARG;
goto Finished; goto Finished;
@ -33,10 +39,10 @@ ASPNETCORE_CONFIG::GetConfig(
*ppAspNetCoreConfig = NULL; *ppAspNetCoreConfig = NULL;
// potential bug if user sepcific config at virtual dir level // potential bug if user sepcific config at virtual dir level
pAspNetCoreConfig = (ASPNETCORE_CONFIG*) pAspNetCoreConfig = (ASPNETCORE_CONFIG*)
pHttpApplication->GetModuleContextContainer()->GetModuleContext(g_pModuleId); pHttpApplication->GetModuleContextContainer()->GetModuleContext(g_pModuleId);
if( pAspNetCoreConfig != NULL ) if (pAspNetCoreConfig != NULL)
{ {
*ppAspNetCoreConfig = pAspNetCoreConfig; *ppAspNetCoreConfig = pAspNetCoreConfig;
pAspNetCoreConfig = NULL; pAspNetCoreConfig = NULL;
@ -44,31 +50,31 @@ ASPNETCORE_CONFIG::GetConfig(
} }
pAspNetCoreConfig = new ASPNETCORE_CONFIG; pAspNetCoreConfig = new ASPNETCORE_CONFIG;
if( pAspNetCoreConfig == NULL ) if (pAspNetCoreConfig == NULL)
{ {
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
goto Finished; goto Finished;
} }
hr = pAspNetCoreConfig->Populate( pHttpContext ); hr = pAspNetCoreConfig->Populate(pHttpContext);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = pHttpApplication->GetModuleContextContainer()-> hr = pHttpApplication->GetModuleContextContainer()->
SetModuleContext( pAspNetCoreConfig, g_pModuleId ); SetModuleContext(pAspNetCoreConfig, g_pModuleId);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
if( hr == HRESULT_FROM_WIN32( ERROR_ALREADY_ASSIGNED ) ) if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
{ {
delete pAspNetCoreConfig; delete pAspNetCoreConfig;
pAspNetCoreConfig = (ASPNETCORE_CONFIG*) pHttpApplication-> pAspNetCoreConfig = (ASPNETCORE_CONFIG*)pHttpApplication->
GetModuleContextContainer()-> GetModuleContextContainer()->
GetModuleContext( g_pModuleId ); GetModuleContext(g_pModuleId);
_ASSERT( pAspNetCoreConfig != NULL ); _ASSERT(pAspNetCoreConfig != NULL);
hr = S_OK; hr = S_OK;
} }
@ -79,8 +85,8 @@ ASPNETCORE_CONFIG::GetConfig(
} }
else else
{ {
// set appliction info here instead of inside Populate() // set appliction info here instead of inside Populate()
// as the destructor will delete the backend process // as the destructor will delete the backend process
hr = pAspNetCoreConfig->QueryApplicationPath()->Copy(pHttpApplication->GetApplicationId()); hr = pAspNetCoreConfig->QueryApplicationPath()->Copy(pHttpApplication->GetApplicationId());
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -93,7 +99,7 @@ ASPNETCORE_CONFIG::GetConfig(
Finished: Finished:
if( pAspNetCoreConfig != NULL ) if (pAspNetCoreConfig != NULL)
{ {
delete pAspNetCoreConfig; delete pAspNetCoreConfig;
pAspNetCoreConfig = NULL; pAspNetCoreConfig = NULL;
@ -102,82 +108,134 @@ Finished:
return hr; return hr;
} }
VOID ReverseMultisz( MULTISZ * pmszInput,
LPCWSTR pszStr,
MULTISZ * pmszOutput )
{
if(pszStr == NULL) return;
ReverseMultisz( pmszInput, pmszInput->Next( pszStr ), pmszOutput );
pmszOutput->Append( pszStr );
}
HRESULT HRESULT
ASPNETCORE_CONFIG::Populate( ASPNETCORE_CONFIG::Populate(
IHttpContext *pHttpContext IHttpContext *pHttpContext
) )
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
STACK_STRU ( strSiteConfigPath, 256); STACK_STRU(strSiteConfigPath, 256);
STRU strEnvName; STRU strEnvName;
STRU strEnvValue; STRU strEnvValue;
STRU strFullEnvVar; STRU strExpandedEnvValue;
IAppHostAdminManager *pAdminManager = NULL; IAppHostAdminManager *pAdminManager = NULL;
IAppHostElement *pAspNetCoreElement = NULL; IAppHostElement *pAspNetCoreElement = NULL;
IAppHostElement *pWindowsAuthenticationElement = NULL;
IAppHostElement *pBasicAuthenticationElement = NULL;
IAppHostElement *pAnonymousAuthenticationElement = NULL;
IAppHostElement *pEnvVarList = NULL; IAppHostElement *pEnvVarList = NULL;
IAppHostElementCollection *pEnvVarCollection = NULL;
IAppHostElement *pEnvVar = NULL; IAppHostElement *pEnvVar = NULL;
//IAppHostElement *pRecycleOnFileChangeFileList = NULL; IAppHostElementCollection *pEnvVarCollection = NULL;
//IAppHostElementCollection *pRecycleOnFileChangeFileCollection = NULL;
//IAppHostElement *pRecycleOnFileChangeFile = NULL;
ULONGLONG ullRawTimeSpan = 0; ULONGLONG ullRawTimeSpan = 0;
ENUM_INDEX index; ENUM_INDEX index;
STRU strExpandedEnvValue; ENVIRONMENT_VAR_ENTRY* pEntry = NULL;
MULTISZ mszEnvironment;
MULTISZ mszEnvironmentListReverse; m_pEnvironmentVariables = new ENVIRONMENT_VAR_HASH();
MULTISZ mszEnvNames; if (m_pEnvironmentVariables == NULL)
LPWSTR pszEnvName; {
LPCWSTR pcszEnvName; hr = E_OUTOFMEMORY;
LPCWSTR pszEnvString; goto Finished;
STRU strFilePath; }
if (FAILED(hr = m_pEnvironmentVariables->Initialize(37 /*prime*/)))
{
delete m_pEnvironmentVariables;
m_pEnvironmentVariables = NULL;
goto Finished;
}
pAdminManager = g_pHttpServer->GetAdminManager(); pAdminManager = g_pHttpServer->GetAdminManager();
hr = strSiteConfigPath.Copy( pHttpContext->GetApplication()->GetAppConfigPath() ); hr = strSiteConfigPath.Copy(pHttpContext->GetApplication()->GetAppConfigPath());
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = pAdminManager->GetAdminSection( CS_ASPNETCORE_SECTION, hr = pAdminManager->GetAdminSection(CS_WINDOWS_AUTHENTICATION_SECTION,
strSiteConfigPath.QueryStr(), strSiteConfigPath.QueryStr(),
&pAspNetCoreElement ); &pWindowsAuthenticationElement);
if( FAILED( hr ) ) if (FAILED(hr))
{
// assume the corresponding authen was not enabled
// as the section may get deleted by user in some HWC case
// ToDo: log a warning to event log
m_fWindowsAuthEnabled = FALSE;
}
else
{
hr = GetElementBoolProperty(pWindowsAuthenticationElement,
CS_AUTHENTICATION_ENABLED,
&m_fWindowsAuthEnabled);
if (FAILED(hr))
{
goto Finished;
}
}
hr = pAdminManager->GetAdminSection(CS_BASIC_AUTHENTICATION_SECTION,
strSiteConfigPath.QueryStr(),
&pBasicAuthenticationElement);
if (FAILED(hr))
{
m_fBasicAuthEnabled = FALSE;
}
else
{
hr = GetElementBoolProperty(pBasicAuthenticationElement,
CS_AUTHENTICATION_ENABLED,
&m_fBasicAuthEnabled);
if (FAILED(hr))
{
goto Finished;
}
}
hr = pAdminManager->GetAdminSection(CS_ANONYMOUS_AUTHENTICATION_SECTION,
strSiteConfigPath.QueryStr(),
&pAnonymousAuthenticationElement);
if (FAILED(hr))
{
m_fAnonymousAuthEnabled = FALSE;
}
else
{
hr = GetElementBoolProperty(pAnonymousAuthenticationElement,
CS_AUTHENTICATION_ENABLED,
&m_fAnonymousAuthEnabled);
if (FAILED(hr))
{
goto Finished;
}
}
hr = pAdminManager->GetAdminSection(CS_ASPNETCORE_SECTION,
strSiteConfigPath.QueryStr(),
&pAspNetCoreElement);
if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = GetElementStringProperty( pAspNetCoreElement, hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_EXE_PATH, CS_ASPNETCORE_PROCESS_EXE_PATH,
&m_struProcessPath ); &m_struProcessPath);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = GetElementStringProperty( pAspNetCoreElement, hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_ARGUMENTS, CS_ASPNETCORE_PROCESS_ARGUMENTS,
&m_struArguments ); &m_struArguments);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = GetElementDWORDProperty( pAspNetCoreElement, hr = GetElementDWORDProperty(pAspNetCoreElement,
CS_ASPNETCORE_RAPID_FAILS_PER_MINUTE, CS_ASPNETCORE_RAPID_FAILS_PER_MINUTE,
&m_dwRapidFailsPerMinute ); &m_dwRapidFailsPerMinute);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
@ -185,298 +243,173 @@ ASPNETCORE_CONFIG::Populate(
// //
// rapidFailsPerMinute cannot be greater than 100. // rapidFailsPerMinute cannot be greater than 100.
// //
if (m_dwRapidFailsPerMinute > MAX_RAPID_FAILS_PER_MINUTE)
if(m_dwRapidFailsPerMinute > MAX_RAPID_FAILS_PER_MINUTE)
{ {
m_dwRapidFailsPerMinute = MAX_RAPID_FAILS_PER_MINUTE; m_dwRapidFailsPerMinute = MAX_RAPID_FAILS_PER_MINUTE;
} }
hr = GetElementDWORDProperty( pAspNetCoreElement, hr = GetElementDWORDProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESSES_PER_APPLICATION, CS_ASPNETCORE_PROCESSES_PER_APPLICATION,
&m_dwProcessesPerApplication ); &m_dwProcessesPerApplication);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = GetElementDWORDProperty( hr = GetElementDWORDProperty(
pAspNetCoreElement, pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT, CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT,
&m_dwStartupTimeLimitInMS &m_dwStartupTimeLimitInMS
); );
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
m_dwStartupTimeLimitInMS *= MILLISECONDS_IN_ONE_SECOND; m_dwStartupTimeLimitInMS *= MILLISECONDS_IN_ONE_SECOND;
hr = GetElementDWORDProperty( hr = GetElementDWORDProperty(
pAspNetCoreElement, pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_SHUTDOWN_TIME_LIMIT, CS_ASPNETCORE_PROCESS_SHUTDOWN_TIME_LIMIT,
&m_dwShutdownTimeLimitInMS &m_dwShutdownTimeLimitInMS
); );
if (FAILED(hr)) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
m_dwShutdownTimeLimitInMS *= MILLISECONDS_IN_ONE_SECOND; m_dwShutdownTimeLimitInMS *= MILLISECONDS_IN_ONE_SECOND;
hr = GetElementBoolProperty( pAspNetCoreElement, hr = GetElementBoolProperty(pAspNetCoreElement,
CS_ASPNETCORE_FORWARD_WINDOWS_AUTH_TOKEN, CS_ASPNETCORE_FORWARD_WINDOWS_AUTH_TOKEN,
&m_fForwardWindowsAuthToken ); &m_fForwardWindowsAuthToken);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = GetElementBoolProperty(pAspNetCoreElement, hr = GetElementBoolProperty(pAspNetCoreElement,
CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE, CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE,
&m_fDisableStartUpErrorPage); &m_fDisableStartUpErrorPage);
if (FAILED(hr)) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = GetElementRawTimeSpanProperty( hr = GetElementRawTimeSpanProperty(
pAspNetCoreElement, pAspNetCoreElement,
CS_ASPNETCORE_WINHTTP_REQUEST_TIMEOUT, CS_ASPNETCORE_WINHTTP_REQUEST_TIMEOUT,
&ullRawTimeSpan &ullRawTimeSpan
); );
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
m_dwRequestTimeoutInMS = (DWORD)TIMESPAN_IN_MILLISECONDS(ullRawTimeSpan); m_dwRequestTimeoutInMS = (DWORD)TIMESPAN_IN_MILLISECONDS(ullRawTimeSpan);
hr = GetElementBoolProperty( pAspNetCoreElement, hr = GetElementBoolProperty(pAspNetCoreElement,
CS_ASPNETCORE_STDOUT_LOG_ENABLED, CS_ASPNETCORE_STDOUT_LOG_ENABLED,
&m_fStdoutLogEnabled ); &m_fStdoutLogEnabled);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = GetElementStringProperty( pAspNetCoreElement, hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_STDOUT_LOG_FILE, CS_ASPNETCORE_STDOUT_LOG_FILE,
&m_struStdoutLogFile ); &m_struStdoutLogFile);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = GetElementChildByName( pAspNetCoreElement, hr = GetElementChildByName(pAspNetCoreElement,
CS_ASPNETCORE_ENVIRONMENT_VARIABLES, CS_ASPNETCORE_ENVIRONMENT_VARIABLES,
&pEnvVarList ); &pEnvVarList);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
hr = pEnvVarList->get_Collection( &pEnvVarCollection ); hr = pEnvVarList->get_Collection(&pEnvVarCollection);
if( FAILED( hr ) ) if (FAILED(hr))
{ {
goto Finished; goto Finished;
} }
for( hr = FindFirstElement( pEnvVarCollection, &index, &pEnvVar ) ; for (hr = FindFirstElement(pEnvVarCollection, &index, &pEnvVar);
SUCCEEDED( hr ) ; SUCCEEDED(hr);
hr = FindNextElement( pEnvVarCollection, &index, &pEnvVar ) ) hr = FindNextElement(pEnvVarCollection, &index, &pEnvVar))
{ {
if( hr == S_FALSE ) if (hr == S_FALSE)
{ {
hr = S_OK; hr = S_OK;
break; break;
} }
hr = GetElementStringProperty( pEnvVar, if (FAILED(hr = GetElementStringProperty(pEnvVar,
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_NAME, CS_ASPNETCORE_ENVIRONMENT_VARIABLE_NAME,
&strEnvName); &strEnvName)) ||
if( FAILED( hr ) ) FAILED(hr = GetElementStringProperty(pEnvVar,
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_VALUE,
&strEnvValue)) ||
FAILED(hr = strEnvName.Append(L"=")) ||
FAILED(hr = STRU::ExpandEnvironmentVariables(strEnvValue.QueryStr(), &strExpandedEnvValue)))
{ {
goto Finished; goto Finished;
} }
hr = GetElementStringProperty( pEnvVar, pEntry = new ENVIRONMENT_VAR_ENTRY();
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_VALUE, if (pEntry == NULL)
&strEnvValue);
if( FAILED( hr ) )
{
goto Finished;
}
hr = strFullEnvVar.Append(strEnvName);
if( FAILED( hr ) )
{
goto Finished;
}
hr = strFullEnvVar.Append(L"=");
if( FAILED( hr ) )
{
goto Finished;
}
pszEnvName = strFullEnvVar.QueryStr();
while( pszEnvName != NULL && *pszEnvName != '\0')
{
*pszEnvName = towupper( *pszEnvName );
pszEnvName++;
}
if( !mszEnvNames.FindString( strFullEnvVar ) )
{
if( !mszEnvNames.Append( strFullEnvVar ) )
{
hr = E_OUTOFMEMORY;
goto Finished;
}
}
hr = STRU::ExpandEnvironmentVariables( strEnvValue.QueryStr(), &strExpandedEnvValue );
if( FAILED( hr ) )
{
goto Finished;
}
hr = strFullEnvVar.Append(strExpandedEnvValue);
if( FAILED( hr ) )
{
goto Finished;
}
if( !mszEnvironment.Append(strFullEnvVar) )
{ {
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
goto Finished; goto Finished;
} }
if (FAILED(hr = pEntry->Initialize(strEnvName.QueryStr(), strExpandedEnvValue.QueryStr())) ||
FAILED(hr = m_pEnvironmentVariables->InsertRecord(pEntry)))
{
goto Finished;
}
strEnvName.Reset();
strEnvValue.Reset();
strExpandedEnvValue.Reset(); strExpandedEnvValue.Reset();
strFullEnvVar.Reset();
pEnvVar->Release(); pEnvVar->Release();
pEnvVar = NULL; pEnvVar = NULL;
pEntry = NULL;
} }
// basically the following logic is to select
ReverseMultisz( &mszEnvironment,
mszEnvironment.First(),
&mszEnvironmentListReverse );
pcszEnvName = mszEnvNames.First();
while(pcszEnvName != NULL)
{
pszEnvString = mszEnvironmentListReverse.First();
while( pszEnvString != NULL )
{
if(wcsstr(pszEnvString, pcszEnvName) != NULL)
{
if(!m_mszEnvironment.Append(pszEnvString))
{
hr = E_OUTOFMEMORY;
goto Finished;
}
break;
}
pszEnvString = mszEnvironmentListReverse.Next(pszEnvString);
}
pcszEnvName = mszEnvNames.Next(pcszEnvName);
}
//
// let's disable this feature for now
//
// get all files listed in recycleOnFileChange
/*
hr = GetElementChildByName( pAspNetCoreElement,
CS_ASPNETCORE_RECYCLE_ON_FILE_CHANGE,
&pRecycleOnFileChangeFileList );
if( FAILED( hr ) )
{
goto Finished;
}
hr = pRecycleOnFileChangeFileList->get_Collection( &pRecycleOnFileChangeFileCollection );
if( FAILED( hr ) )
{
goto Finished;
}
for( hr = FindFirstElement( pRecycleOnFileChangeFileCollection, &index, &pRecycleOnFileChangeFile ) ;
SUCCEEDED( hr ) ;
hr = FindNextElement( pRecycleOnFileChangeFileCollection, &index, &pRecycleOnFileChangeFile ) )
{
if( hr == S_FALSE )
{
hr = S_OK;
break;
}
hr = GetElementStringProperty( pRecycleOnFileChangeFile,
CS_ASPNETCORE_RECYCLE_ON_FILE_CHANGE_FILE_PATH,
&strFilePath);
if( FAILED( hr ) )
{
goto Finished;
}
if(!m_mszRecycleOnFileChangeFiles.Append( strFilePath ))
{
hr = E_OUTOFMEMORY;
goto Finished;
}
strFilePath.Reset();
pRecycleOnFileChangeFile->Release();
pRecycleOnFileChangeFile = NULL;
}
*/
Finished: Finished:
if( pAspNetCoreElement != NULL ) if (pAspNetCoreElement != NULL)
{ {
pAspNetCoreElement->Release(); pAspNetCoreElement->Release();
pAspNetCoreElement = NULL; pAspNetCoreElement = NULL;
} }
if( pEnvVarList != NULL ) if (pEnvVarList != NULL)
{ {
pEnvVarList->Release(); pEnvVarList->Release();
pEnvVarList = NULL; pEnvVarList = NULL;
} }
if( pEnvVar != NULL ) if (pEnvVar != NULL)
{ {
pEnvVar->Release(); pEnvVar->Release();
pEnvVar = NULL; pEnvVar = NULL;
} }
if( pEnvVarCollection != NULL ) if (pEnvVarCollection != NULL)
{ {
pEnvVarCollection->Release(); pEnvVarCollection->Release();
pEnvVarCollection = NULL; pEnvVarCollection = NULL;
} }
/* if( pRecycleOnFileChangeFileCollection != NULL ) if (pEntry != NULL)
{ {
pRecycleOnFileChangeFileCollection->Release(); pEntry->Dereference();
pRecycleOnFileChangeFileCollection = NULL; pEntry = NULL;
} }
if( pRecycleOnFileChangeFileList != NULL )
{
pRecycleOnFileChangeFileList->Release();
pRecycleOnFileChangeFileList = NULL;
}
if( pRecycleOnFileChangeFile != NULL )
{
pRecycleOnFileChangeFile->Release();
pRecycleOnFileChangeFile = NULL;
}*/
return hr; return hr;
} }

View File

@ -1,55 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
//
// ReplacePlaceHolderWithValue replaces a placeholder found in
// pszStr with dwValue.
// If replace is successful, pfReplaced is TRUE else FALSE.
//
HRESULT
ASPNETCORE_UTILS::ReplacePlaceHolderWithValue(
_Inout_ LPWSTR pszStr,
_In_ LPWSTR pszPlaceholder,
_In_ DWORD cchPlaceholder,
_In_ DWORD dwValue,
_In_ DWORD dwNumDigitsInValue,
_Out_ BOOL *pfReplaced
)
{
HRESULT hr = S_OK;
LPWSTR pszPortPlaceHolder = NULL;
DBG_ASSERT( pszStr != NULL );
DBG_ASSERT( pszPlaceholder != NULL );
DBG_ASSERT( pfReplaced != NULL );
*pfReplaced = FALSE;
if((pszPortPlaceHolder = wcsstr(pszStr, pszPlaceholder)) != NULL)
{
if( swprintf_s( pszPortPlaceHolder,
cchPlaceholder,
L"%u",
dwValue ) == -1 )
{
hr = HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
goto Finished;
}
if( wmemcpy_s( pszPortPlaceHolder + dwNumDigitsInValue,
cchPlaceholder,
L" ",
cchPlaceholder - dwNumDigitsInValue ) != 0 )
{
hr = HRESULT_FROM_WIN32( EINVAL );
goto Finished;
}
*pfReplaced = TRUE;
}
Finished:
return hr;
}

View File

@ -318,7 +318,7 @@ FILE_WATCHER_ENTRY::Monitor(VOID)
_buffDirectoryChanges.QueryPtr(), _buffDirectoryChanges.QueryPtr(),
_buffDirectoryChanges.QuerySize(), _buffDirectoryChanges.QuerySize(),
FALSE, // Watching sub dirs. Set to False now as only monitoring app_offline FALSE, // Watching sub dirs. Set to False now as only monitoring app_offline
FILE_NOTIFY_VALID_MASK & ~FILE_NOTIFY_CHANGE_LAST_ACCESS & ~FILE_NOTIFY_CHANGE_ATTRIBUTES, FILE_NOTIFY_VALID_MASK & ~FILE_NOTIFY_CHANGE_LAST_ACCESS,
&cbRead, &cbRead,
&_overlapped, &_overlapped,
NULL)) NULL))

File diff suppressed because it is too large Load Diff

View File

@ -86,7 +86,7 @@ inline bool IsSpace(char ch)
#include <acache.h> #include <acache.h>
#include <time.h> #include <time.h>
#include "aspnetcoreutils.h" #include "environmentvariablehash.h"
#include "..\aspnetcore_msg.h" #include "..\aspnetcore_msg.h"
#include "aspnetcoreconfig.h" #include "aspnetcoreconfig.h"
#include "serverprocess.h" #include "serverprocess.h"

View File

@ -238,6 +238,9 @@ PROCESS_MANAGER::GetProcess(
pConfig->QueryArguments(), pConfig->QueryArguments(),
pConfig->QueryStartupTimeLimitInMS(), pConfig->QueryStartupTimeLimitInMS(),
pConfig->QueryShutdownTimeLimitInMS(), pConfig->QueryShutdownTimeLimitInMS(),
pConfig->QueryWindowsAuthEnabled(),
pConfig->QueryBasicAuthEnabled(),
pConfig->QueryAnonymousAuthEnabled(),
pConfig->QueryEnvironmentVariables(), pConfig->QueryEnvironmentVariables(),
pConfig->QueryStdoutLogEnabled(), pConfig->QueryStdoutLogEnabled(),
pConfig->QueryStdoutLogFile() pConfig->QueryStdoutLogFile()

View File

@ -11,7 +11,6 @@ PROTOCOL_CONFIG::Initialize()
m_fKeepAlive = TRUE; m_fKeepAlive = TRUE;
m_msTimeout = 120000; m_msTimeout = 120000;
m_fPreserveHostHeader = TRUE;
m_fReverseRewriteHeaders = FALSE; m_fReverseRewriteHeaders = FALSE;
if (FAILED(hr = m_strXForwardedForName.CopyW(L"X-Forwarded-For"))) if (FAILED(hr = m_strXForwardedForName.CopyW(L"X-Forwarded-For")))

File diff suppressed because it is too large Load Diff

View File

@ -212,7 +212,10 @@ WEBSOCKET_HANDLER::IndicateCompletionToIIS(
_pHandler->SetStatus(FORWARDER_DONE); _pHandler->SetStatus(FORWARDER_DONE);
_pHttpContext->IndicateCompletion(RQ_NOTIFICATION_PENDING); // do not call IndicateCompletion here
// wait for handle close callback and then call IndicateCompletion
// otherwise we may release W3Context too early and cause AV
//_pHttpContext->IndicateCompletion(RQ_NOTIFICATION_PENDING);
} }
HRESULT HRESULT
@ -744,18 +747,25 @@ Routine Description:
++*/ ++*/
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
BOOL fLocked = FALSE;
CleanupReason cleanupReason = CleanupReasonUnknown; CleanupReason cleanupReason = CleanupReasonUnknown;
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::OnWinHttpSendComplete"); "WEBSOCKET_HANDLER::OnWinHttpSendComplete");
EnterCriticalSection (&_RequestLock);
if (_fCleanupInProgress) if (_fCleanupInProgress)
{ {
goto Finished; goto Finished;
} }
EnterCriticalSection (&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress)
{
goto Finished;
}
// //
// Data was successfully sent to backend. // Data was successfully sent to backend.
// Initiate next receive from IIS. // Initiate next receive from IIS.
@ -768,8 +778,10 @@ Routine Description:
} }
Finished: Finished:
if (fLocked)
LeaveCriticalSection(&_RequestLock); {
LeaveCriticalSection(&_RequestLock);
}
if (FAILED (hr)) if (FAILED (hr))
{ {
@ -840,18 +852,24 @@ Routine Description:
--*/ --*/
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
BOOL fLocked = FALSE;
CleanupReason cleanupReason = CleanupReasonUnknown; CleanupReason cleanupReason = CleanupReasonUnknown;
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::OnWinHttpReceiveComplete"); "WEBSOCKET_HANDLER::OnWinHttpReceiveComplete");
EnterCriticalSection(&_RequestLock);
if (_fCleanupInProgress) if (_fCleanupInProgress)
{ {
goto Finished; goto Finished;
} }
EnterCriticalSection(&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress)
{
goto Finished;
}
hr = DoIisWebSocketSend( hr = DoIisWebSocketSend(
pCompletionStatus->dwBytesTransferred, pCompletionStatus->dwBytesTransferred,
pCompletionStatus->eBufferType pCompletionStatus->eBufferType
@ -864,9 +882,10 @@ Routine Description:
} }
Finished: Finished:
if (fLocked)
LeaveCriticalSection(&_RequestLock); {
LeaveCriticalSection(&_RequestLock);
}
if (FAILED (hr)) if (FAILED (hr))
{ {
Cleanup (cleanupReason); Cleanup (cleanupReason);
@ -902,21 +921,26 @@ Routine Description:
--*/ --*/
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
BOOL fLocked = FALSE;
CleanupReason cleanupReason = CleanupReasonUnknown; CleanupReason cleanupReason = CleanupReasonUnknown;
UNREFERENCED_PARAMETER(cbIo); UNREFERENCED_PARAMETER(cbIo);
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, "WEBSOCKET_HANDLER::OnIisSendComplete"); DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, "WEBSOCKET_HANDLER::OnIisSendComplete");
EnterCriticalSection(&_RequestLock); if (FAILED(hrCompletion))
if (FAILED (hrCompletion))
{ {
hr = hrCompletion; hr = hrCompletion;
cleanupReason = ClientDisconnect; cleanupReason = ClientDisconnect;
goto Finished; goto Finished;
} }
if (_fCleanupInProgress)
{
goto Finished;
}
EnterCriticalSection(&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress) if (_fCleanupInProgress)
{ {
goto Finished; goto Finished;
@ -934,9 +958,10 @@ Routine Description:
} }
Finished: Finished:
if (fLocked)
LeaveCriticalSection(&_RequestLock); {
LeaveCriticalSection(&_RequestLock);
}
if (FAILED (hr)) if (FAILED (hr))
{ {
Cleanup (cleanupReason); Cleanup (cleanupReason);
@ -977,15 +1002,14 @@ Routine Description:
--*/ --*/
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
BOOL fLocked = FALSE;
CleanupReason cleanupReason = CleanupReasonUnknown; CleanupReason cleanupReason = CleanupReasonUnknown;
WINHTTP_WEB_SOCKET_BUFFER_TYPE BufferType; WINHTTP_WEB_SOCKET_BUFFER_TYPE BufferType;
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::OnIisReceiveComplete"); "WEBSOCKET_HANDLER::OnIisReceiveComplete");
EnterCriticalSection(&_RequestLock); if (FAILED(hrCompletion))
if (FAILED (hrCompletion))
{ {
cleanupReason = ClientDisconnect; cleanupReason = ClientDisconnect;
hr = hrCompletion; hr = hrCompletion;
@ -997,6 +1021,13 @@ Routine Description:
goto Finished; goto Finished;
} }
EnterCriticalSection(&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress)
{
goto Finished;
}
// //
// Get Buffer Type from flags. // Get Buffer Type from flags.
// //
@ -1018,9 +1049,10 @@ Routine Description:
} }
Finished: Finished:
if (fLocked)
LeaveCriticalSection(&_RequestLock); {
LeaveCriticalSection(&_RequestLock);
}
if (FAILED (hr)) if (FAILED (hr))
{ {
Cleanup (cleanupReason); Cleanup (cleanupReason);
@ -1042,7 +1074,7 @@ Finished:
VOID VOID
WEBSOCKET_HANDLER::Cleanup( WEBSOCKET_HANDLER::Cleanup(
CleanupReason reason CleanupReason reason
) )
/*++ /*++
Routine Description: Routine Description:
@ -1056,11 +1088,18 @@ Arguments:
CleanupReason CleanupReason
--*/ --*/
{ {
DebugPrintf (ASPNETCORE_DEBUG_FLAG_INFO, BOOL fLocked = FALSE;
"WEBSOCKET_HANDLER::Cleanup Initiated with reason %d", reason); DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::Cleanup Initiated with reason %d", reason);
if (_fCleanupInProgress)
{
goto Finished;
}
EnterCriticalSection(&_RequestLock); EnterCriticalSection(&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress) if (_fCleanupInProgress)
{ {
goto Finished; goto Finished;
@ -1080,5 +1119,8 @@ Arguments:
_pHttpContext->CancelIo(); _pHttpContext->CancelIo();
Finished: Finished:
LeaveCriticalSection(&_RequestLock); if (fLocked)
{
LeaveCriticalSection(&_RequestLock);
}
} }