⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filters.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

			pLog->dwHttpStatus = rgStatus[m_rs].dwStatusNumber;

			// don't pass NULL, give 'em empty string on certain cases
			if ( ! pLog->pszClientUserName)  
				pLog->pszClientUserName = cszEmpty;

			if ( ! pLog->pszParameters )
				pLog->pszParameters = cszEmpty;

			*ppStFilterOrg = MyAllocNZ(HTTP_FILTER_LOG);

cleanupFCLog:
			if (    !pLog->pszClientUserName  || !pLog->pszServerName  
			    ||  !pLog->pszOperation       || !pLog->pszTarget      
			    ||  !pLog->pszParameters      || !pLog->pszClientHostName  
			    ||   !(*ppStFilterOrg))
			{
				MyFree((*ppStFilterOrg));
				MyFree(pLog->pszClientHostName);

				if (pLog->pszServerName != cszEmpty) {
					MyFree(pLog->pszServerName);
				}

				MyFree(pLog);
				*ppStFilter = NULL;
				myleave(344);
			}

			memcpy(*ppStFilterOrg,*ppStFilter,sizeof(HTTP_FILTER_LOG));
		}
		break;

		default:
			DEBUGCHK(0);
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: FillFC received unknown notification type = %d\r\n",dwNotifyType));
			*ppStFilterOrg = *ppStFilter = NULL;
			myleave(246);
		break;
	}

	// the pfc is always the same regardless of dwNotifyType
	pfc->cbSize = sizeof(*pfc);
	pfc->Revision = HTTP_FILTER_REVISION;
	pfc->ServerContext = (PVOID) this;
	pfc->ulReserved = 0;
	pfc->fIsSecurePort = m_fIsSecurePort;
	//  pfc->pFilterContext is filled in calling loop in CallFilter()
	pfc->GetServerVariable = ::GetServerVariable;
	pfc->AddResponseHeaders = ::AddResponseHeaders;
	pfc->WriteClient = ::WriteClient;
	pfc->AllocMem = ::AllocMem;
	pfc->ServerSupportFunction = ::ServerSupportFunction;

	ret = TRUE;
done:
	DEBUGMSG_ERR(ZONE_ERROR,(L"HTTPD: FillFC failed on mem alloc, GLE = %d, err= %d\r\n",GetLastError(),err));
	
	return ret;
}


// Final fcn called in CallFilter, this frees any unneeded allocated memory
// and sets the last three values, if valid, to whatever the filter changed them to.
BOOL CHttpRequest::CleanupFC(DWORD dwNotifyType, LPVOID* ppStFilter, LPVOID* ppStFilterOrg,
							PSTR *ppszBuf1, int *pcbBuf, PSTR *ppszBuf2)

{
	BOOL fRet = TRUE;

	switch (dwNotifyType)
	{
		case SF_NOTIFY_END_OF_NET_SESSION:
		case SF_NOTIFY_END_OF_REQUEST:
		case SF_NOTIFY_PREPROC_HEADERS:
		case SF_NOTIFY_SEND_RESPONSE:
			break;

		case SF_NOTIFY_READ_RAW_DATA:
		{
			PHTTP_FILTER_RAW_DATA pRawData = (PHTTP_FILTER_RAW_DATA) *ppStFilter;			

			if (! ppszBuf1) { // Use buffer in CHttpResponse class
				m_bufRequest.FilterDataUpdate(pRawData->pvInData,pRawData->cbInData,pRawData->pvInData != m_bufRequest.FilterRawData());
			}
			else {
				*ppszBuf1 = (PSTR) pRawData->pvInData;
				*pcbBuf =   pRawData->cbInData;
			}
		}
		break;

		case SF_NOTIFY_AUTHENTICATION: 
		{
			PHTTP_FILTER_AUTHENT pAuth = (PHTTP_FILTER_AUTHENT) *ppStFilter;

			*ppszBuf1 = pAuth->pszUser;
			*ppszBuf2 = pAuth->pszPassword;
		}
		break;
		
		case SF_NOTIFY_SEND_RAW_DATA:
		{
			PHTTP_FILTER_RAW_DATA pRawData = (PHTTP_FILTER_RAW_DATA) *ppStFilter;
			*ppszBuf1 = (PSTR) pRawData->pvInData;
			*pcbBuf  = pRawData->cbInData;
		}
		break;

		case SF_NOTIFY_URL_MAP:
		{
			PHTTP_FILTER_URL_MAP pUrlMap = (PHTTP_FILTER_URL_MAP) *ppStFilter ;
			PHTTP_FILTER_URL_MAP pUrlMapOrg = (PHTTP_FILTER_URL_MAP) *ppStFilterOrg;

			// Case when parsing http headers from a request.
			if (NULL == ppszBuf1) {
				// since data can be modified in place, always re-copy						
				MyFree(m_wszPath);
				m_wszPath = MySzDupAtoW(pUrlMap->pszPhysicalPath);

				MyFree(pUrlMapOrg->pszPhysicalPath);
				if (!m_wszPath)
					fRet = FALSE;

				// note: don't set m_ccWPath here because it will be set in ParseHeaders() anyway.
			}
			else { // ServerSupportFunction with HSE_MAP_URL call
				*ppszBuf1 = (PSTR) pUrlMap->pszURL;
				*ppszBuf2 = pUrlMap->pszPhysicalPath;
				*pcbBuf = pUrlMap->cbPathBuff;
			}
		}
		break;

		case SF_NOTIFY_ACCESS_DENIED:
		{
			PHTTP_FILTER_ACCESS_DENIED pDeniedOrg = (PHTTP_FILTER_ACCESS_DENIED) *ppStFilterOrg;
			// If they change pDenied->pszURL we ignore it.  Since the session
			// is coming to an end because of access problems, the only thing changing 
			// pszURL could affect would be logging (which should be set through logging filter)		
			MyFree(pDeniedOrg->pszPhysicalPath);
		}
		break;

		// We use m_pFInfo->m_pFLog to store changes to the log.  When
		// we write out the log, we use the web server value by default
		// unless a particular value is non-NULL; by default all values
		// are NULL in m_pFInfo->m_pFLog unless overwritten by this code.
		case SF_NOTIFY_LOG:
		{
			PHTTP_FILTER_LOG pLog = (PHTTP_FILTER_LOG) *ppStFilter;
			PHTTP_FILTER_LOG pLogOrg = (PHTTP_FILTER_LOG ) *ppStFilterOrg;
			PHTTP_FILTER_LOG pFLog;

			// Free dynamically allocated data.
			MyFreeNZ(pLogOrg->pszClientHostName);

			if (pLogOrg->pszServerName != cszEmpty)
				MyFreeNZ(pLogOrg->pszServerName);

			// If no changes were made, break out early.
			if ( ! memcmp(pLog, pLogOrg, sizeof(HTTP_FILTER_LOG))) {
				break;  				
			}

			if (NULL == (pFLog = m_pFInfo->m_pFLog = MyAllocZ(HTTP_FILTER_LOG))) {
				// Memory errors just mean we won't bother doing logging, non-fatal.
				break;  
			}
			
			if (pLog->pszClientHostName != pLogOrg->pszClientHostName)
				pFLog->pszClientHostName = pLog->pszClientHostName;

 			if (pLog->pszServerName  != pLogOrg->pszServerName)
				pFLog->pszServerName = pLog->pszServerName;

			if (pLog->pszClientUserName  != pLogOrg->pszClientUserName)
				pFLog->pszClientUserName = pLog->pszClientUserName;

			if (pLog->pszOperation  != pLogOrg->pszOperation)
				pFLog->pszOperation = pLog->pszOperation;

			if (pLog->pszTarget  != pLogOrg->pszTarget)
				pFLog->pszTarget = pLog->pszTarget;

			if (pLog->pszParameters  != pLogOrg->pszParameters)
				pFLog->pszParameters = pLog->pszParameters ;

			pFLog->dwHttpStatus 	   = pLog->dwHttpStatus;
			pFLog->dwWin32Status       = pLog->dwWin32Status;
			pFLog->dwBytesSent         = pLog->dwBytesSent;
			pFLog->dwBytesRecvd        = pLog->dwBytesRecvd ;
			pFLog->msTimeForProcessing = pLog->msTimeForProcessing;		
		}
		
		break;

		default:
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: CleanupFCs received unknown code = %d\r\n",dwNotifyType));
		break;

	}

	MyFree(*ppStFilterOrg);
	MyFree(*ppStFilter);
	return fRet;
}

//  Initializes buffers for CallFilter with SF_NOTIFY_AUTHENTICATION, and tries
//  to authenticate if the filter changes any data.

//  Note:  Even in the case where security isn't a component or is disabled in 
//         registry, we make this call because filter may theoretically decide to end
//		   the session based on the user information it receives.

BOOL CHttpRequest::AuthenticateFilter() {
	DEBUG_CODE_INIT;
	BOOL ret = FALSE;

	// IIS docs promise the filter minimum sized buffers to write password
	// and user name into, we provide them
	char szUserName[SF_MAX_USERNAME];
	char szPassword[SF_MAX_PASSWORD];  

	PSTR pszNewUserName = szUserName;
	PSTR pszNewPassword = szPassword;

	// We only make notification if we're using Anonymous or BASIC auth,
	// otherwise we don't know how to decode the text/password.  Like IIS.
	if ( m_pszAuthType && 0 != _stricmp(m_pszAuthType,cszBasic))
		return TRUE;

	// write existing value, if any, into the new buffers

	//  In this case we've cracked the user name and password into ANSI already.
	if (m_pszRemoteUser) {
		// These are safe strcpy's because HandleBasicAuth cracked
		// out the strings and made sure their combined len was < MAX_PATH.
		DEBUGCHK(strlen(m_pszRemoteUser) < sizeof(szUserName));
		DEBUGCHK(strlen(m_pszPassword)   < sizeof(szPassword));
		
		StringCbCopyA(szUserName,sizeof(szUserName),m_pszRemoteUser);
		StringCbCopyA(szPassword,sizeof(szPassword),m_pszPassword);
	}
	//  We have user user name data but it hasn't been Base64 Decoded yet
	else if (m_pszRawRemoteUser) {
		DWORD dwLen = sizeof(szUserName);

		if (strlen(m_pszRawRemoteUser) >= MAXUSERPASS) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Base64 data > 256 bytes on Basic Auth, failing request\r\n"));
			m_rs = STATUS_FORBIDDEN;
			return FALSE;
		}
	
		if (! svsutil_Base64Decode(m_pszRawRemoteUser,(void*)szUserName,sizeof(szUserName),NULL,TRUE)) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Base64 data is invalid, failing request\r\n"));
			m_rs = STATUS_BADREQ;
			return FALSE;
		}

		PSTR pszDivider =  strchr(szUserName, ':');
		if(NULL == pszDivider)
			myleave(290);
		*pszDivider++ = 0;		// seperate user & pass
	
		//  We need copies of this data for later in the fcn
		m_pszRemoteUser = MySzDupA(szUserName, strlen(szUserName));
		if (NULL == m_pszRemoteUser)
			myleave(291);
				
		m_pszPassword = MySzDupA(pszDivider);
		if (NULL == m_pszPassword)
			myleave(292);
		
		strcpy(szPassword, m_pszPassword);
		strcpy(szUserName, m_pszRemoteUser);
	}
	// Otherwise the browser didn't set any user information.
	else {
		szUserName[0] = '\0';
		szPassword[0] = '\0';
	}

	if ( ! CallFilter(SF_NOTIFY_AUTHENTICATION,&pszNewUserName, NULL, &pszNewPassword))
		myleave(293);


	//  If the filter arbitrarily denied access, then we exit. 
	//  Check if the filter has changed the user name ptr or modified it in place.
	
	if ( pszNewUserName != szUserName ||							// changed ptr
		 (m_pszRemoteUser == NULL  && szUserName[0] != '\0') ||		// modified in place
		 (m_pszRemoteUser && strcmp(szUserName, m_pszRemoteUser) )  // modified in place
	   )						
	{
		// Update m_pszRemoteUser with what was set in filter because GetServerVariable
		// may need it.
		ResetString(m_pszRemoteUser, pszNewUserName);
		if (! m_pszRemoteUser)
			myleave(294);
	}

	if ( pszNewPassword != szPassword ||
   	     (m_pszPassword == NULL  && szPassword[0] != '\0') ||
		 (m_pszPassword && strcmp(szPassword, m_pszPassword))
		 )
	{
		// GetServerVariables with AUTH_PASSWORD might request this.
		ResetString(m_pszPassword, pszNewPassword);
		if (! m_pszPassword)
			myleave(295);
	}


	ret = TRUE;
done:
	DEBUGMSG_ERR(ZONE_ERROR,(L"HTTPD: Authentication for filters failed, err = %d, GLE = %d\r\n",err,GetLastError()));
	return ret;
}


//  Called on updating data from an ISAPI filter, resets internal structures.  
//  fModifiedPtr is TRUE when 

BOOL CBuffer::FilterDataUpdate(PVOID pvData, DWORD cbData, BOOL fModifiedPtr) {
	// a filter can do anything to 2nd HTTP request waiting in buffer, so
	// just mark it as invalid to play it safe.
	InvalidateNextRequestIfAlreadyRead();

	if (fModifiedPtr) {
		if ((int) (cbData - UnaccessedCount()) > 0) {
			if (! AllocMem(cbData - UnaccessedCount() + 1))
				return FALSE;

			memcpy(m_pszBuf + m_iNextInFollow, pvData, cbData);
		}
	}
	// It's possible we modified data in place, so we always update the size
	// information that the filter passed us in case it changed the # of bytes
	// in the request.

	m_iNextIn = (int)cbData + m_iNextInFollow;
	m_iNextInFollow = m_iNextIn;
	
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -