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

View File

@ -70,10 +70,12 @@ public:
VOID
)
{
BOOL fResult = FALSE;
BOOL fResult = TRUE;
LARGE_INTEGER li = {0};
CHAR *pszBuff = NULL;
HANDLE handle = CreateFile( m_Path.QueryStr(),
HANDLE handle = INVALID_HANDLE_VALUE;
handle = CreateFile( m_Path.QueryStr(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@ -81,8 +83,15 @@ public:
FILE_ATTRIBUTE_NORMAL,
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;
}
@ -91,8 +100,6 @@ public:
goto Finished;
}
fResult = TRUE;
if( li.HighPart != 0 )
{
// > 4gb file size not supported
@ -113,10 +120,10 @@ public:
}
Finished:
if( handle )
if( handle != INVALID_HANDLE_VALUE )
{
CloseHandle(handle);
handle = NULL;
handle = INVALID_HANDLE_VALUE;
}
if( pszBuff != NULL )

View File

@ -5,6 +5,10 @@
#define CS_ROOTWEB_CONFIG L"MACHINE/WEBROOT/APPHOST/"
#define CS_ROOTWEB_CONFIG_LEN _countof(CS_ROOTWEB_CONFIG)-1
#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_ARGUMENTS L"arguments"
#define CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT L"startupTimeLimit"
@ -34,7 +38,6 @@
extern HTTP_MODULE_ID g_pModuleId;
extern IHttpServer * g_pHttpServer;
class ASPNETCORE_CONFIG : IHttpStoredContext
{
public:
@ -54,13 +57,13 @@ public:
_In_ IHttpContext *pHttpContext,
_Out_ ASPNETCORE_CONFIG **ppAspNetCoreConfig
);
MULTISZ*
ENVIRONMENT_VAR_HASH*
QueryEnvironmentVariables(
VOID
)
{
return &m_mszEnvironment;
return m_pEnvironmentVariables;
}
DWORD
@ -139,6 +142,24 @@ public:
return m_fForwardWindowsAuthToken;
}
BOOL
QueryWindowsAuthEnabled()
{
return m_fWindowsAuthEnabled;
}
BOOL
QueryBasicAuthEnabled()
{
return m_fBasicAuthEnabled;
}
BOOL
QueryAnonymousAuthEnabled()
{
return m_fAnonymousAuthEnabled;
}
BOOL
QueryDisableStartUpErrorPage()
{
@ -155,10 +176,10 @@ private:
//
// private constructor
//
//
ASPNETCORE_CONFIG():
m_fStdoutLogEnabled( FALSE )
m_fStdoutLogEnabled( FALSE ),
m_pEnvironmentVariables( NULL )
{
}
@ -167,18 +188,20 @@ private:
IHttpContext *pHttpContext
);
DWORD m_dwRequestTimeoutInMS;
DWORD m_dwStartupTimeLimitInMS;
DWORD m_dwShutdownTimeLimitInMS;
MULTISZ m_mszEnvironment;
DWORD m_dwRapidFailsPerMinute;
STRU m_struApplication;
STRU m_struArguments;
STRU m_struProcessPath;
BOOL m_fStdoutLogEnabled;
STRU m_struStdoutLogFile;
DWORD m_dwProcessesPerApplication;
BOOL m_fForwardWindowsAuthToken;
BOOL m_fDisableStartUpErrorPage;
MULTISZ m_mszRecycleOnFileChangeFiles;
DWORD m_dwRequestTimeoutInMS;
DWORD m_dwStartupTimeLimitInMS;
DWORD m_dwShutdownTimeLimitInMS;
DWORD m_dwRapidFailsPerMinute;
DWORD m_dwProcessesPerApplication;
STRU m_struApplication;
STRU m_struArguments;
STRU m_struProcessPath;
STRU m_struStdoutLogFile;
BOOL m_fStdoutLogEnabled;
BOOL m_fForwardWindowsAuthToken;
BOOL m_fDisableStartUpErrorPage;
BOOL m_fWindowsAuthEnabled;
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
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
forwardinghandler.h
Abstract:
Handler for handling URLs from out-of-box.
--*/
#include "forwarderconnection.h"
#include "protocolconfig.h"
#include "serverprocess.h"
@ -109,7 +98,13 @@ public:
DWORD dwStatusInformationLength
)
{
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);
pThis->OnWinHttpCompletionInternal(hRequest,
dwInternetStatus,
@ -186,7 +181,6 @@ private:
__in const PROTOCOL_CONFIG * pProtocol,
__in HINTERNET hConnect,
__inout STRU * pstrUrl,
const STRU& strDestination,
ASPNETCORE_CONFIG* pAspNetCoreConfig,
SERVER_PROCESS* pServerProcess
);
@ -201,7 +195,6 @@ private:
HRESULT
GetHeaders(
const PROTOCOL_CONFIG * pProtocol,
PCWSTR pszDestination,
PCWSTR * ppszHeaders,
DWORD * pcchHeaders,
ASPNETCORE_CONFIG* pAspNetCoreConfig,
@ -325,6 +318,10 @@ private:
bool m_fHandleClosedDueToClient;
bool m_fResponseHeadersReceivedAndSet;
BOOL m_fDoReverseRewriteHeaders;
BOOL m_fErrorHandled;
BOOL m_fWebSocketUpgrade;
BOOL m_fFinishRequest;
BOOL m_fClientDisconnected;
DWORD m_msStartTime;
DWORD m_BytesToReceive;

View File

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

View File

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

View File

@ -5,6 +5,12 @@
APPLICATION::~APPLICATION()
{
if (m_pAppOfflineHtm != NULL)
{
m_pAppOfflineHtm->DereferenceAppOfflineHtm();
m_pAppOfflineHtm = NULL;
}
if (m_pFileWatcherEntry != NULL)
{
// Mark the entry as invalid,
@ -109,6 +115,7 @@ APPLICATION::UpdateAppOfflineFileHandle()
STRU strFilePath;
PATH::ConvertPathToFullPath(L".\\app_offline.htm", m_strAppPhysicalPath.QueryStr(), &strFilePath);
APP_OFFLINE_HTM *pOldAppOfflineHtm = NULL;
APP_OFFLINE_HTM *pNewAppOfflineHtm = NULL;
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFilePath.QueryStr()) && GetLastError() == ERROR_FILE_NOT_FOUND)
{
@ -117,30 +124,41 @@ APPLICATION::UpdateAppOfflineFileHandle()
else
{
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)
{
//
// loaded new app offline htm
//
pOldAppOfflineHtm = (APP_OFFLINE_HTM *)InterlockedExchangePointer((VOID**)&m_pAppOfflineHtm, pNewAppOfflineHtm);
m_pProcessManager->SendShutdownSignal();
}
//
// send shutdown signal to the app
//
if (m_pProcessManager != NULL)
pNewAppOfflineHtm = new APP_OFFLINE_HTM(strFilePath.QueryStr());
if ( pNewAppOfflineHtm != 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());
}
if(m_pEnvironmentVariables != NULL)
{
m_pEnvironmentVariables->Clear();
delete m_pEnvironmentVariables;
m_pEnvironmentVariables = NULL;
}
}
HRESULT
@ -24,7 +30,7 @@ ASPNETCORE_CONFIG::GetConfig(
IHttpApplication *pHttpApplication = pHttpContext->GetApplication();
ASPNETCORE_CONFIG *pAspNetCoreConfig = NULL;
if( ppAspNetCoreConfig == NULL)
if (ppAspNetCoreConfig == NULL)
{
hr = E_INVALIDARG;
goto Finished;
@ -33,10 +39,10 @@ ASPNETCORE_CONFIG::GetConfig(
*ppAspNetCoreConfig = NULL;
// potential bug if user sepcific config at virtual dir level
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)
pHttpApplication->GetModuleContextContainer()->GetModuleContext(g_pModuleId);
if( pAspNetCoreConfig != NULL )
if (pAspNetCoreConfig != NULL)
{
*ppAspNetCoreConfig = pAspNetCoreConfig;
pAspNetCoreConfig = NULL;
@ -44,31 +50,31 @@ ASPNETCORE_CONFIG::GetConfig(
}
pAspNetCoreConfig = new ASPNETCORE_CONFIG;
if( pAspNetCoreConfig == NULL )
if (pAspNetCoreConfig == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pAspNetCoreConfig->Populate( pHttpContext );
if( FAILED( hr ) )
hr = pAspNetCoreConfig->Populate(pHttpContext);
if (FAILED(hr))
{
goto Finished;
}
hr = pHttpApplication->GetModuleContextContainer()->
SetModuleContext( pAspNetCoreConfig, g_pModuleId );
if( FAILED( hr ) )
SetModuleContext(pAspNetCoreConfig, g_pModuleId);
if (FAILED(hr))
{
if( hr == HRESULT_FROM_WIN32( ERROR_ALREADY_ASSIGNED ) )
if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_ASSIGNED))
{
delete pAspNetCoreConfig;
pAspNetCoreConfig = (ASPNETCORE_CONFIG*) pHttpApplication->
GetModuleContextContainer()->
GetModuleContext( g_pModuleId );
pAspNetCoreConfig = (ASPNETCORE_CONFIG*)pHttpApplication->
GetModuleContextContainer()->
GetModuleContext(g_pModuleId);
_ASSERT( pAspNetCoreConfig != NULL );
_ASSERT(pAspNetCoreConfig != NULL);
hr = S_OK;
}
@ -79,8 +85,8 @@ ASPNETCORE_CONFIG::GetConfig(
}
else
{
// set appliction info here instead of inside Populate()
// as the destructor will delete the backend process
// set appliction info here instead of inside Populate()
// as the destructor will delete the backend process
hr = pAspNetCoreConfig->QueryApplicationPath()->Copy(pHttpApplication->GetApplicationId());
if (FAILED(hr))
{
@ -93,7 +99,7 @@ ASPNETCORE_CONFIG::GetConfig(
Finished:
if( pAspNetCoreConfig != NULL )
if (pAspNetCoreConfig != NULL)
{
delete pAspNetCoreConfig;
pAspNetCoreConfig = NULL;
@ -102,82 +108,134 @@ Finished:
return hr;
}
VOID ReverseMultisz( MULTISZ * pmszInput,
LPCWSTR pszStr,
MULTISZ * pmszOutput )
{
if(pszStr == NULL) return;
ReverseMultisz( pmszInput, pmszInput->Next( pszStr ), pmszOutput );
pmszOutput->Append( pszStr );
}
HRESULT
ASPNETCORE_CONFIG::Populate(
IHttpContext *pHttpContext
)
{
HRESULT hr = S_OK;
STACK_STRU ( strSiteConfigPath, 256);
STACK_STRU(strSiteConfigPath, 256);
STRU strEnvName;
STRU strEnvValue;
STRU strFullEnvVar;
STRU strExpandedEnvValue;
IAppHostAdminManager *pAdminManager = NULL;
IAppHostElement *pAspNetCoreElement = NULL;
IAppHostElement *pWindowsAuthenticationElement = NULL;
IAppHostElement *pBasicAuthenticationElement = NULL;
IAppHostElement *pAnonymousAuthenticationElement = NULL;
IAppHostElement *pEnvVarList = NULL;
IAppHostElementCollection *pEnvVarCollection = NULL;
IAppHostElement *pEnvVar = NULL;
//IAppHostElement *pRecycleOnFileChangeFileList = NULL;
//IAppHostElementCollection *pRecycleOnFileChangeFileCollection = NULL;
//IAppHostElement *pRecycleOnFileChangeFile = NULL;
IAppHostElementCollection *pEnvVarCollection = NULL;
ULONGLONG ullRawTimeSpan = 0;
ENUM_INDEX index;
STRU strExpandedEnvValue;
MULTISZ mszEnvironment;
MULTISZ mszEnvironmentListReverse;
MULTISZ mszEnvNames;
LPWSTR pszEnvName;
LPCWSTR pcszEnvName;
LPCWSTR pszEnvString;
STRU strFilePath;
ENVIRONMENT_VAR_ENTRY* pEntry = NULL;
m_pEnvironmentVariables = new ENVIRONMENT_VAR_HASH();
if (m_pEnvironmentVariables == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
if (FAILED(hr = m_pEnvironmentVariables->Initialize(37 /*prime*/)))
{
delete m_pEnvironmentVariables;
m_pEnvironmentVariables = NULL;
goto Finished;
}
pAdminManager = g_pHttpServer->GetAdminManager();
hr = strSiteConfigPath.Copy( pHttpContext->GetApplication()->GetAppConfigPath() );
if( FAILED( hr ) )
hr = strSiteConfigPath.Copy(pHttpContext->GetApplication()->GetAppConfigPath());
if (FAILED(hr))
{
goto Finished;
}
hr = pAdminManager->GetAdminSection( CS_ASPNETCORE_SECTION,
strSiteConfigPath.QueryStr(),
&pAspNetCoreElement );
if( FAILED( hr ) )
hr = pAdminManager->GetAdminSection(CS_WINDOWS_AUTHENTICATION_SECTION,
strSiteConfigPath.QueryStr(),
&pWindowsAuthenticationElement);
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;
}
hr = GetElementStringProperty( pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_EXE_PATH,
&m_struProcessPath );
if( FAILED( hr ) )
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_EXE_PATH,
&m_struProcessPath);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementStringProperty( pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_ARGUMENTS,
&m_struArguments );
if( FAILED( hr ) )
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_ARGUMENTS,
&m_struArguments);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementDWORDProperty( pAspNetCoreElement,
CS_ASPNETCORE_RAPID_FAILS_PER_MINUTE,
&m_dwRapidFailsPerMinute );
if( FAILED( hr ) )
hr = GetElementDWORDProperty(pAspNetCoreElement,
CS_ASPNETCORE_RAPID_FAILS_PER_MINUTE,
&m_dwRapidFailsPerMinute);
if (FAILED(hr))
{
goto Finished;
}
@ -185,298 +243,173 @@ ASPNETCORE_CONFIG::Populate(
//
// 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;
}
hr = GetElementDWORDProperty( pAspNetCoreElement,
CS_ASPNETCORE_PROCESSES_PER_APPLICATION,
&m_dwProcessesPerApplication );
if( FAILED( hr ) )
hr = GetElementDWORDProperty(pAspNetCoreElement,
CS_ASPNETCORE_PROCESSES_PER_APPLICATION,
&m_dwProcessesPerApplication);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementDWORDProperty(
pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT,
&m_dwStartupTimeLimitInMS
);
if( FAILED( hr ) )
hr = GetElementDWORDProperty(
pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT,
&m_dwStartupTimeLimitInMS
);
if (FAILED(hr))
{
goto Finished;
}
m_dwStartupTimeLimitInMS *= MILLISECONDS_IN_ONE_SECOND;
hr = GetElementDWORDProperty(
pAspNetCoreElement,
CS_ASPNETCORE_PROCESS_SHUTDOWN_TIME_LIMIT,
&m_dwShutdownTimeLimitInMS
);
);
if (FAILED(hr))
{
goto Finished;
}
m_dwShutdownTimeLimitInMS *= MILLISECONDS_IN_ONE_SECOND;
hr = GetElementBoolProperty( pAspNetCoreElement,
CS_ASPNETCORE_FORWARD_WINDOWS_AUTH_TOKEN,
&m_fForwardWindowsAuthToken );
if( FAILED( hr ) )
hr = GetElementBoolProperty(pAspNetCoreElement,
CS_ASPNETCORE_FORWARD_WINDOWS_AUTH_TOKEN,
&m_fForwardWindowsAuthToken);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementBoolProperty(pAspNetCoreElement,
CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE,
&m_fDisableStartUpErrorPage);
CS_ASPNETCORE_DISABLE_START_UP_ERROR_PAGE,
&m_fDisableStartUpErrorPage);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementRawTimeSpanProperty(
pAspNetCoreElement,
CS_ASPNETCORE_WINHTTP_REQUEST_TIMEOUT,
&ullRawTimeSpan
);
if( FAILED( hr ) )
hr = GetElementRawTimeSpanProperty(
pAspNetCoreElement,
CS_ASPNETCORE_WINHTTP_REQUEST_TIMEOUT,
&ullRawTimeSpan
);
if (FAILED(hr))
{
goto Finished;
}
m_dwRequestTimeoutInMS = (DWORD)TIMESPAN_IN_MILLISECONDS(ullRawTimeSpan);
hr = GetElementBoolProperty( pAspNetCoreElement,
CS_ASPNETCORE_STDOUT_LOG_ENABLED,
&m_fStdoutLogEnabled );
if( FAILED( hr ) )
hr = GetElementBoolProperty(pAspNetCoreElement,
CS_ASPNETCORE_STDOUT_LOG_ENABLED,
&m_fStdoutLogEnabled);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementStringProperty( pAspNetCoreElement,
CS_ASPNETCORE_STDOUT_LOG_FILE,
&m_struStdoutLogFile );
if( FAILED( hr ) )
hr = GetElementStringProperty(pAspNetCoreElement,
CS_ASPNETCORE_STDOUT_LOG_FILE,
&m_struStdoutLogFile);
if (FAILED(hr))
{
goto Finished;
}
hr = GetElementChildByName( pAspNetCoreElement,
CS_ASPNETCORE_ENVIRONMENT_VARIABLES,
&pEnvVarList );
if( FAILED( hr ) )
hr = GetElementChildByName(pAspNetCoreElement,
CS_ASPNETCORE_ENVIRONMENT_VARIABLES,
&pEnvVarList);
if (FAILED(hr))
{
goto Finished;
}
hr = pEnvVarList->get_Collection( &pEnvVarCollection );
if( FAILED( hr ) )
hr = pEnvVarList->get_Collection(&pEnvVarCollection);
if (FAILED(hr))
{
goto Finished;
}
for( hr = FindFirstElement( pEnvVarCollection, &index, &pEnvVar ) ;
SUCCEEDED( hr ) ;
hr = FindNextElement( pEnvVarCollection, &index, &pEnvVar ) )
for (hr = FindFirstElement(pEnvVarCollection, &index, &pEnvVar);
SUCCEEDED(hr);
hr = FindNextElement(pEnvVarCollection, &index, &pEnvVar))
{
if( hr == S_FALSE )
if (hr == S_FALSE)
{
hr = S_OK;
break;
}
hr = GetElementStringProperty( pEnvVar,
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_NAME,
&strEnvName);
if( FAILED( hr ) )
if (FAILED(hr = GetElementStringProperty(pEnvVar,
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_NAME,
&strEnvName)) ||
FAILED(hr = GetElementStringProperty(pEnvVar,
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_VALUE,
&strEnvValue)) ||
FAILED(hr = strEnvName.Append(L"=")) ||
FAILED(hr = STRU::ExpandEnvironmentVariables(strEnvValue.QueryStr(), &strExpandedEnvValue)))
{
goto Finished;
}
hr = GetElementStringProperty( pEnvVar,
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_VALUE,
&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) )
pEntry = new ENVIRONMENT_VAR_ENTRY();
if (pEntry == NULL)
{
hr = E_OUTOFMEMORY;
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();
strFullEnvVar.Reset();
pEnvVar->Release();
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:
if( pAspNetCoreElement != NULL )
if (pAspNetCoreElement != NULL)
{
pAspNetCoreElement->Release();
pAspNetCoreElement = NULL;
}
if( pEnvVarList != NULL )
if (pEnvVarList != NULL)
{
pEnvVarList->Release();
pEnvVarList = NULL;
}
if( pEnvVar != NULL )
if (pEnvVar != NULL)
{
pEnvVar->Release();
pEnvVar = NULL;
}
if( pEnvVarCollection != NULL )
if (pEnvVarCollection != NULL)
{
pEnvVarCollection->Release();
pEnvVarCollection = NULL;
}
/* if( pRecycleOnFileChangeFileCollection != NULL )
if (pEntry != NULL)
{
pRecycleOnFileChangeFileCollection->Release();
pRecycleOnFileChangeFileCollection = NULL;
pEntry->Dereference();
pEntry = NULL;
}
if( pRecycleOnFileChangeFileList != NULL )
{
pRecycleOnFileChangeFileList->Release();
pRecycleOnFileChangeFileList = NULL;
}
if( pRecycleOnFileChangeFile != NULL )
{
pRecycleOnFileChangeFile->Release();
pRecycleOnFileChangeFile = NULL;
}*/
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.QuerySize(),
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,
&_overlapped,
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 <time.h>
#include "aspnetcoreutils.h"
#include "environmentvariablehash.h"
#include "..\aspnetcore_msg.h"
#include "aspnetcoreconfig.h"
#include "serverprocess.h"

View File

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

View File

@ -11,7 +11,6 @@ PROTOCOL_CONFIG::Initialize()
m_fKeepAlive = TRUE;
m_msTimeout = 120000;
m_fPreserveHostHeader = TRUE;
m_fReverseRewriteHeaders = FALSE;
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);
_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
@ -744,18 +747,25 @@ Routine Description:
++*/
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
CleanupReason cleanupReason = CleanupReasonUnknown;
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::OnWinHttpSendComplete");
EnterCriticalSection (&_RequestLock);
if (_fCleanupInProgress)
{
goto Finished;
}
EnterCriticalSection (&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress)
{
goto Finished;
}
//
// Data was successfully sent to backend.
// Initiate next receive from IIS.
@ -768,8 +778,10 @@ Routine Description:
}
Finished:
LeaveCriticalSection(&_RequestLock);
if (fLocked)
{
LeaveCriticalSection(&_RequestLock);
}
if (FAILED (hr))
{
@ -840,18 +852,24 @@ Routine Description:
--*/
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
CleanupReason cleanupReason = CleanupReasonUnknown;
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::OnWinHttpReceiveComplete");
EnterCriticalSection(&_RequestLock);
if (_fCleanupInProgress)
{
goto Finished;
}
EnterCriticalSection(&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress)
{
goto Finished;
}
hr = DoIisWebSocketSend(
pCompletionStatus->dwBytesTransferred,
pCompletionStatus->eBufferType
@ -864,9 +882,10 @@ Routine Description:
}
Finished:
LeaveCriticalSection(&_RequestLock);
if (fLocked)
{
LeaveCriticalSection(&_RequestLock);
}
if (FAILED (hr))
{
Cleanup (cleanupReason);
@ -902,21 +921,26 @@ Routine Description:
--*/
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
CleanupReason cleanupReason = CleanupReasonUnknown;
UNREFERENCED_PARAMETER(cbIo);
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, "WEBSOCKET_HANDLER::OnIisSendComplete");
EnterCriticalSection(&_RequestLock);
if (FAILED (hrCompletion))
if (FAILED(hrCompletion))
{
hr = hrCompletion;
cleanupReason = ClientDisconnect;
goto Finished;
}
if (_fCleanupInProgress)
{
goto Finished;
}
EnterCriticalSection(&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress)
{
goto Finished;
@ -934,9 +958,10 @@ Routine Description:
}
Finished:
LeaveCriticalSection(&_RequestLock);
if (fLocked)
{
LeaveCriticalSection(&_RequestLock);
}
if (FAILED (hr))
{
Cleanup (cleanupReason);
@ -977,15 +1002,14 @@ Routine Description:
--*/
{
HRESULT hr = S_OK;
BOOL fLocked = FALSE;
CleanupReason cleanupReason = CleanupReasonUnknown;
WINHTTP_WEB_SOCKET_BUFFER_TYPE BufferType;
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::OnIisReceiveComplete");
EnterCriticalSection(&_RequestLock);
if (FAILED (hrCompletion))
if (FAILED(hrCompletion))
{
cleanupReason = ClientDisconnect;
hr = hrCompletion;
@ -997,6 +1021,13 @@ Routine Description:
goto Finished;
}
EnterCriticalSection(&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress)
{
goto Finished;
}
//
// Get Buffer Type from flags.
//
@ -1018,9 +1049,10 @@ Routine Description:
}
Finished:
LeaveCriticalSection(&_RequestLock);
if (fLocked)
{
LeaveCriticalSection(&_RequestLock);
}
if (FAILED (hr))
{
Cleanup (cleanupReason);
@ -1042,7 +1074,7 @@ Finished:
VOID
WEBSOCKET_HANDLER::Cleanup(
CleanupReason reason
)
)
/*++
Routine Description:
@ -1056,11 +1088,18 @@ Arguments:
CleanupReason
--*/
{
DebugPrintf (ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::Cleanup Initiated with reason %d", reason);
BOOL fLocked = FALSE;
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
"WEBSOCKET_HANDLER::Cleanup Initiated with reason %d", reason);
if (_fCleanupInProgress)
{
goto Finished;
}
EnterCriticalSection(&_RequestLock);
fLocked = TRUE;
if (_fCleanupInProgress)
{
goto Finished;
@ -1080,5 +1119,8 @@ Arguments:
_pHttpContext->CancelIo();
Finished:
LeaveCriticalSection(&_RequestLock);
if (fLocked)
{
LeaveCriticalSection(&_RequestLock);
}
}