477 lines
12 KiB
C++
477 lines
12 KiB
C++
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
|
|
#include "precomp.hxx"
|
|
#include "inprocessapplication.h"
|
|
#include "inprocesshandler.h"
|
|
#include "requesthandler_config.h"
|
|
//
|
|
// Initialization export
|
|
//
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
register_callbacks(
|
|
_In_ IN_PROCESS_APPLICATION* pInProcessApplication,
|
|
_In_ PFN_REQUEST_HANDLER request_handler,
|
|
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
|
|
_In_ PFN_MANAGED_CONTEXT_HANDLER async_completion_handler,
|
|
_In_ VOID* pvRequstHandlerContext,
|
|
_In_ VOID* pvShutdownHandlerContext
|
|
)
|
|
{
|
|
if (pInProcessApplication == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
pInProcessApplication->SetCallbackHandles(
|
|
request_handler,
|
|
shutdown_handler,
|
|
async_completion_handler,
|
|
pvRequstHandlerContext,
|
|
pvShutdownHandlerContext
|
|
);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HTTP_REQUEST*
|
|
http_get_raw_request(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler
|
|
)
|
|
{
|
|
return pInProcessHandler->QueryHttpContext()->GetRequest()->GetRawHttpRequest();
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HTTP_RESPONSE*
|
|
http_get_raw_response(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler
|
|
)
|
|
{
|
|
return pInProcessHandler->QueryHttpContext()->GetResponse()->GetRawHttpResponse();
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_get_server_variable(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ PCSTR pszVariableName,
|
|
_Out_ BSTR* pwszReturn
|
|
)
|
|
{
|
|
PCWSTR pszVariableValue;
|
|
DWORD cbLength;
|
|
|
|
DBG_ASSERT(pszVariableValue != NULL);
|
|
|
|
HRESULT hr = pInProcessHandler
|
|
->QueryHttpContext()
|
|
->GetServerVariable(pszVariableName, &pszVariableValue, &cbLength);
|
|
|
|
if (FAILED(hr) || cbLength == 0)
|
|
{
|
|
goto Finished;
|
|
}
|
|
|
|
*pwszReturn = SysAllocString(pszVariableValue);
|
|
|
|
if (*pwszReturn == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Finished;
|
|
}
|
|
Finished:
|
|
return hr;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_set_response_status_code(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ USHORT statusCode,
|
|
_In_ PCSTR pszReason
|
|
)
|
|
{
|
|
return pInProcessHandler->QueryHttpContext()->GetResponse()->SetStatus(statusCode, pszReason, 0, 0, nullptr,
|
|
true); // fTrySkipCustomErrors
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_post_completion(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
DWORD cbBytes
|
|
)
|
|
{
|
|
return pInProcessHandler->QueryHttpContext()->PostCompletion(cbBytes);
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_set_completion_status(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ REQUEST_NOTIFICATION_STATUS requestNotificationStatus
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
pInProcessHandler->IndicateManagedRequestComplete();
|
|
pInProcessHandler->SetAsyncCompletionStatus(requestNotificationStatus);
|
|
return hr;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_set_managed_context(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ PVOID pvManagedContext
|
|
)
|
|
{
|
|
// todo: should we consider changing the signature
|
|
HRESULT hr = S_OK;
|
|
pInProcessHandler->SetManagedHttpContext(pvManagedContext);
|
|
|
|
return hr;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
VOID
|
|
http_indicate_completion(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ REQUEST_NOTIFICATION_STATUS notificationStatus
|
|
)
|
|
{
|
|
pInProcessHandler->QueryHttpContext()->IndicateCompletion(notificationStatus);
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
VOID
|
|
http_get_completion_info(
|
|
_In_ IHttpCompletionInfo2* info,
|
|
_Out_ DWORD* cbBytes,
|
|
_Out_ HRESULT* hr
|
|
)
|
|
{
|
|
*cbBytes = info->GetCompletionBytes();
|
|
*hr = info->GetCompletionStatus();
|
|
}
|
|
|
|
//
|
|
// the signature should be changed. application's based address should be passed in
|
|
//
|
|
|
|
struct IISConfigurationData
|
|
{
|
|
IN_PROCESS_APPLICATION* pInProcessApplication;
|
|
BSTR pwzFullApplicationPath;
|
|
BSTR pwzVirtualApplicationPath;
|
|
BOOL fWindowsAuthEnabled;
|
|
BOOL fBasicAuthEnabled;
|
|
BOOL fAnonymousAuthEnable;
|
|
};
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_get_application_properties(
|
|
_In_ IISConfigurationData* pIISCofigurationData
|
|
)
|
|
{
|
|
auto pInProcessApplication = IN_PROCESS_APPLICATION::GetInstance();
|
|
if (pInProcessApplication == NULL)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
auto pConfiguration = pInProcessApplication->QueryConfig();
|
|
|
|
pIISCofigurationData->pInProcessApplication = pInProcessApplication;
|
|
pIISCofigurationData->pwzFullApplicationPath = SysAllocString(pConfiguration->QueryApplicationPhysicalPath()->QueryStr());
|
|
pIISCofigurationData->pwzVirtualApplicationPath = SysAllocString(pConfiguration->QueryApplicationVirtualPath()->QueryStr());
|
|
pIISCofigurationData->fWindowsAuthEnabled = pConfiguration->QueryWindowsAuthEnabled();
|
|
pIISCofigurationData->fBasicAuthEnabled = pConfiguration->QueryBasicAuthEnabled();
|
|
pIISCofigurationData->fAnonymousAuthEnable = pConfiguration->QueryAnonymousAuthEnabled();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_read_request_bytes(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_Out_ CHAR* pvBuffer,
|
|
_In_ DWORD dwCbBuffer,
|
|
_Out_ DWORD* pdwBytesReceived,
|
|
_Out_ BOOL* pfCompletionPending
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (pInProcessHandler == NULL)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
if (dwCbBuffer == 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
IHttpRequest *pHttpRequest = (IHttpRequest*)pInProcessHandler->QueryHttpContext()->GetRequest();
|
|
|
|
// Check if there is anything to read
|
|
if (pHttpRequest->GetRemainingEntityBytes() > 0)
|
|
{
|
|
BOOL fAsync = TRUE;
|
|
hr = pHttpRequest->ReadEntityBody(
|
|
pvBuffer,
|
|
dwCbBuffer,
|
|
fAsync,
|
|
pdwBytesReceived,
|
|
pfCompletionPending);
|
|
|
|
if (hr == HRESULT_FROM_WIN32(ERROR_HANDLE_EOF))
|
|
{
|
|
// We reached the end of the data
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*pdwBytesReceived = 0;
|
|
*pfCompletionPending = FALSE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_write_response_bytes(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ HTTP_DATA_CHUNK* pDataChunks,
|
|
_In_ DWORD dwChunks,
|
|
_In_ BOOL* pfCompletionExpected
|
|
)
|
|
{
|
|
IHttpResponse *pHttpResponse = (IHttpResponse*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
|
BOOL fAsync = TRUE;
|
|
BOOL fMoreData = TRUE;
|
|
DWORD dwBytesSent = 0;
|
|
|
|
HRESULT hr = pHttpResponse->WriteEntityChunks(
|
|
pDataChunks,
|
|
dwChunks,
|
|
fAsync,
|
|
fMoreData,
|
|
&dwBytesSent,
|
|
pfCompletionExpected);
|
|
|
|
return hr;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_flush_response_bytes(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_Out_ BOOL* pfCompletionExpected
|
|
)
|
|
{
|
|
IHttpResponse *pHttpResponse = (IHttpResponse*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
|
|
|
BOOL fAsync = TRUE;
|
|
BOOL fMoreData = TRUE;
|
|
DWORD dwBytesSent = 0;
|
|
|
|
HRESULT hr = pHttpResponse->Flush(
|
|
fAsync,
|
|
fMoreData,
|
|
&dwBytesSent,
|
|
pfCompletionExpected);
|
|
return hr;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_websockets_read_bytes(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ CHAR* pvBuffer,
|
|
_In_ DWORD cbBuffer,
|
|
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
|
|
_In_ VOID* pvCompletionContext,
|
|
_In_ DWORD* pDwBytesReceived,
|
|
_In_ BOOL* pfCompletionPending
|
|
)
|
|
{
|
|
IHttpRequest3 *pHttpRequest = (IHttpRequest3*)pInProcessHandler->QueryHttpContext()->GetRequest();
|
|
|
|
BOOL fAsync = TRUE;
|
|
|
|
HRESULT hr = pHttpRequest->ReadEntityBody(
|
|
pvBuffer,
|
|
cbBuffer,
|
|
fAsync,
|
|
pfnCompletionCallback,
|
|
pvCompletionContext,
|
|
pDwBytesReceived,
|
|
pfCompletionPending);
|
|
|
|
if (hr == HRESULT_FROM_WIN32(ERROR_HANDLE_EOF))
|
|
{
|
|
// We reached the end of the data
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_websockets_write_bytes(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ HTTP_DATA_CHUNK* pDataChunks,
|
|
_In_ DWORD dwChunks,
|
|
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
|
|
_In_ VOID* pvCompletionContext,
|
|
_In_ BOOL* pfCompletionExpected
|
|
)
|
|
{
|
|
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
|
|
|
BOOL fAsync = TRUE;
|
|
BOOL fMoreData = TRUE;
|
|
DWORD dwBytesSent;
|
|
|
|
HRESULT hr = pHttpResponse->WriteEntityChunks(
|
|
pDataChunks,
|
|
dwChunks,
|
|
fAsync,
|
|
fMoreData,
|
|
pfnCompletionCallback,
|
|
pvCompletionContext,
|
|
&dwBytesSent,
|
|
pfCompletionExpected);
|
|
|
|
return hr;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_websockets_flush_bytes(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ PFN_ASYNC_COMPLETION pfnCompletionCallback,
|
|
_In_ VOID* pvCompletionContext,
|
|
_In_ BOOL* pfCompletionExpected
|
|
)
|
|
{
|
|
IHttpResponse2 *pHttpResponse = (IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse();
|
|
|
|
BOOL fAsync = TRUE;
|
|
BOOL fMoreData = TRUE;
|
|
DWORD dwBytesSent;
|
|
|
|
HRESULT hr = pHttpResponse->Flush(
|
|
fAsync,
|
|
fMoreData,
|
|
pfnCompletionCallback,
|
|
pvCompletionContext,
|
|
&dwBytesSent,
|
|
pfCompletionExpected);
|
|
return hr;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_enable_websockets(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler
|
|
)
|
|
{
|
|
((IHttpContext3*)pInProcessHandler->QueryHttpContext())->EnableFullDuplex();
|
|
((IHttpResponse2*)pInProcessHandler->QueryHttpContext()->GetResponse())->DisableBuffering();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_cancel_io(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler
|
|
)
|
|
{
|
|
return pInProcessHandler->QueryHttpContext()->CancelIo();
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_response_set_unknown_header(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ PCSTR pszHeaderName,
|
|
_In_ PCSTR pszHeaderValue,
|
|
_In_ USHORT usHeaderValueLength,
|
|
_In_ BOOL fReplace
|
|
)
|
|
{
|
|
return pInProcessHandler->QueryHttpContext()->GetResponse()->SetHeader(pszHeaderName, pszHeaderValue, usHeaderValueLength, fReplace);
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_response_set_known_header(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_In_ HTTP_HEADER_ID dwHeaderId,
|
|
_In_ PCSTR pszHeaderValue,
|
|
_In_ USHORT usHeaderValueLength,
|
|
_In_ BOOL fReplace
|
|
)
|
|
{
|
|
return pInProcessHandler->QueryHttpContext()->GetResponse()->SetHeader(dwHeaderId, pszHeaderValue, usHeaderValueLength, fReplace);
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_get_authentication_information(
|
|
_In_ IN_PROCESS_HANDLER* pInProcessHandler,
|
|
_Out_ BSTR* pstrAuthType,
|
|
_Out_ VOID** pvToken
|
|
)
|
|
{
|
|
*pstrAuthType = SysAllocString(pInProcessHandler->QueryHttpContext()->GetUser()->GetAuthenticationType());
|
|
*pvToken = pInProcessHandler->QueryHttpContext()->GetUser()->GetPrimaryToken();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_stop_calls_into_managed(_In_ IN_PROCESS_APPLICATION* pInProcessApplication)
|
|
{
|
|
if (pInProcessApplication == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
pInProcessApplication->StopCallsIntoManaged();
|
|
return S_OK;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
HRESULT
|
|
http_stop_incoming_requests(_In_ IN_PROCESS_APPLICATION* pInProcessApplication)
|
|
{
|
|
if (pInProcessApplication == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
pInProcessApplication->StopIncomingRequests();
|
|
return S_OK;
|
|
}
|
|
|
|
EXTERN_C __MIDL_DECLSPEC_DLLEXPORT
|
|
VOID
|
|
set_main_handler(_In_ hostfxr_main_fn main)
|
|
{
|
|
IN_PROCESS_APPLICATION::SetMainCallback(main);
|
|
}
|
|
|
|
// End of export
|