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

📄 filters.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				DEBUGMSG(ZONE_ERROR, (L"HTTPD: ISAPI Filter DLL <<%s>> caused exception 0x%08x\r\n", 
									        g_pFilterCon->m_pFilters[i].wszDLLName, GetExceptionCode()));

				g_pVars->m_pLog->WriteEvent(IDS_HTTPD_FILT_EXCEPTION,g_pFilterCon->m_pFilters[i].wszDLLName,GetExceptionCode(),L"HttpFilterProc",GetLastError());
				m_fKeepAlive = FALSE; 
				myleave(216);
			}

			// bail out if another filter call said to, but not on certain events (for compat with IIS)
			// This would happen if a filter triggered an event to occur which caused another filter call
			// to be made, and if that nested filter returned an error code indicating the end of session.
			if ( (! m_pFInfo->m_fFAccept) &&
			  ! (dwNotifyType & (SF_NOTIFY_END_OF_REQUEST | SF_NOTIFY_LOG | SF_NOTIFY_END_OF_NET_SESSION | SF_NOTIFY_SEND_RESPONSE | SF_NOTIFY_SEND_RAW_DATA)))
			{
				DEBUGMSG(ZONE_ISAPI,(L"HTTPD: Filter indirectly set us to end, ending CallFilter for event= %x,i=%d\r\n",dwNotifyType,i));
				myretleave(FALSE,0);
			}
			
			m_pFInfo->m_ppvContext[i] = fc.pFilterContext;

			DEBUGMSG(ZONE_ISAPI, (L"HTTPD: Filter returned response code of 0x%08x\r\n",dwFilterCode));
			switch (dwFilterCode) {
				// alert calling class that this request + net session is over
				case SF_STATUS_REQ_FINISHED:
					m_fKeepAlive = FALSE;
					m_pFInfo->m_fSentHeaders = TRUE;  // don't send back headers in these cases.
					myretleave(FALSE,0);   
				break;

				// alert calling class that this request but not the net session is over
				case SF_STATUS_REQ_FINISHED_KEEP_CONN:
					m_fKeepAlive = TRUE;
					m_pFInfo->m_fSentHeaders = TRUE;  // don't send back headers in these cases.
					myretleave(FALSE,0);   
				break;

				// goes to top of loop, handle next filter in line
				case SF_STATUS_REQ_NEXT_NOTIFICATION:
					NEXTFILTER(dwNotifyType, i);
				break;

				// not an error, just done handling current httpd event
				case SF_STATUS_REQ_HANDLED_NOTIFICATION:
					myretleave(TRUE,0);   		
				break;

				// alert calling class that this request is over
				case SF_STATUS_REQ_ERROR:
					m_fKeepAlive = FALSE;  
					m_rs = STATUS_INTERNALERR;
					myretleave(FALSE,214);
				break;

				case SF_STATUS_REQ_READ_NEXT:
					// only valid for read raw data events.  IIS ignores if returned by other filters
					// Continue running through remaining filters before reading more data
					if (dwNotifyType == SF_NOTIFY_READ_RAW_DATA) {
						fReqReadNext = TRUE;					
					}
					NEXTFILTER(dwNotifyType, i);
				break;
				
				default:	// treat like SF_STATUS_REQ_NEXT_NOTIFICATION
					DEBUGMSG(ZONE_ERROR, (L"HTTPD: Filter returned unknown/unhandled return code\r\n"));
					NEXTFILTER(dwNotifyType, i);
				break;
			}
		}

		// Only after all filters have been serviced to we handle READ_NEXT event
		// Note that having a filter call SF_READ_REQ_NEXT during a call to an 
		// ISAPI ext ReadClient is completly unsupported.  This has been docced.
		if (fReqReadNext) {
			PHTTP_FILTER_RAW_DATA pRaw = (PHTTP_FILTER_RAW_DATA) pStFilter;
			fFillStructs = TRUE; // set here in case we don't read any data and 
			                     // exit loop, so we don't call CleanupFC 2 times.

			DEBUGCHK(dwNotifyType == SF_NOTIFY_READ_RAW_DATA);

			CleanupFC(dwNotifyType, &pStFilter,&pStFilterOrg,ppszBuf1, pcbBuf, ppszBuf2);
			m_bufRequest.RecvBody(m_socket,m_pFInfo->m_dwNextReadSize ? m_pFInfo->m_dwNextReadSize : g_pVars->m_dwPostReadSize,TRUE, FALSE, this, FALSE);

			// only stop reading if we didn't get any data.  Timeouts are OK, we'll call read filter again
			if (m_bufRequest.UnaccessedCount() == 0)
				fReqReadNext = FALSE;  
			else
				m_pFInfo->m_dwBytesReceived += pRaw->cbInData; // from HTTP recv
		}
	} while (fReqReadNext);

	ret = TRUE;
done:
	DEBUGMSG_ERR(ZONE_ERROR, (L"HTTPD: CIsapiFilterCon::CallFilter FAILED: GLE=%d err=%d\r\n", 
			GetLastError(), err));


	// Udpate our bytes sent/received if need be.  
	// Send bytes update must after we do our cleanup, Read bytes must happen before.
	if (dwNotifyType == SF_NOTIFY_READ_RAW_DATA) {
		// We only allocate pRaw if we need to (ie someone notified for read),
		// if this is so use that value for rx bytes.  If no one notefied for read filt, use
		// the value we were passed for bytes read by calling fcn.
	
		PHTTP_FILTER_RAW_DATA pRaw = (PHTTP_FILTER_RAW_DATA) pStFilter;
		if (pRaw)
			m_pFInfo->m_dwBytesReceived += pRaw->cbInData;
		else if (ppszBuf1)
			m_pFInfo->m_dwBytesReceived += *pcbBuf;  // from ISAPI ReadClient
		else
			m_pFInfo->m_dwBytesReceived += m_bufRequest.UnaccessedCount(); // from HTTP recv
	}			

	//  fFillStructs will be false if no filter registered for this event, which means
	//  we have no cleanup
	if (FALSE == fFillStructs)
		ret = CleanupFC(dwNotifyType, &pStFilter,&pStFilterOrg,ppszBuf1, pcbBuf, ppszBuf2);	

	if (dwNotifyType == SF_NOTIFY_SEND_RAW_DATA)
		m_pFInfo->m_dwBytesSent += *pcbBuf;

	if (!ret) {
		m_pFInfo->m_fFAccept = FALSE;
	}
	return ret;	
}

// sets up the FilterContext data structure so it makes sense to filterr being called.
// Only called once per filter event.

// ppStFilter is sent to filter dlls.
// ppStFilterOrg is a copy, it stores what we've allocated and is used to free up mem, as
// the filter would cause server mem leaks without it as a reference

// Last three parameters are the same as CallFilter

BOOL CHttpRequest::FillFC(PHTTP_FILTER_CONTEXT pfc, DWORD dwNotifyType, 
						  LPVOID *ppStFilter, LPVOID *ppStFilterOrg,
						  PSTR *ppszBuf1, int *pcbBuf, PSTR *ppszBuf2, int *pcbBuf2)
{
	DEBUG_CODE_INIT;
	BOOL ret = FALSE;

	DEBUGCHK((*ppStFilterOrg) == NULL);
	DEBUGCHK((*ppStFilter)    == NULL);
	
	switch (dwNotifyType) {
		case SF_NOTIFY_END_OF_NET_SESSION:
		case SF_NOTIFY_END_OF_REQUEST:
			break;

		case SF_NOTIFY_READ_RAW_DATA:
		{
			PHTTP_FILTER_RAW_DATA pRawData = NULL;
			*ppStFilter = pRawData = MyAllocNZ(HTTP_FILTER_RAW_DATA);
			if (!pRawData)
				myleave(220);

			// We use UnaccessedCount() rather than Count() member of Buffio class
			// because we want the entire buffer for the Filter to read.  For instance,
			// if we had http headers and POST data, Count would only return the size
			// of the headers, while UnaccessedCount returns the size of everything.
			// We give filter the whole buffer.  For IIS compat.

			if (!ppszBuf1)  { // Use buffer in CHttpResponse class
				pRawData->cbInData =   m_bufRequest.UnaccessedCount();
				pRawData->cbInBuffer = m_bufRequest.AvailableBufferSize();
				pRawData->pvInData =   m_bufRequest.FilterRawData();  
			}	
			else  { //  Called from ISAPI ReadClient()
				pRawData->cbInBuffer  = *pcbBuf2;
				pRawData->cbInData = *pcbBuf;
				pRawData->pvInData = (PVOID) *ppszBuf1;
			}

			pRawData->dwReserved = 0;
			*ppStFilterOrg = MyAllocNZ(HTTP_FILTER_RAW_DATA);

			if (!(*ppStFilterOrg)) {
				MyFree(pRawData);
				*ppStFilter = NULL;
				myleave(240);
			}
			memcpy(*ppStFilterOrg,*ppStFilter,sizeof(HTTP_FILTER_RAW_DATA));		
		}
		break;

		case SF_NOTIFY_PREPROC_HEADERS:
		{
			PHTTP_FILTER_PREPROC_HEADERS pPreProc = NULL;
			*ppStFilter = pPreProc = MyAllocNZ(HTTP_FILTER_PREPROC_HEADERS);
			*ppStFilterOrg = NULL;

			if (!pPreProc)
				myleave(221);
			pPreProc->GetHeader = ::GetHeader;
			pPreProc->SetHeader = ::SetHeader;
			pPreProc->AddHeader = ::SetHeader;
			pPreProc->HttpStatus = 0;		// no response status code this return 
			pPreProc->dwReserved = 0;	
		}
		break;

		case SF_NOTIFY_URL_MAP:
		{
			PHTTP_FILTER_URL_MAP pUrlMap = NULL;
			*ppStFilter = pUrlMap = MyAllocNZ(HTTP_FILTER_URL_MAP);

			if (!pUrlMap)
				myleave(222);

			if (NULL == ppszBuf1) {  // usual case, use data in CHttpRequest
				pUrlMap->pszURL = m_pszURL;
				pUrlMap->pszPhysicalPath = MySzDupWtoA(m_wszPath);

				if (pUrlMap->pszPhysicalPath)
					pUrlMap->cbPathBuff = MyStrlenA(pUrlMap->pszPhysicalPath);
			}
			else  { // called from ISAPI ext with HSE_REQ_MAP_URL_TO_PATH
				pUrlMap->pszURL = (PSTR) *ppszBuf1;
				pUrlMap->pszPhysicalPath = (PSTR) *ppszBuf2;
				pUrlMap->cbPathBuff = *pcbBuf;
			}
			*ppStFilterOrg = MyAllocNZ(HTTP_FILTER_URL_MAP);

			if ( !pUrlMap->pszURL || ! pUrlMap->pszPhysicalPath || ! (*ppStFilterOrg))  {
				if (NULL == ppszBuf1) // only in this case do we have to clean this up.
					MyFree(pUrlMap->pszPhysicalPath);

				MyFree((*ppStFilterOrg));
				*ppStFilterOrg = NULL;

				MyFree(pUrlMap);
				*ppStFilter = NULL;
				myleave(320);
			}

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

		case SF_NOTIFY_AUTHENTICATION:
		{
			DEBUGCHK(NULL != ppszBuf1 && NULL != ppszBuf2);
			
			PHTTP_FILTER_AUTHENT pAuth = NULL;
			*ppStFilter = pAuth = MyAllocNZ(HTTP_FILTER_AUTHENT);

			if (!pAuth)
				myleave(223);

			// pszUser + pszPassword are static buffers made in AuthenticateFilter fcn
			pAuth->pszUser = (PSTR) *ppszBuf1; 
			pAuth->cbUserBuff = SF_MAX_USERNAME;
			pAuth->pszPassword = (PSTR) *ppszBuf2;		 
			pAuth->cbPasswordBuff = SF_MAX_PASSWORD;
		}
		break;

		case SF_NOTIFY_ACCESS_DENIED:
		{
			PHTTP_FILTER_ACCESS_DENIED pDenied = NULL;
			*ppStFilter = pDenied = MyAllocNZ(HTTP_FILTER_ACCESS_DENIED);

			if (!pDenied)
				myleave(224);

			pDenied->pszURL = m_pszURL;
			pDenied->pszPhysicalPath = MySzDupWtoA(m_wszPath);	
			pDenied->dwReason = SF_DENIED_LOGON;	
			*ppStFilterOrg = MyAllocNZ(HTTP_FILTER_ACCESS_DENIED);

			if (! pDenied->pszURL || ! pDenied->pszPhysicalPath || !(*ppStFilterOrg)) {
				MyFree(pDenied->pszPhysicalPath);
				MyFree((*ppStFilterOrg));
				MyFree(pDenied);
				*ppStFilter = NULL;
				myleave(322);
			}
			memcpy(*ppStFilterOrg,*ppStFilter,sizeof(HTTP_FILTER_ACCESS_DENIED));
		}
		break;

		case SF_NOTIFY_SEND_RESPONSE:
		{
			PHTTP_FILTER_SEND_RESPONSE pSendRes = NULL;
			*ppStFilter = pSendRes = MyAllocNZ(HTTP_FILTER_PREPROC_HEADERS);
			
			if (!pSendRes)
				myleave(225);

			pSendRes->GetHeader  = ::GetHeader;
			pSendRes->SetHeader  = ::SetHeader;
			pSendRes->AddHeader  = ::SetHeader;
			pSendRes->HttpStatus = rgStatus[m_rs].dwStatusNumber;	
			pSendRes->dwReserved = 0;
		}
		break;

		case SF_NOTIFY_SEND_RAW_DATA:
		{
			PHTTP_FILTER_RAW_DATA pRawData = NULL;
			*ppStFilter = pRawData = MyAllocNZ(HTTP_FILTER_RAW_DATA);
			*ppStFilterOrg = MyAllocNZ(HTTP_FILTER_RAW_DATA);

			if (!pRawData || !(*ppStFilterOrg)) {
				MyFree(pRawData);
				MyFree((*ppStFilterOrg));
				*ppStFilter = *ppStFilterOrg = NULL;
				myleave(220);
			}

			pRawData->pvInData = *ppszBuf1;  
			pRawData->cbInData = *pcbBuf;
			pRawData->cbInBuffer = *pcbBuf;
			pRawData->dwReserved = 0;

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

		case SF_NOTIFY_LOG:
		{
			PHTTP_FILTER_LOG pLog = NULL;
			CHAR szHostBuf[MAX_PATH];
			
			*ppStFilter = pLog = MyAllocZ(HTTP_FILTER_LOG);
			if (!pLog)
				myleave(226);

			if (NULL == (pLog->pszClientHostName = (CHAR*)svsutil_AllocZ(LOG_REMOTE_ADDR_SIZE*sizeof(CHAR))))
				goto cleanupFCLog;

			GetRemoteAddress(m_socket,(PSTR) pLog->pszClientHostName,FALSE,LOG_REMOTE_ADDR_SIZE);

			if ( 0 == gethostname(szHostBuf, sizeof(szHostBuf))) {
				if (NULL == (pLog->pszServerName = MySzDupA(szHostBuf)))
					goto cleanupFCLog;
			}
			else
				pLog->pszServerName = cszEmpty;

			pLog->pszClientUserName = m_pszRemoteUser;
			pLog->pszOperation = m_pszMethod;  
			pLog->pszTarget = m_pszURL;
			pLog->pszParameters = m_pszQueryString;
			pLog->dwWin32Status = GetLastError();
			pLog->dwBytesSent = m_pFInfo->m_dwBytesSent;		
			pLog->dwBytesRecvd = m_pFInfo->m_dwBytesReceived;
			pLog->msTimeForProcessing = GetTickCount() - m_pFInfo->m_dwStartTick;

⌨️ 快捷键说明

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