add features: flowing authentication info, hosting environment variable support; fix client disconnect and app_offline issues (#102)
resubmit
This commit is contained in:
parent
88cc1c14d0
commit
bce531f61a
|
|
@ -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" />
|
||||||
|
|
|
||||||
|
|
@ -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 )
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
@ -55,12 +58,12 @@ public:
|
||||||
_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()
|
||||||
{
|
{
|
||||||
|
|
@ -156,9 +177,9 @@ private:
|
||||||
//
|
//
|
||||||
// private constructor
|
// private constructor
|
||||||
//
|
//
|
||||||
|
|
||||||
ASPNETCORE_CONFIG():
|
ASPNETCORE_CONFIG():
|
||||||
m_fStdoutLogEnabled( FALSE )
|
m_fStdoutLogEnabled( FALSE ),
|
||||||
|
m_pEnvironmentVariables( NULL )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,15 +191,17 @@ private:
|
||||||
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;
|
||||||
DWORD m_dwProcessesPerApplication;
|
BOOL m_fStdoutLogEnabled;
|
||||||
BOOL m_fForwardWindowsAuthToken;
|
BOOL m_fForwardWindowsAuthToken;
|
||||||
BOOL m_fDisableStartUpErrorPage;
|
BOOL m_fDisableStartUpErrorPage;
|
||||||
MULTISZ m_mszRecycleOnFileChangeFiles;
|
BOOL m_fWindowsAuthEnabled;
|
||||||
|
BOOL m_fBasicAuthEnabled;
|
||||||
|
BOOL m_fAnonymousAuthEnabled;
|
||||||
|
ENVIRONMENT_VAR_HASH* m_pEnvironmentVariables;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -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 &);
|
||||||
|
};
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -30,7 +37,10 @@ public:
|
||||||
_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 fBasicAuthEnabled,
|
||||||
|
_In_ BOOL fAnonymousAuthEnabled,
|
||||||
|
_In_ ENVIRONMENT_VAR_HASH* pEnvironmentVariables,
|
||||||
_In_ BOOL fStdoutLogEnabled,
|
_In_ BOOL fStdoutLogEnabled,
|
||||||
_In_ STRU *pstruStdoutLogFile
|
_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 ;
|
||||||
};
|
};
|
||||||
|
|
@ -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);
|
|
||||||
|
|
||||||
if (pNewAppOfflineHtm->Load())
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// loaded new app offline htm
|
|
||||||
//
|
|
||||||
pOldAppOfflineHtm = (APP_OFFLINE_HTM *)InterlockedExchangePointer((VOID**)&m_pAppOfflineHtm, pNewAppOfflineHtm);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// send shutdown signal to the app
|
// send shutdown signal
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// 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)
|
if (m_pProcessManager != NULL)
|
||||||
{
|
{
|
||||||
m_pProcessManager->SendShutdownSignal();
|
m_pProcessManager->SendShutdownSignal();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
pNewAppOfflineHtm = new APP_OFFLINE_HTM(strFilePath.QueryStr());
|
||||||
|
|
||||||
|
if ( pNewAppOfflineHtm != NULL )
|
||||||
|
{
|
||||||
|
if (pNewAppOfflineHtm->Load())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// loaded the new app_offline.htm
|
||||||
|
//
|
||||||
|
pOldAppOfflineHtm = (APP_OFFLINE_HTM *)InterlockedExchangePointer((VOID**)&m_pAppOfflineHtm, pNewAppOfflineHtm);
|
||||||
|
|
||||||
if (pOldAppOfflineHtm != NULL)
|
if (pOldAppOfflineHtm != NULL)
|
||||||
{
|
{
|
||||||
pOldAppOfflineHtm->DereferenceAppOfflineHtm();
|
pOldAppOfflineHtm->DereferenceAppOfflineHtm();
|
||||||
pOldAppOfflineHtm = NULL;
|
pOldAppOfflineHtm = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ignored the new app_offline file because the file does not exist.
|
||||||
|
pNewAppOfflineHtm->DereferenceAppOfflineHtm();
|
||||||
|
pNewAppOfflineHtm = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -36,7 +42,7 @@ ASPNETCORE_CONFIG::GetConfig(
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
@ -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,16 +243,15 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +261,7 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
@ -222,10 +279,10 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
@ -243,240 +300,116 @@ ASPNETCORE_CONFIG::Populate(
|
||||||
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,
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = GetElementStringProperty( pEnvVar,
|
|
||||||
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_VALUE,
|
CS_ASPNETCORE_ENVIRONMENT_VARIABLE_VALUE,
|
||||||
&strEnvValue);
|
&strEnvValue)) ||
|
||||||
if( FAILED( hr ) )
|
FAILED(hr = strEnvName.Append(L"=")) ||
|
||||||
|
FAILED(hr = STRU::ExpandEnvironmentVariables(strEnvValue.QueryStr(), &strExpandedEnvValue)))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = strFullEnvVar.Append(strEnvName);
|
pEntry = new ENVIRONMENT_VAR_ENTRY();
|
||||||
if( FAILED( hr ) )
|
if (pEntry == NULL)
|
||||||
{
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -22,32 +22,36 @@ PROTOCOL_CONFIG FORWARDING_HANDLER::sm_ProtocolConfig;
|
||||||
|
|
||||||
FORWARDING_HANDLER::FORWARDING_HANDLER(
|
FORWARDING_HANDLER::FORWARDING_HANDLER(
|
||||||
__in IHttpContext * pW3Context
|
__in IHttpContext * pW3Context
|
||||||
) : m_Signature ( FORWARDING_HANDLER_SIGNATURE ),
|
) : m_Signature(FORWARDING_HANDLER_SIGNATURE),
|
||||||
m_cRefs ( 1 ),
|
m_cRefs(1),
|
||||||
m_pW3Context ( pW3Context ),
|
m_pW3Context(pW3Context),
|
||||||
m_pChildRequestContext ( NULL ),
|
m_pChildRequestContext(NULL),
|
||||||
m_hRequest ( NULL ),
|
m_hRequest(NULL),
|
||||||
m_fHandleClosedDueToClient( FALSE ),
|
m_fHandleClosedDueToClient(FALSE),
|
||||||
m_fResponseHeadersReceivedAndSet( FALSE ),
|
m_fResponseHeadersReceivedAndSet(FALSE),
|
||||||
m_fDoReverseRewriteHeaders ( FALSE ),
|
m_fDoReverseRewriteHeaders(FALSE),
|
||||||
m_msStartTime ( 0 ),
|
m_msStartTime(0),
|
||||||
m_BytesToReceive ( 0 ),
|
m_BytesToReceive(0),
|
||||||
m_BytesToSend ( 0 ),
|
m_BytesToSend(0),
|
||||||
m_pEntityBuffer ( NULL ),
|
m_pEntityBuffer(NULL),
|
||||||
m_cchLastSend ( 0 ),
|
m_cchLastSend(0),
|
||||||
m_cEntityBuffers ( 0 ),
|
m_cEntityBuffers(0),
|
||||||
m_cBytesBuffered ( 0 ),
|
m_cBytesBuffered(0),
|
||||||
m_cMinBufferLimit ( 0 ),
|
m_cMinBufferLimit(0),
|
||||||
m_pszOriginalHostHeader ( NULL ),
|
m_pszOriginalHostHeader(NULL),
|
||||||
m_RequestStatus ( FORWARDER_START ),
|
m_RequestStatus(FORWARDER_START),
|
||||||
m_pDisconnect ( NULL ),
|
m_pDisconnect(NULL),
|
||||||
m_pszHeaders ( NULL ),
|
m_pszHeaders(NULL),
|
||||||
m_cchHeaders ( 0 ),
|
m_cchHeaders(0),
|
||||||
m_fWebSocketEnabled ( FALSE ),
|
m_fWebSocketEnabled(FALSE),
|
||||||
m_cContentLength ( 0 ),
|
m_cContentLength(0),
|
||||||
m_pWebSocket ( NULL ),
|
m_pWebSocket(NULL),
|
||||||
m_pApplication( NULL ),
|
m_pApplication(NULL),
|
||||||
m_pAppOfflineHtm( NULL )
|
m_pAppOfflineHtm(NULL),
|
||||||
|
m_fErrorHandled(FALSE),
|
||||||
|
m_fWebSocketUpgrade(FALSE),
|
||||||
|
m_fFinishRequest(FALSE),
|
||||||
|
m_fClientDisconnected(FALSE)
|
||||||
{
|
{
|
||||||
InitializeSRWLock(&m_RequestLock);
|
InitializeSRWLock(&m_RequestLock);
|
||||||
}
|
}
|
||||||
|
|
@ -95,6 +99,10 @@ FORWARDING_HANDLER::~FORWARDING_HANDLER(
|
||||||
|
|
||||||
if (m_hRequest != NULL)
|
if (m_hRequest != NULL)
|
||||||
{
|
{
|
||||||
|
// m_hRequest should have already been closed and set to NULL
|
||||||
|
// if not, we cannot close it as it may callback and cause AV
|
||||||
|
// let's do our best job here
|
||||||
|
WinHttpSetStatusCallback(m_hRequest, NULL, NULL, NULL);
|
||||||
WinHttpCloseHandle(m_hRequest);
|
WinHttpCloseHandle(m_hRequest);
|
||||||
m_hRequest = NULL;
|
m_hRequest = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +113,7 @@ FORWARDING_HANDLER::~FORWARDING_HANDLER(
|
||||||
m_pApplication = NULL;
|
m_pApplication = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_pAppOfflineHtm != NULL )
|
if(m_pAppOfflineHtm != NULL)
|
||||||
{
|
{
|
||||||
m_pAppOfflineHtm->DereferenceAppOfflineHtm();
|
m_pAppOfflineHtm->DereferenceAppOfflineHtm();
|
||||||
m_pAppOfflineHtm = NULL;
|
m_pAppOfflineHtm = NULL;
|
||||||
|
|
@ -154,10 +162,10 @@ FORWARDING_HANDLER::DereferenceForwardingHandler(
|
||||||
VOID
|
VOID
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
DBG_ASSERT(m_cRefs != 0 );
|
DBG_ASSERT(m_cRefs != 0);
|
||||||
|
|
||||||
LONG cRefs = 0;
|
LONG cRefs = 0;
|
||||||
if ( (cRefs = InterlockedDecrement(&m_cRefs) ) == 0)
|
if ((cRefs = InterlockedDecrement(&m_cRefs)) == 0)
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
@ -179,8 +187,8 @@ FORWARDING_HANDLER::SetStatusAndHeaders(
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IHttpResponse * pResponse = m_pW3Context->GetResponse();
|
IHttpResponse * pResponse = m_pW3Context->GetResponse();
|
||||||
IHttpRequest * pRequest = m_pW3Context->GetRequest();
|
IHttpRequest * pRequest = m_pW3Context->GetRequest();
|
||||||
STACK_STRA ( strHeaderName, 128);
|
STACK_STRA(strHeaderName, 128);
|
||||||
STACK_STRA ( strHeaderValue, 2048);
|
STACK_STRA(strHeaderValue, 2048);
|
||||||
DWORD index = 0;
|
DWORD index = 0;
|
||||||
PSTR pchNewline;
|
PSTR pchNewline;
|
||||||
PCSTR pchEndofHeaderValue;
|
PCSTR pchEndofHeaderValue;
|
||||||
|
|
@ -341,7 +349,7 @@ FORWARDING_HANDLER::SetStatusAndHeaders(
|
||||||
//
|
//
|
||||||
// Copy the header value
|
// Copy the header value
|
||||||
//
|
//
|
||||||
if (pchEndofHeaderValue == pszHeaders+index)
|
if (pchEndofHeaderValue == pszHeaders + index)
|
||||||
{
|
{
|
||||||
strHeaderValue.Reset();
|
strHeaderValue.Reset();
|
||||||
}
|
}
|
||||||
|
|
@ -405,7 +413,7 @@ FORWARDING_HANDLER::SetStatusAndHeaders(
|
||||||
// Explicitly remove the Server header if the back-end didn't set one.
|
// Explicitly remove the Server header if the back-end didn't set one.
|
||||||
//
|
//
|
||||||
|
|
||||||
if ( !fServerHeaderPresent )
|
if (!fServerHeaderPresent)
|
||||||
{
|
{
|
||||||
pResponse->DeleteHeader("Server");
|
pResponse->DeleteHeader("Server");
|
||||||
}
|
}
|
||||||
|
|
@ -525,7 +533,7 @@ SetCookie:
|
||||||
// syntax name=value ; ... ; Domain=.host ; ...
|
// syntax name=value ; ... ; Domain=.host ; ...
|
||||||
//
|
//
|
||||||
pHeaders = &pResponse->GetRawHttpResponse()->Headers;
|
pHeaders = &pResponse->GetRawHttpResponse()->Headers;
|
||||||
for (DWORD i=0; i<pHeaders->UnknownHeaderCount; i++)
|
for (DWORD i = 0; i<pHeaders->UnknownHeaderCount; i++)
|
||||||
{
|
{
|
||||||
if (_stricmp(pHeaders->pUnknownHeaders[i].pName, "Set-Cookie") != 0)
|
if (_stricmp(pHeaders->pUnknownHeaders[i].pName, "Set-Cookie") != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -567,7 +575,7 @@ SetCookie:
|
||||||
pszStartHost++;
|
pszStartHost++;
|
||||||
}
|
}
|
||||||
pszEndHost = pszStartHost;
|
pszEndHost = pszStartHost;
|
||||||
while(!IsSpace(*pszEndHost) &&
|
while (!IsSpace(*pszEndHost) &&
|
||||||
*pszEndHost != ';' &&
|
*pszEndHost != ';' &&
|
||||||
*pszEndHost != '\0')
|
*pszEndHost != '\0')
|
||||||
{
|
{
|
||||||
|
|
@ -600,39 +608,45 @@ SetCookie:
|
||||||
HRESULT
|
HRESULT
|
||||||
FORWARDING_HANDLER::GetHeaders(
|
FORWARDING_HANDLER::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,
|
||||||
SERVER_PROCESS* pServerProcess
|
SERVER_PROCESS* pServerProcess
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IHttpRequest *pRequest = m_pW3Context->GetRequest();
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
PCSTR pszCurrentHeader;
|
PCSTR pszCurrentHeader;
|
||||||
USHORT cchCurrentHeader;
|
|
||||||
PCSTR pszFinalHeader;
|
|
||||||
DWORD cchFinalHeader;
|
|
||||||
STACK_STRA( strTemp, 64);
|
|
||||||
HTTP_REQUEST_HEADERS *pHeaders;
|
|
||||||
PCSTR ppHeadersToBeRemoved;
|
PCSTR ppHeadersToBeRemoved;
|
||||||
|
PCSTR pszFinalHeader;
|
||||||
|
USHORT cchCurrentHeader;
|
||||||
|
DWORD cchFinalHeader;
|
||||||
|
BOOL fSecure = FALSE; // dummy. Used in SplitUrl. Value will not be used
|
||||||
|
// as ANCM always use http protocol to communicate with backend
|
||||||
|
STRU struDestination;
|
||||||
|
STRU struUrl;
|
||||||
|
STACK_STRA(strTemp, 64);
|
||||||
|
HTTP_REQUEST_HEADERS *pHeaders;
|
||||||
|
IHttpRequest *pRequest = m_pW3Context->GetRequest();
|
||||||
MULTISZA mszMsAspNetCoreHeaders;
|
MULTISZA mszMsAspNetCoreHeaders;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Update host header if so configured
|
// We historically set the host section in request url to the new host header
|
||||||
|
// this is wrong but Kestrel has dependency on it.
|
||||||
|
// should change it in the future
|
||||||
//
|
//
|
||||||
if (!pProtocol->QueryPreserveHostHeader())
|
if (FAILED(hr = PATH::SplitUrl(pRequest->GetRawHttpRequest()->CookedUrl.pFullUrl,
|
||||||
{
|
&fSecure,
|
||||||
STACK_STRA( straTemp, 256 );
|
&struDestination,
|
||||||
if (FAILED(hr = straTemp.CopyW(pszDestination)) ||
|
&struUrl)) ||
|
||||||
|
FAILED(hr = strTemp.CopyW(struDestination.QueryStr())) ||
|
||||||
FAILED(hr = pRequest->SetHeader(HttpHeaderHost,
|
FAILED(hr = pRequest->SetHeader(HttpHeaderHost,
|
||||||
straTemp.QueryStr(),
|
strTemp.QueryStr(),
|
||||||
static_cast<USHORT>(straTemp.QueryCCH()),
|
static_cast<USHORT>(strTemp.QueryCCH()),
|
||||||
TRUE))) // fReplace
|
TRUE))) // fReplace
|
||||||
{
|
{
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Strip all headers starting with MS-ASPNETCORE.
|
// Strip all headers starting with MS-ASPNETCORE.
|
||||||
|
|
@ -641,11 +655,11 @@ FORWARDING_HANDLER::GetHeaders(
|
||||||
//
|
//
|
||||||
|
|
||||||
pHeaders = &m_pW3Context->GetRequest()->GetRawHttpRequest()->Headers;
|
pHeaders = &m_pW3Context->GetRequest()->GetRawHttpRequest()->Headers;
|
||||||
for (DWORD i=0; i<pHeaders->UnknownHeaderCount; i++)
|
for (DWORD i = 0; i<pHeaders->UnknownHeaderCount; i++)
|
||||||
{
|
{
|
||||||
if (_strnicmp(pHeaders->pUnknownHeaders[i].pName, "MS-ASPNETCORE", 13) == 0)
|
if (_strnicmp(pHeaders->pUnknownHeaders[i].pName, "MS-ASPNETCORE", 13) == 0)
|
||||||
{
|
{
|
||||||
mszMsAspNetCoreHeaders.Append( pHeaders->pUnknownHeaders[i].pName, (DWORD) pHeaders->pUnknownHeaders[i].NameLength );
|
mszMsAspNetCoreHeaders.Append(pHeaders->pUnknownHeaders[i].pName, (DWORD)pHeaders->pUnknownHeaders[i].NameLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -655,35 +669,35 @@ FORWARDING_HANDLER::GetHeaders(
|
||||||
// iterate the list of headers to be removed and delete them from the request.
|
// iterate the list of headers to be removed and delete them from the request.
|
||||||
//
|
//
|
||||||
|
|
||||||
while(ppHeadersToBeRemoved != NULL)
|
while (ppHeadersToBeRemoved != NULL)
|
||||||
{
|
{
|
||||||
m_pW3Context->GetRequest()->DeleteHeader( ppHeadersToBeRemoved );
|
m_pW3Context->GetRequest()->DeleteHeader(ppHeadersToBeRemoved);
|
||||||
ppHeadersToBeRemoved = mszMsAspNetCoreHeaders.Next( ppHeadersToBeRemoved );
|
ppHeadersToBeRemoved = mszMsAspNetCoreHeaders.Next(ppHeadersToBeRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pServerProcess->QueryGuid() != NULL )
|
if (pServerProcess->QueryGuid() != NULL)
|
||||||
{
|
{
|
||||||
hr = m_pW3Context->GetRequest()->SetHeader( "MS-ASPNETCORE-TOKEN",
|
hr = m_pW3Context->GetRequest()->SetHeader("MS-ASPNETCORE-TOKEN",
|
||||||
pServerProcess->QueryGuid(),
|
pServerProcess->QueryGuid(),
|
||||||
(USHORT)strlen(pServerProcess->QueryGuid()),
|
(USHORT)strlen(pServerProcess->QueryGuid()),
|
||||||
TRUE );
|
TRUE);
|
||||||
if(FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pAspNetCoreConfig->QueryForwardWindowsAuthToken() &&
|
if (pAspNetCoreConfig->QueryForwardWindowsAuthToken() &&
|
||||||
(_wcsicmp(m_pW3Context->GetUser()->GetAuthenticationType(), L"negotiate") == 0 ||
|
(_wcsicmp(m_pW3Context->GetUser()->GetAuthenticationType(), L"negotiate") == 0 ||
|
||||||
_wcsicmp(m_pW3Context->GetUser()->GetAuthenticationType(), L"ntlm") == 0) )
|
_wcsicmp(m_pW3Context->GetUser()->GetAuthenticationType(), L"ntlm") == 0))
|
||||||
{
|
{
|
||||||
if( m_pW3Context->GetUser()->GetPrimaryToken() != NULL &&
|
if (m_pW3Context->GetUser()->GetPrimaryToken() != NULL &&
|
||||||
m_pW3Context->GetUser()->GetPrimaryToken() != INVALID_HANDLE_VALUE )
|
m_pW3Context->GetUser()->GetPrimaryToken() != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
HANDLE hTargetTokenHandle = NULL;
|
HANDLE hTargetTokenHandle = NULL;
|
||||||
hr = pServerProcess->SetWindowsAuthToken( m_pW3Context->GetUser()->GetPrimaryToken(),
|
hr = pServerProcess->SetWindowsAuthToken(m_pW3Context->GetUser()->GetPrimaryToken(),
|
||||||
&hTargetTokenHandle );
|
&hTargetTokenHandle);
|
||||||
if(FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
@ -691,18 +705,18 @@ FORWARDING_HANDLER::GetHeaders(
|
||||||
//
|
//
|
||||||
// set request header with target token value
|
// set request header with target token value
|
||||||
//
|
//
|
||||||
CHAR pszHandleStr[16] = {0};
|
CHAR pszHandleStr[16] = { 0 };
|
||||||
if(_ui64toa_s( (UINT64) hTargetTokenHandle, pszHandleStr, 16, 16 ) != 0)
|
if (_ui64toa_s((UINT64)hTargetTokenHandle, pszHandleStr, 16, 16) != 0)
|
||||||
{
|
{
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = m_pW3Context->GetRequest()->SetHeader( "MS-ASPNETCORE-WINAUTHTOKEN",
|
hr = m_pW3Context->GetRequest()->SetHeader("MS-ASPNETCORE-WINAUTHTOKEN",
|
||||||
pszHandleStr,
|
pszHandleStr,
|
||||||
(USHORT)strlen(pszHandleStr),
|
(USHORT)strlen(pszHandleStr),
|
||||||
TRUE );
|
TRUE);
|
||||||
if(FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
@ -793,14 +807,14 @@ FORWARDING_HANDLER::GetHeaders(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(FAILED(hr = strTemp.Append(pszScheme)))
|
if (FAILED(hr = strTemp.Append(pszScheme)))
|
||||||
{
|
{
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(FAILED(pRequest->SetHeader(pProtocol->QuerySslHeaderName()->QueryStr(),
|
if (FAILED(pRequest->SetHeader(pProtocol->QuerySslHeaderName()->QueryStr(),
|
||||||
strTemp.QueryStr(),
|
strTemp.QueryStr(),
|
||||||
(USHORT) strTemp.QueryCCH(),
|
(USHORT)strTemp.QueryCCH(),
|
||||||
TRUE)))
|
TRUE)))
|
||||||
{
|
{
|
||||||
return hr;
|
return hr;
|
||||||
|
|
@ -816,8 +830,9 @@ FORWARDING_HANDLER::GetHeaders(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Resize the buffer large enough to hold the encoded certificate info
|
||||||
if (FAILED(hr = strTemp.Resize(
|
if (FAILED(hr = strTemp.Resize(
|
||||||
1 + (pRequest->GetRawHttpRequest()->pSslInfo->pClientCertInfo->CertEncodedSize + 2)/3 * 4)))
|
1 + (pRequest->GetRawHttpRequest()->pSslInfo->pClientCertInfo->CertEncodedSize + 2) / 3 * 4)))
|
||||||
{
|
{
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
@ -869,7 +884,6 @@ FORWARDING_HANDLER::CreateWinHttpRequest(
|
||||||
__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
|
||||||
)
|
)
|
||||||
|
|
@ -877,7 +891,7 @@ FORWARDING_HANDLER::CreateWinHttpRequest(
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
PCWSTR pszVersion = NULL;
|
PCWSTR pszVersion = NULL;
|
||||||
PCSTR pszVerb;
|
PCSTR pszVerb;
|
||||||
STACK_STRU( strVerb, 32 );
|
STACK_STRU(strVerb, 32);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create the request handle for this request (leave some fields blank,
|
// Create the request handle for this request (leave some fields blank,
|
||||||
|
|
@ -910,7 +924,7 @@ FORWARDING_HANDLER::CreateWinHttpRequest(
|
||||||
WINHTTP_NO_REFERER,
|
WINHTTP_NO_REFERER,
|
||||||
WINHTTP_DEFAULT_ACCEPT_TYPES,
|
WINHTTP_DEFAULT_ACCEPT_TYPES,
|
||||||
WINHTTP_FLAG_ESCAPE_DISABLE_QUERY
|
WINHTTP_FLAG_ESCAPE_DISABLE_QUERY
|
||||||
| g_OptionalWinHttpFlags );
|
| g_OptionalWinHttpFlags);
|
||||||
if (m_hRequest == NULL)
|
if (m_hRequest == NULL)
|
||||||
{
|
{
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
|
@ -964,8 +978,18 @@ FORWARDING_HANDLER::CreateWinHttpRequest(
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WinHttpSetStatusCallback(m_hRequest,
|
||||||
|
FORWARDING_HANDLER::OnWinHttpCompletion,
|
||||||
|
(WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS |
|
||||||
|
WINHTTP_CALLBACK_FLAG_HANDLES |
|
||||||
|
WINHTTP_CALLBACK_STATUS_SENDING_REQUEST),
|
||||||
|
NULL) == WINHTTP_INVALID_STATUS_CALLBACK)
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
hr = GetHeaders(pProtocol,
|
hr = GetHeaders(pProtocol,
|
||||||
strDestination.QueryStr(),
|
|
||||||
&m_pszHeaders,
|
&m_pszHeaders,
|
||||||
&m_cchHeaders,
|
&m_cchHeaders,
|
||||||
pAspNetCoreConfig,
|
pAspNetCoreConfig,
|
||||||
|
|
@ -982,7 +1006,7 @@ Finished:
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
REQUEST_NOTIFICATION_STATUS
|
||||||
FORWARDING_HANDLER::OnExecuteRequestHandler(
|
FORWARDING_HANDLER::OnExecuteRequestHandler(
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
REQUEST_NOTIFICATION_STATUS retVal = RQ_NOTIFICATION_CONTINUE;
|
REQUEST_NOTIFICATION_STATUS retVal = RQ_NOTIFICATION_CONTINUE;
|
||||||
|
|
@ -990,10 +1014,10 @@ VOID
|
||||||
bool fRequestLocked = FALSE;
|
bool fRequestLocked = FALSE;
|
||||||
ASPNETCORE_CONFIG *pAspNetCoreConfig = NULL;
|
ASPNETCORE_CONFIG *pAspNetCoreConfig = NULL;
|
||||||
FORWARDER_CONNECTION *pConnection = NULL;
|
FORWARDER_CONNECTION *pConnection = NULL;
|
||||||
STACK_STRU( strDestination, 32);
|
STACK_STRU(strDestination, 32);
|
||||||
STACK_STRU( strUrl, 2048);
|
STACK_STRU(strUrl, 2048);
|
||||||
STACK_STRU( struEscapedUrl, 2048);
|
STACK_STRU(struEscapedUrl, 2048);
|
||||||
STACK_STRU( strDescription, 128);
|
STACK_STRU(strDescription, 128);
|
||||||
HINTERNET hConnect = NULL;
|
HINTERNET hConnect = NULL;
|
||||||
IHttpRequest *pRequest = m_pW3Context->GetRequest();
|
IHttpRequest *pRequest = m_pW3Context->GetRequest();
|
||||||
IHttpResponse *pResponse = m_pW3Context->GetResponse();
|
IHttpResponse *pResponse = m_pW3Context->GetResponse();
|
||||||
|
|
@ -1065,8 +1089,8 @@ VOID
|
||||||
goto Failure;
|
goto Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pApplicationManager->GetApplication( m_pW3Context,
|
hr = pApplicationManager->GetApplication(m_pW3Context,
|
||||||
&m_pApplication );
|
&m_pApplication);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Failure;
|
goto Failure;
|
||||||
|
|
@ -1136,7 +1160,7 @@ VOID
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = m_pApplication->GetProcess( m_pW3Context,
|
hr = m_pApplication->GetProcess(m_pW3Context,
|
||||||
pAspNetCoreConfig,
|
pAspNetCoreConfig,
|
||||||
&pServerProcess);
|
&pServerProcess);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -1178,7 +1202,6 @@ VOID
|
||||||
pProtocol,
|
pProtocol,
|
||||||
hConnect,
|
hConnect,
|
||||||
&struEscapedUrl,
|
&struEscapedUrl,
|
||||||
strDestination,
|
|
||||||
pAspNetCoreConfig,
|
pAspNetCoreConfig,
|
||||||
pServerProcess);
|
pServerProcess);
|
||||||
|
|
||||||
|
|
@ -1443,7 +1466,7 @@ Finished:
|
||||||
pConnection = NULL;
|
pConnection = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pServerProcess != NULL )
|
if (pServerProcess != NULL)
|
||||||
{
|
{
|
||||||
pServerProcess->DereferenceServerProcess();
|
pServerProcess->DereferenceServerProcess();
|
||||||
pServerProcess = NULL;
|
pServerProcess = NULL;
|
||||||
|
|
@ -1494,17 +1517,17 @@ FORWARDING_HANDLER::OnAsyncCompletion(
|
||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Handle the completion from IIS and continue the execution
|
Handle the completion from IIS and continue the execution
|
||||||
of this request based on the current state.
|
of this request based on the current state.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
cbCompletion - Number of bytes associated with this completion
|
cbCompletion - Number of bytes associated with this completion
|
||||||
dwCompletionStatus - the win32 status associated with this completion
|
dwCompletionStatus - the win32 status associated with this completion
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
REQUEST_NOTIFICATION_STATUS
|
REQUEST_NOTIFICATION_STATUS
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
|
|
@ -1512,17 +1535,16 @@ Return Value:
|
||||||
REQUEST_NOTIFICATION_STATUS retVal = RQ_NOTIFICATION_CONTINUE;
|
REQUEST_NOTIFICATION_STATUS retVal = RQ_NOTIFICATION_CONTINUE;
|
||||||
BOOL fLocked = FALSE;
|
BOOL fLocked = FALSE;
|
||||||
bool fClientError = FALSE;
|
bool fClientError = FALSE;
|
||||||
DBG_ASSERT(m_pW3Context != NULL);
|
BOOL fClosed = FALSE;
|
||||||
__analysis_assume(m_pW3Context != NULL);
|
|
||||||
|
|
||||||
if ( sm_pTraceLog != NULL )
|
if (sm_pTraceLog != NULL)
|
||||||
{
|
{
|
||||||
WriteRefTraceLogEx( sm_pTraceLog,
|
WriteRefTraceLogEx(sm_pTraceLog,
|
||||||
m_cRefs,
|
m_cRefs,
|
||||||
this,
|
this,
|
||||||
"FORWARDING_HANDLER::OnAsyncCompletion Enter",
|
"FORWARDING_HANDLER::OnAsyncCompletion Enter",
|
||||||
reinterpret_cast<PVOID>(static_cast<DWORD_PTR>(cbCompletion)),
|
reinterpret_cast<PVOID>(static_cast<DWORD_PTR>(cbCompletion)),
|
||||||
reinterpret_cast<PVOID>(static_cast<DWORD_PTR>(hrCompletionStatus)) );
|
reinterpret_cast<PVOID>(static_cast<DWORD_PTR>(hrCompletionStatus)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -1534,6 +1556,9 @@ Return Value:
|
||||||
//
|
//
|
||||||
ReferenceForwardingHandler();
|
ReferenceForwardingHandler();
|
||||||
|
|
||||||
|
DBG_ASSERT(m_pW3Context != NULL);
|
||||||
|
__analysis_assume(m_pW3Context != NULL);
|
||||||
|
|
||||||
//
|
//
|
||||||
// OnAsyncCompletion can be called on a Winhttp io completion thread.
|
// OnAsyncCompletion can be called on a Winhttp io completion thread.
|
||||||
// Hence we need to check the TLS before we acquire the shared lock.
|
// Hence we need to check the TLS before we acquire the shared lock.
|
||||||
|
|
@ -1551,7 +1576,7 @@ Return Value:
|
||||||
|
|
||||||
if (m_hRequest == NULL)
|
if (m_hRequest == NULL)
|
||||||
{
|
{
|
||||||
if (m_RequestStatus == FORWARDER_DONE)
|
if (m_RequestStatus == FORWARDER_DONE && m_fFinishRequest)
|
||||||
{
|
{
|
||||||
retVal = RQ_NOTIFICATION_FINISH_REQUEST;
|
retVal = RQ_NOTIFICATION_FINISH_REQUEST;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
@ -1584,10 +1609,22 @@ Return Value:
|
||||||
//
|
//
|
||||||
// WebSocket upgrade is successful. Close the WinHttpRequest Handle
|
// WebSocket upgrade is successful. Close the WinHttpRequest Handle
|
||||||
//
|
//
|
||||||
|
WinHttpSetStatusCallback(m_hRequest,
|
||||||
WinHttpCloseHandle(m_hRequest);
|
FORWARDING_HANDLER::OnWinHttpCompletion,
|
||||||
|
WINHTTP_CALLBACK_FLAG_HANDLES,
|
||||||
|
NULL);
|
||||||
|
fClosed = WinHttpCloseHandle(m_hRequest);
|
||||||
|
DBG_ASSERT(fClosed);
|
||||||
|
if (fClosed)
|
||||||
|
{
|
||||||
|
m_fWebSocketUpgrade = TRUE;
|
||||||
m_hRequest = NULL;
|
m_hRequest = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
goto Failure;
|
||||||
|
}
|
||||||
retVal = RQ_NOTIFICATION_PENDING;
|
retVal = RQ_NOTIFICATION_PENDING;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
@ -1662,6 +1699,13 @@ Failure:
|
||||||
IHttpResponse *pResponse = m_pW3Context->GetResponse();
|
IHttpResponse *pResponse = m_pW3Context->GetResponse();
|
||||||
pResponse->DisableKernelCache();
|
pResponse->DisableKernelCache();
|
||||||
pResponse->GetRawHttpResponse()->EntityChunkCount = 0;
|
pResponse->GetRawHttpResponse()->EntityChunkCount = 0;
|
||||||
|
|
||||||
|
// double check to set right status code
|
||||||
|
if (!m_pW3Context->GetConnection()->IsConnected())
|
||||||
|
{
|
||||||
|
fClientError = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (fClientError)
|
if (fClientError)
|
||||||
{
|
{
|
||||||
if (!m_fResponseHeadersReceivedAndSet)
|
if (!m_fResponseHeadersReceivedAndSet)
|
||||||
|
|
@ -1679,14 +1723,14 @@ Failure:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
STACK_STRU( strDescription, 128);
|
STACK_STRU(strDescription, 128);
|
||||||
|
|
||||||
pResponse->SetStatus(502, "Bad Gateway", 3, hr);
|
pResponse->SetStatus(502, "Bad Gateway", 3, hr);
|
||||||
|
|
||||||
if (hr > HRESULT_FROM_WIN32(WINHTTP_ERROR_BASE) &&
|
if (hr > HRESULT_FROM_WIN32(WINHTTP_ERROR_BASE) &&
|
||||||
hr <= HRESULT_FROM_WIN32(WINHTTP_ERROR_LAST))
|
hr <= HRESULT_FROM_WIN32(WINHTTP_ERROR_LAST))
|
||||||
{
|
{
|
||||||
#pragma prefast (suppress : __WARNING_FUNCTION_NEEDS_REVIEW, "Function and parameters reviewed.")
|
#pragma prefast (suppress : __WARNING_FUNCTION_NEEDS_REVIEW, "Function and parameters reviewed.")
|
||||||
FormatMessage(
|
FormatMessage(
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
|
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
|
||||||
g_hWinHttpModule,
|
g_hWinHttpModule,
|
||||||
|
|
@ -1703,7 +1747,7 @@ Failure:
|
||||||
strDescription.QueryStr(),
|
strDescription.QueryStr(),
|
||||||
strDescription.QuerySizeCCH());
|
strDescription.QuerySizeCCH());
|
||||||
}
|
}
|
||||||
(VOID) strDescription.SyncWithBuffer();
|
(VOID)strDescription.SyncWithBuffer();
|
||||||
if (strDescription.QueryCCH() != 0)
|
if (strDescription.QueryCCH() != 0)
|
||||||
{
|
{
|
||||||
pResponse->SetErrorDescription(
|
pResponse->SetErrorDescription(
|
||||||
|
|
@ -1712,7 +1756,7 @@ Failure:
|
||||||
FALSE);
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE))
|
if (hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE))
|
||||||
{
|
{
|
||||||
pResponse->ResetConnection();
|
pResponse->ResetConnection();
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
@ -1832,8 +1876,8 @@ FORWARDING_HANDLER::OnSendingRequest(
|
||||||
m_pEntityBuffer[4] = '\r';
|
m_pEntityBuffer[4] = '\r';
|
||||||
m_pEntityBuffer[5] = '\n';
|
m_pEntityBuffer[5] = '\n';
|
||||||
|
|
||||||
m_pEntityBuffer[cbCompletion+6] = '\r';
|
m_pEntityBuffer[cbCompletion + 6] = '\r';
|
||||||
m_pEntityBuffer[cbCompletion+7] = '\n';
|
m_pEntityBuffer[cbCompletion + 7] = '\n';
|
||||||
|
|
||||||
if (cbCompletion < 0x10)
|
if (cbCompletion < 0x10)
|
||||||
{
|
{
|
||||||
|
|
@ -1918,7 +1962,7 @@ FORWARDING_HANDLER::OnReceivingResponse(
|
||||||
// buffering
|
// buffering
|
||||||
//
|
//
|
||||||
m_BytesToSend = min(m_cMinBufferLimit, BUFFER_SIZE);
|
m_BytesToSend = min(m_cMinBufferLimit, BUFFER_SIZE);
|
||||||
if (m_BytesToSend < BUFFER_SIZE/2)
|
if (m_BytesToSend < BUFFER_SIZE / 2)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Disable buffering.
|
// Disable buffering.
|
||||||
|
|
@ -1986,10 +2030,10 @@ Failure:
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FORWARDING_HANDLER::OnWinHttpCompletionInternal(
|
FORWARDING_HANDLER::OnWinHttpCompletionInternal(
|
||||||
HINTERNET hRequest,
|
HINTERNET hRequest,
|
||||||
DWORD dwInternetStatus,
|
DWORD dwInternetStatus,
|
||||||
LPVOID lpvStatusInformation,
|
LPVOID lpvStatusInformation,
|
||||||
DWORD dwStatusInformationLength
|
DWORD dwStatusInformationLength
|
||||||
)
|
)
|
||||||
/*++
|
/*++
|
||||||
|
|
||||||
|
|
@ -2018,6 +2062,7 @@ None
|
||||||
__analysis_assume(m_pW3Context != NULL);
|
__analysis_assume(m_pW3Context != NULL);
|
||||||
IHttpResponse * pResponse = m_pW3Context->GetResponse();
|
IHttpResponse * pResponse = m_pW3Context->GetResponse();
|
||||||
BOOL fDerefForwardingHandler = TRUE;
|
BOOL fDerefForwardingHandler = TRUE;
|
||||||
|
BOOL fEndRequest = FALSE;
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(dwStatusInformationLength);
|
UNREFERENCED_PARAMETER(dwStatusInformationLength);
|
||||||
|
|
||||||
|
|
@ -2032,14 +2077,69 @@ None
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// If the request is upgraded to websocket, route the completion
|
// ReadLock on the winhttp handle to protect from a client disconnect/
|
||||||
// to the websocket handler. We don't need to take the request lock,
|
// server stop closing the handle while we are using it.
|
||||||
// since for websocket request, the parent request handle is already
|
|
||||||
// closed.
|
|
||||||
//
|
//
|
||||||
|
// WinHttp can call async completion on the same thread/stack, so
|
||||||
|
// we have to account for that and not try to take the lock again,
|
||||||
|
// otherwise, we could end up in a deadlock.
|
||||||
|
//
|
||||||
|
// Take a reference so that object does not go away as a result of
|
||||||
|
// async completion - release one reference when async operation is
|
||||||
|
// initiated, two references if async operation is not initiated
|
||||||
|
//
|
||||||
|
|
||||||
|
if (TlsGetValue(g_dwTlsIndex) != this)
|
||||||
|
{
|
||||||
|
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == NULL);
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&m_RequestLock);
|
||||||
|
TlsSetValue(g_dwTlsIndex, this);
|
||||||
|
fIsCompletionThread = TRUE;
|
||||||
|
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == this);
|
||||||
|
}
|
||||||
|
|
||||||
|
fEndRequest = (dwInternetStatus == WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING);
|
||||||
|
if (!fEndRequest)
|
||||||
|
{
|
||||||
|
if (!m_pW3Context->GetConnection()->IsConnected())
|
||||||
|
{
|
||||||
|
m_fClientDisconnected = TRUE;
|
||||||
|
if (m_hRequest != NULL)
|
||||||
|
{
|
||||||
|
WinHttpSetStatusCallback(m_hRequest,
|
||||||
|
FORWARDING_HANDLER::OnWinHttpCompletion,
|
||||||
|
WINHTTP_CALLBACK_FLAG_HANDLES,
|
||||||
|
NULL);
|
||||||
|
if (WinHttpCloseHandle(m_hRequest))
|
||||||
|
{
|
||||||
|
m_hRequest = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if WinHttpCloseHandle failed, we are already in failure path
|
||||||
|
// nothing can can be done here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hr = ERROR_CONNECTION_ABORTED;
|
||||||
|
fClientError = m_fHandleClosedDueToClient = TRUE;
|
||||||
|
fDerefForwardingHandler = FALSE;
|
||||||
|
// wait for HANDLE_CLOSING callback to clean up
|
||||||
|
fAnotherCompletionExpected = !fEndRequest;
|
||||||
|
goto Failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_RequestStatus == FORWARDER_RECEIVED_WEBSOCKET_RESPONSE)
|
if (m_RequestStatus == FORWARDER_RECEIVED_WEBSOCKET_RESPONSE)
|
||||||
{
|
{
|
||||||
|
fDerefForwardingHandler = FALSE;
|
||||||
|
fAnotherCompletionExpected = TRUE;
|
||||||
|
|
||||||
|
if(m_pWebSocket == NULL)
|
||||||
|
{
|
||||||
|
goto Finished;
|
||||||
|
}
|
||||||
|
|
||||||
switch (dwInternetStatus)
|
switch (dwInternetStatus)
|
||||||
{
|
{
|
||||||
case WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE:
|
case WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE:
|
||||||
|
|
@ -2064,46 +2164,10 @@ None
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fDerefForwardingHandler = FALSE;
|
|
||||||
fAnotherCompletionExpected = TRUE;
|
|
||||||
|
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// ReadLock on the winhttp handle to protect from a client disconnect/
|
|
||||||
// server stop closing the handle while we are using it.
|
|
||||||
//
|
|
||||||
// WinHttp can call async completion on the same thread/stack, so
|
|
||||||
// we have to account for that and not try to take the lock again,
|
|
||||||
// otherwise, we could end up in a deadlock.
|
|
||||||
//
|
|
||||||
// Take a reference so that object does not go away as a result of
|
|
||||||
// async completion - release one reference when async operation is
|
|
||||||
// initiated, two references if async operation is not initiated
|
|
||||||
//
|
|
||||||
if (TlsGetValue(g_dwTlsIndex) != this)
|
|
||||||
{
|
|
||||||
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == NULL);
|
|
||||||
|
|
||||||
AcquireSRWLockShared(&m_RequestLock);
|
|
||||||
TlsSetValue(g_dwTlsIndex, this);
|
|
||||||
fIsCompletionThread = TRUE;
|
|
||||||
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_hRequest == NULL)
|
|
||||||
{
|
|
||||||
fClientError = m_fHandleClosedDueToClient;
|
|
||||||
goto Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_pWebSocket)
|
|
||||||
{
|
|
||||||
DBG_ASSERT(hRequest == m_hRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (dwInternetStatus)
|
switch (dwInternetStatus)
|
||||||
{
|
{
|
||||||
|
|
@ -2154,6 +2218,21 @@ None
|
||||||
fDerefForwardingHandler = FALSE;
|
fDerefForwardingHandler = FALSE;
|
||||||
fAnotherCompletionExpected = TRUE;
|
fAnotherCompletionExpected = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING:
|
||||||
|
if (m_RequestStatus != FORWARDER_DONE)
|
||||||
|
{
|
||||||
|
hr = ERROR_CONNECTION_ABORTED;
|
||||||
|
fClientError = m_fHandleClosedDueToClient;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fDerefForwardingHandler = m_fClientDisconnected && !m_fWebSocketUpgrade;
|
||||||
|
}
|
||||||
|
m_hRequest = NULL;
|
||||||
|
m_pWebSocket = NULL;
|
||||||
|
fAnotherCompletionExpected = FALSE;
|
||||||
|
break;
|
||||||
case WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED:
|
case WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED:
|
||||||
hr = ERROR_CONNECTION_ABORTED;
|
hr = ERROR_CONNECTION_ABORTED;
|
||||||
break;
|
break;
|
||||||
|
|
@ -2190,17 +2269,20 @@ None
|
||||||
goto Finished;
|
goto Finished;
|
||||||
|
|
||||||
Failure:
|
Failure:
|
||||||
|
m_RequestStatus = FORWARDER_DONE;
|
||||||
|
|
||||||
|
if (!m_fErrorHandled)
|
||||||
|
{
|
||||||
|
m_fErrorHandled = TRUE;
|
||||||
if (hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE))
|
if (hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE))
|
||||||
{
|
{
|
||||||
m_RequestStatus = FORWARDER_RESET_CONNECTION;
|
m_RequestStatus = FORWARDER_RESET_CONNECTION;
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_RequestStatus = FORWARDER_DONE;
|
|
||||||
|
|
||||||
pResponse->DisableKernelCache();
|
pResponse->DisableKernelCache();
|
||||||
pResponse->GetRawHttpResponse()->EntityChunkCount = 0;
|
pResponse->GetRawHttpResponse()->EntityChunkCount = 0;
|
||||||
|
fClientError = !m_pW3Context->GetConnection()->IsConnected();
|
||||||
if (fClientError)
|
if (fClientError)
|
||||||
{
|
{
|
||||||
if (!m_fResponseHeadersReceivedAndSet)
|
if (!m_fResponseHeadersReceivedAndSet)
|
||||||
|
|
@ -2251,8 +2333,10 @@ Failure:
|
||||||
FALSE);
|
FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
|
|
||||||
if (fIsCompletionThread)
|
if (fIsCompletionThread)
|
||||||
{
|
{
|
||||||
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == this);
|
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == this);
|
||||||
|
|
@ -2275,14 +2359,45 @@ Finished:
|
||||||
// If fAnotherCompletionExpected is false, this method must post the completion.
|
// If fAnotherCompletionExpected is false, this method must post the completion.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
if (m_RequestStatus == FORWARDER_DONE)
|
||||||
|
{
|
||||||
|
if (m_hRequest != NULL)
|
||||||
|
{
|
||||||
|
WinHttpSetStatusCallback(m_hRequest,
|
||||||
|
FORWARDING_HANDLER::OnWinHttpCompletion,
|
||||||
|
WINHTTP_CALLBACK_FLAG_HANDLES,
|
||||||
|
NULL);
|
||||||
|
if(WinHttpCloseHandle(m_hRequest))
|
||||||
|
{
|
||||||
|
m_hRequest = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_pWebSocket != NULL)
|
||||||
|
{
|
||||||
|
m_pWebSocket->TerminateRequest();
|
||||||
|
m_pWebSocket = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!fAnotherCompletionExpected )
|
if(fEndRequest)
|
||||||
|
{
|
||||||
|
// only postCompletion after WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
|
||||||
|
// so that no further WinHttp callback will be called
|
||||||
|
// in case of websocket, m_hRequest has already been closed after upgrade
|
||||||
|
// websocket will handle completion
|
||||||
|
m_fFinishRequest = TRUE;
|
||||||
|
m_pW3Context->PostCompletion(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!fAnotherCompletionExpected)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Since we use TLS to guard WinHttp operation, call PostCompletion instead of
|
// Since we use TLS to guard WinHttp operation, call PostCompletion instead of
|
||||||
// IndicateCompletion to allow cleaning up the TLS before thread reuse.
|
// IndicateCompletion to allow cleaning up the TLS before thread reuse.
|
||||||
//
|
//
|
||||||
|
|
||||||
m_pW3Context->PostCompletion(0);
|
m_pW3Context->PostCompletion(0);
|
||||||
|
|
||||||
//
|
//
|
||||||
// No code executed after posting the completion.
|
// No code executed after posting the completion.
|
||||||
//
|
//
|
||||||
|
|
@ -2292,7 +2407,7 @@ Finished:
|
||||||
HRESULT
|
HRESULT
|
||||||
FORWARDING_HANDLER::OnWinHttpCompletionSendRequestOrWriteComplete(
|
FORWARDING_HANDLER::OnWinHttpCompletionSendRequestOrWriteComplete(
|
||||||
HINTERNET hRequest,
|
HINTERNET hRequest,
|
||||||
DWORD ,
|
DWORD,
|
||||||
__out bool * pfClientError,
|
__out bool * pfClientError,
|
||||||
__out bool * pfAnotherCompletionExpected
|
__out bool * pfAnotherCompletionExpected
|
||||||
)
|
)
|
||||||
|
|
@ -2414,8 +2529,8 @@ FORWARDING_HANDLER::OnWinHttpCompletionStatusHeadersAvailable(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
STACK_BUFFER( bufHeaderBuffer, 2048);
|
STACK_BUFFER(bufHeaderBuffer, 2048);
|
||||||
STACK_STRA( strHeaders, 2048);
|
STACK_STRA(strHeaders, 2048);
|
||||||
DWORD dwHeaderSize = bufHeaderBuffer.QuerySize();
|
DWORD dwHeaderSize = bufHeaderBuffer.QuerySize();
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(pfAnotherCompletionExpected);
|
UNREFERENCED_PARAMETER(pfAnotherCompletionExpected);
|
||||||
|
|
@ -2471,10 +2586,10 @@ FORWARDING_HANDLER::OnWinHttpCompletionStatusHeadersAvailable(
|
||||||
// HTTP/1.1 302 Moved Permanently\r\n....\r\nLocation:http://site\0
|
// HTTP/1.1 302 Moved Permanently\r\n....\r\nLocation:http://site\0
|
||||||
//
|
//
|
||||||
|
|
||||||
if ( !strHeaders.IsEmpty() && strHeaders.QueryStr()[strHeaders.QueryCCH() - 1] != '\n' )
|
if (!strHeaders.IsEmpty() && strHeaders.QueryStr()[strHeaders.QueryCCH() - 1] != '\n')
|
||||||
{
|
{
|
||||||
hr = strHeaders.Append( "\r\n" );
|
hr = strHeaders.Append("\r\n");
|
||||||
if ( FAILED( hr ) )
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
@ -2596,7 +2711,7 @@ FORWARDING_HANDLER::OnWinHttpCompletionStatusReadComplete(
|
||||||
//
|
//
|
||||||
m_BytesToSend -= dwStatusInformationLength;
|
m_BytesToSend -= dwStatusInformationLength;
|
||||||
|
|
||||||
if (m_cMinBufferLimit >= BUFFER_SIZE/2)
|
if (m_cMinBufferLimit >= BUFFER_SIZE / 2)
|
||||||
{
|
{
|
||||||
if (m_cContentLength != 0)
|
if (m_cContentLength != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -2676,15 +2791,15 @@ FORWARDING_HANDLER::StaticInitialize(
|
||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Global initialization routine for FORWARDING_HANDLERs
|
Global initialization routine for FORWARDING_HANDLERs
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
fEnableReferenceCountTracing - True if ref count tracing should be use.
|
fEnableReferenceCountTracing - True if ref count tracing should be use.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
|
|
@ -2730,8 +2845,8 @@ Return Value:
|
||||||
//
|
//
|
||||||
if (WinHttpSetStatusCallback(sm_hSession,
|
if (WinHttpSetStatusCallback(sm_hSession,
|
||||||
FORWARDING_HANDLER::OnWinHttpCompletion,
|
FORWARDING_HANDLER::OnWinHttpCompletion,
|
||||||
( WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS |
|
(WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS |
|
||||||
WINHTTP_CALLBACK_STATUS_SENDING_REQUEST ),
|
WINHTTP_CALLBACK_STATUS_SENDING_REQUEST),
|
||||||
NULL) == WINHTTP_INVALID_STATUS_CALLBACK)
|
NULL) == WINHTTP_INVALID_STATUS_CALLBACK)
|
||||||
{
|
{
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
|
@ -2754,14 +2869,14 @@ Return Value:
|
||||||
|
|
||||||
// Initialize Application Manager
|
// Initialize Application Manager
|
||||||
APPLICATION_MANAGER *pApplicationManager = APPLICATION_MANAGER::GetInstance();
|
APPLICATION_MANAGER *pApplicationManager = APPLICATION_MANAGER::GetInstance();
|
||||||
if(pApplicationManager == NULL)
|
if (pApplicationManager == NULL)
|
||||||
{
|
{
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
goto Failure;
|
goto Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pApplicationManager->Initialize();
|
hr = pApplicationManager->Initialize();
|
||||||
if(FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
goto Failure;
|
goto Failure;
|
||||||
}
|
}
|
||||||
|
|
@ -2803,9 +2918,9 @@ Return Value:
|
||||||
goto Failure;
|
goto Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( fEnableReferenceCountTracing )
|
if (fEnableReferenceCountTracing)
|
||||||
{
|
{
|
||||||
sm_pTraceLog = CreateRefTraceLog( 10000, 0 );
|
sm_pTraceLog = CreateRefTraceLog(10000, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
@ -2826,15 +2941,15 @@ FORWARDING_HANDLER::StaticTerminate(
|
||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Global termination routine for FORWARDING_HANDLERs
|
Global termination routine for FORWARDING_HANDLERs
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
None
|
None
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
None
|
None
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
|
|
@ -2851,9 +2966,9 @@ Return Value:
|
||||||
|
|
||||||
DWORD tickCount = GetTickCount();
|
DWORD tickCount = GetTickCount();
|
||||||
|
|
||||||
while( g_dwActiveServerProcesses > 0 )
|
while (g_dwActiveServerProcesses > 0)
|
||||||
{
|
{
|
||||||
if( (GetTickCount() - tickCount) > 10000 )
|
if ((GetTickCount() - tickCount) > 10000)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2905,7 +3020,7 @@ CopyMultiSzToOutput(
|
||||||
PCWSTR pszListCopy = pszList;
|
PCWSTR pszListCopy = pszList;
|
||||||
while (*pszList != L'\0')
|
while (*pszList != L'\0')
|
||||||
{
|
{
|
||||||
cbData += (static_cast<DWORD>(wcslen(pszList)) + 1)*sizeof(WCHAR);
|
cbData += (static_cast<DWORD>(wcslen(pszList)) + 1) * sizeof(WCHAR);
|
||||||
pszList += wcslen(pszList) + 1;
|
pszList += wcslen(pszList) + 1;
|
||||||
}
|
}
|
||||||
cbData += sizeof(WCHAR);
|
cbData += sizeof(WCHAR);
|
||||||
|
|
@ -2943,13 +3058,27 @@ FORWARDING_HANDLER::TerminateRequest(
|
||||||
bool fClientInitiated
|
bool fClientInitiated
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
AcquireSRWLockExclusive(&m_RequestLock);
|
bool fAcquiredLock = FALSE;
|
||||||
|
|
||||||
|
if (TlsGetValue(g_dwTlsIndex) != this)
|
||||||
|
{
|
||||||
|
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == NULL);
|
||||||
|
AcquireSRWLockShared(&m_RequestLock);
|
||||||
|
TlsSetValue(g_dwTlsIndex, this);
|
||||||
|
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == this);
|
||||||
|
fAcquiredLock = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_hRequest != NULL)
|
if (m_hRequest != NULL)
|
||||||
{
|
{
|
||||||
WinHttpCloseHandle(m_hRequest);
|
WinHttpSetStatusCallback(m_hRequest,
|
||||||
|
FORWARDING_HANDLER::OnWinHttpCompletion,
|
||||||
|
WINHTTP_CALLBACK_FLAG_HANDLES,
|
||||||
|
NULL);
|
||||||
|
if (WinHttpCloseHandle(m_hRequest))
|
||||||
|
{
|
||||||
m_hRequest = NULL;
|
m_hRequest = NULL;
|
||||||
|
}
|
||||||
m_fHandleClosedDueToClient = fClientInitiated;
|
m_fHandleClosedDueToClient = fClientInitiated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2962,7 +3091,13 @@ FORWARDING_HANDLER::TerminateRequest(
|
||||||
m_pWebSocket->TerminateRequest();
|
m_pWebSocket->TerminateRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseSRWLockExclusive(&m_RequestLock);
|
if (fAcquiredLock)
|
||||||
|
{
|
||||||
|
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == this);
|
||||||
|
TlsSetValue(g_dwTlsIndex, NULL);
|
||||||
|
ReleaseSRWLockShared(&m_RequestLock);
|
||||||
|
DBG_ASSERT(TlsGetValue(g_dwTlsIndex) == NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BYTE *
|
BYTE *
|
||||||
|
|
@ -2970,10 +3105,10 @@ FORWARDING_HANDLER::GetNewResponseBuffer(
|
||||||
DWORD dwBufferSize
|
DWORD dwBufferSize
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DWORD dwNeededSize = (m_cEntityBuffers+1)*sizeof(BYTE *);
|
DWORD dwNeededSize = (m_cEntityBuffers + 1) * sizeof(BYTE *);
|
||||||
if (dwNeededSize > m_buffEntityBuffers.QuerySize() &&
|
if (dwNeededSize > m_buffEntityBuffers.QuerySize() &&
|
||||||
!m_buffEntityBuffers.Resize(
|
!m_buffEntityBuffers.Resize(
|
||||||
max(dwNeededSize, m_buffEntityBuffers.QuerySize()*2)))
|
max(dwNeededSize, m_buffEntityBuffers.QuerySize() * 2)))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -2996,7 +3131,7 @@ VOID
|
||||||
FORWARDING_HANDLER::FreeResponseBuffers()
|
FORWARDING_HANDLER::FreeResponseBuffers()
|
||||||
{
|
{
|
||||||
BYTE **pBuffers = m_buffEntityBuffers.QueryPtr();
|
BYTE **pBuffers = m_buffEntityBuffers.QueryPtr();
|
||||||
for (DWORD i=0; i<m_cEntityBuffers; i++)
|
for (DWORD i = 0; i<m_cEntityBuffers; i++)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(),
|
HeapFree(GetProcessHeap(),
|
||||||
0, // dwFlags
|
0, // dwFlags
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
@ -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;
|
||||||
|
DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO,
|
||||||
"WEBSOCKET_HANDLER::Cleanup Initiated with reason %d", reason);
|
"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:
|
||||||
|
if (fLocked)
|
||||||
|
{
|
||||||
LeaveCriticalSection(&_RequestLock);
|
LeaveCriticalSection(&_RequestLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue