|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name : logging.cxx
Abstract: Handle Logging
Author: Anil Ruia (AnilR) 1-Jul-2000
Environment: Win32 - User Mode
Project: w3core.dll --*/
#include "precomp.hxx"
CONTEXT_STATUS W3_STATE_LOG::DoWork( W3_MAIN_CONTEXT *pMainContext, DWORD, DWORD) /*++
Routine Description:
Log the request (and call the END_OF_REQUEST notification)
Arguments:
pMainContext - W3_MAIN_CONTEXT representing an execution of the state machine
Return Value:
CONTEXT_STATUS_CONTINUE - if we should continue in state machine else stop executing the machine and free up the current thread
--*/ { BOOL fUnused = FALSE;
if (pMainContext->QueryNeedFinalDone()) { //
// Clear remaining chunks from handle/response state
//
pMainContext->QueryResponse()->Clear();
//
// End of request notifications happen BEFORE logging.
//
if ( pMainContext->IsNotificationNeeded( SF_NOTIFY_END_OF_REQUEST ) ) { pMainContext->NotifyFilters( SF_NOTIFY_END_OF_REQUEST, NULL, &fUnused ); } //
// Clear any crud from the last write from END_OF_REQUEST filter
//
pMainContext->QueryResponse()->Clear();
//
// Do the final send
//
pMainContext->SendEntity(W3_FLAG_PAST_END_OF_REQ); }
if (pMainContext->QueryDoCustomLogging()) { if (FAILED(pMainContext->CollectLoggingData(FALSE))) { goto Exit; }
pMainContext->QuerySite()->LogInformation(pMainContext->QueryLogContext()); }
Exit: return CONTEXT_STATUS_CONTINUE; }
CONTEXT_STATUS W3_STATE_LOG::OnCompletion( W3_MAIN_CONTEXT *, DWORD, DWORD) /*++
Routine Description:
Completion for the W3_STATE_LOG state
Arguments:
pMainContext - W3_MAIN_CONTEXT representing an execution of the state machine
Return Value:
CONTEXT_STATUS_CONTINUE - if we should continue in state machine else stop executing the machine and free up the current thread
--*/ { //
// This code should never get hit
//
DBG_ASSERT(FALSE);
return CONTEXT_STATUS_CONTINUE; }
HRESULT W3_MAIN_CONTEXT::CollectLoggingData(BOOL fCollectForULLogging) /*++
Routine Description:
Routine which collects all the logging data
Arguments:
fCollectForULLogging - whether the data is being collected for http.sys/custom logging
Return Value:
HRESULT
--*/ { STACK_STRA(strVal, 64); STACK_STRU(strValW, 64); HRESULT hr = S_OK; DWORD dwLength; CHUNK_BUFFER * pHeaderBuffer;
HTTP_LOG_FIELDS_DATA *pUlLogData = QueryUlLogData(); W3_REQUEST *pRequest = QueryRequest(); W3_RESPONSE *pResponse = QueryResponse();
pHeaderBuffer = QueryHeaderBuffer(); DBG_ASSERT( pHeaderBuffer != NULL );
if (IsNotificationNeeded(SF_NOTIFY_LOG)) { //
// There is a SF_NOTIFY_LOG filter, collect the data for the
// notification
//
HTTP_FILTER_LOG filtLog; ZeroMemory(&filtLog, sizeof filtLog);
if (SUCCEEDED(hr = GetServerVariableRemoteHost(this, &strVal))) { dwLength = strVal.QueryCCH() + 1; if (FAILED(hr = pHeaderBuffer->AllocateSpace( dwLength, (PCHAR *)&filtLog.pszClientHostName))) { goto Exit; } strVal.CopyToBuffer((LPSTR)filtLog.pszClientHostName, &dwLength); } else { goto Exit; }
if (SUCCEEDED(hr = GetServerVariableLogonUser(this, &strVal))) { dwLength = strVal.QueryCCH() + 1; if (FAILED(hr = pHeaderBuffer->AllocateSpace( dwLength, (PCHAR *)&filtLog.pszClientUserName))) { goto Exit; } strVal.CopyToBuffer((LPSTR)filtLog.pszClientUserName, &dwLength); } else { goto Exit; }
if (SUCCEEDED(hr = GetServerVariableLocalAddr(this, &strVal))) { dwLength = strVal.QueryCCH() + 1; if (FAILED(hr = pHeaderBuffer->AllocateSpace( dwLength, (PCHAR *)&filtLog.pszServerName))) { goto Exit; } strVal.CopyToBuffer((LPSTR)filtLog.pszServerName, &dwLength); } else { goto Exit; }
pRequest->QueryVerb((CHAR **)&filtLog.pszOperation, (USHORT *)&dwLength);
if (FAILED(hr = pRequest->GetUrl(&strValW)) || FAILED(hr = strVal.CopyWToUTF8(strValW)) || FAILED(hr = pHeaderBuffer->AllocateSpace( strVal.QueryStr(), strVal.QueryCCH(), (CHAR **)&filtLog.pszTarget))) { goto Exit; }
//
// If an ISAPI used HSE_APPEND_LOG_PARAMETER use it
//
if (_LogContext.m_strLogParam.IsEmpty()) { if (FAILED(hr = pRequest->GetQueryStringA(&_LogContext.m_strLogParam))) { goto Exit; } } filtLog.pszParameters = _LogContext.m_strLogParam.QueryStr();
filtLog.dwHttpStatus = pResponse->QueryStatusCode(); if ( HRESULT_FACILITY( QueryErrorStatus() ) == FACILITY_WIN32 ) { filtLog.dwWin32Status = WIN32_FROM_HRESULT( QueryErrorStatus() ); } else { filtLog.dwWin32Status = QueryErrorStatus(); }
filtLog.dwBytesSent = _LogContext.m_dwBytesSent; filtLog.dwBytesRecvd = _LogContext.m_dwBytesRecvd; filtLog.msTimeForProcessing = GetTickCount() - _LogContext.m_msStartTickCount;
NotifyFilters(SF_NOTIFY_LOG, &filtLog, NULL);
//
// The filter may have changed some the data, copy it back to our
// logging structure
//
pUlLogData->ClientIp = (CHAR *)filtLog.pszClientHostName; pUlLogData->ClientIpLength = (USHORT) strlen(filtLog.pszClientHostName);
if (FAILED(hr = strValW.CopyA(filtLog.pszClientUserName)) || FAILED(hr = pHeaderBuffer->AllocateSpace( strValW.QueryStr(), strValW.QueryCCH(), (PWSTR*) &pUlLogData->UserName))) { goto Exit; } pUlLogData->UserNameLength = (USHORT)(strValW.QueryCCH() * sizeof(WCHAR));
pUlLogData->ServerIp = (CHAR *)filtLog.pszServerName; pUlLogData->ServerIpLength = (USHORT) strlen(filtLog.pszServerName);
pUlLogData->Method = (CHAR *)filtLog.pszOperation; pUlLogData->MethodLength = (USHORT) strlen(filtLog.pszOperation); pUlLogData->MethodNum = (HTTP_VERB)METHOD_HASH::GetIndex((CHAR *)filtLog.pszOperation);
if (FAILED(hr = strValW.CopyA(filtLog.pszTarget)) || FAILED(hr = pHeaderBuffer->AllocateSpace( strValW.QueryStr(), strValW.QueryCCH(), (PWSTR*) &pUlLogData->UriStem))) { goto Exit; } pUlLogData->UriStemLength = (USHORT)(strValW.QueryCCH() * sizeof(WCHAR));
pUlLogData->UriQuery = (CHAR *)filtLog.pszParameters; pUlLogData->UriQueryLength = (USHORT) strlen(filtLog.pszParameters);
pUlLogData->ProtocolStatus = (USHORT) filtLog.dwHttpStatus; pUlLogData->Win32Status = filtLog.dwWin32Status; _LogContext.m_dwBytesSent = filtLog.dwBytesSent; _LogContext.m_dwBytesRecvd = filtLog.dwBytesRecvd; _LogContext.m_msProcessingTime = filtLog.msTimeForProcessing; } else { //
// No filter, just get the logging data
//
if (SUCCEEDED(hr = GetServerVariableRemoteHost(this, &strVal))) { if (FAILED(hr = pHeaderBuffer->AllocateSpace( strVal.QueryStr(), strVal.QueryCCH(), (PSTR*) &pUlLogData->ClientIp))) { goto Exit; } pUlLogData->ClientIpLength = (USHORT)strVal.QueryCCH(); } else { goto Exit; }
if ( QueryUserContext() == NULL ) { if (FAILED(hr = pRequest->GetRequestUserName(&strVal))) { goto Exit; }
if (strVal.IsEmpty()) { pUlLogData->UserName = L""; pUlLogData->UserNameLength = 0; } else { if (FAILED(hr = strValW.CopyA(strVal.QueryStr())) || FAILED(hr = pHeaderBuffer->AllocateSpace( strValW.QueryStr(), strValW.QueryCCH(), (PWSTR*) &pUlLogData->UserName))) { goto Exit; } pUlLogData->UserNameLength = (USHORT)strValW.QueryCB(); } } else { pUlLogData->UserName = QueryUserContext()->QueryUserName(); if (pUlLogData->UserName) { pUlLogData->UserNameLength = (USHORT)wcslen(pUlLogData->UserName) * sizeof(WCHAR); } }
if (SUCCEEDED(hr = GetServerVariableLocalAddr(this, &strVal))) { if (FAILED(hr = pHeaderBuffer->AllocateSpace( strVal.QueryStr(), strVal.QueryCCH(), (PSTR*) &pUlLogData->ServerIp))) { goto Exit; } pUlLogData->ServerIpLength = (USHORT)strVal.QueryCCH(); } else { goto Exit; }
pRequest->QueryVerb((CHAR**) &pUlLogData->Method, &pUlLogData->MethodLength); pUlLogData->MethodNum = pRequest->QueryVerbType();
pRequest->QueryUrl((WCHAR**) &pUlLogData->UriStem, &pUlLogData->UriStemLength);
//
// If an ISAPI used HSE_APPEND_LOG_PARAMETER use it
//
if (_LogContext.m_strLogParam.IsEmpty()) { if (FAILED(hr = pRequest->GetQueryStringA(&_LogContext.m_strLogParam))) { goto Exit; } } pUlLogData->UriQuery = _LogContext.m_strLogParam.QueryStr(); pUlLogData->UriQueryLength = (USHORT)_LogContext.m_strLogParam.QueryCCH();
pUlLogData->ProtocolStatus = pResponse->QueryStatusCode(); if ( HRESULT_FACILITY( QueryErrorStatus() ) == FACILITY_WIN32 ) { pUlLogData->Win32Status = WIN32_FROM_HRESULT( QueryErrorStatus() ); } else { pUlLogData->Win32Status = QueryErrorStatus(); }
if (!fCollectForULLogging) { _LogContext.m_msProcessingTime = GetTickCount() - _LogContext.m_msStartTickCount; } }
//
// Now get data unaffected by any SF_NOTIFY_LOG filter
//
HTTP_SUB_ERROR subError; pResponse->QuerySubError(&subError); pUlLogData->SubStatus = subError.mdSubError;
pUlLogData->ServerPort = ntohs( pRequest->QueryLocalPort() );
pUlLogData->ServiceName = QuerySite()->QueryName()->QueryStr(); pUlLogData->ServiceNameLength = (USHORT)QuerySite()->QueryName()->QueryCCH();
pUlLogData->ServerName = g_pW3Server->QueryComputerName(); pUlLogData->ServerNameLength = g_pW3Server->QueryComputerNameLength();
if (fCollectForULLogging) { pUlLogData->Host = pRequest->GetHeader(HttpHeaderHost, &pUlLogData->HostLength);
pUlLogData->UserAgent = pRequest->GetHeader(HttpHeaderUserAgent, &pUlLogData->UserAgentLength); pUlLogData->Cookie = pRequest->GetHeader(HttpHeaderCookie, &pUlLogData->CookieLength);
pUlLogData->Referrer = pRequest->GetHeader(HttpHeaderReferer, &pUlLogData->ReferrerLength); } else { if (FAILED(hr = GetServerVariableHttpVersion(this, &_LogContext.m_strVersion))) { goto Exit; }
if (QuerySite()->IsRequiredExtraLoggingFields()) { //
// If the custom logging module needs extra logging fields, get them
//
const MULTISZA *pmszExtraLoggingFields = QuerySite()->QueryExtraLoggingFields(); LPSTR pszHeaderName = (LPSTR)pmszExtraLoggingFields->First(); STACK_STRA( strHeaderName, 128);
while (pszHeaderName != NULL) { hr = strHeaderName.Copy( pszHeaderName, (DWORD)strlen(pszHeaderName) - 1 ); if (FAILED(hr)) { goto Exit; }
hr = pRequest->GetHeader( strHeaderName, &strVal ); if (FAILED(hr)) { if (hr == HRESULT_FROM_WIN32(ERROR_INVALID_INDEX)) { strVal.Reset(); hr = S_OK; } else { goto Exit; } }
if (!_LogContext.m_mszHTTPHeaders.Append(strVal.QueryStr())) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; }
pszHeaderName = (LPSTR)pmszExtraLoggingFields->Next(pszHeaderName); } } }
Exit: return hr; }
|