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

📄 request.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//  the http engine no longer directly display the requested page.  In this
//  case the filter acts like an ISAPI extension, it's responsible for returning
//  it's own content.  (Like IIS).  

//  This isn't the same as ASP's concept of having sent headers.  ASP's sent headers
//  stops script from doing other calls to send headers.  If Filter wants to send
//  more headers (which will appear in client browser window) fine, we copy IIS.

//  This is small enough that it's not worth putting into a stub.
BOOL CHttpRequest::FilterNoResponse(void) {
	if (m_pFInfo && m_pFInfo->m_fSentHeaders)
		return TRUE;

	return FALSE;
}

// Note:  This has not been made part of the ISAPI component because we need
// to do checking as to whether the requested operation is valid given our current
// component set.
BOOL CHttpRequest::HandleScript()  {
	DEBUG_CODE_INIT;
	BOOL ret = TRUE;		// Is page a ASP/ISAPI?

	WCHAR *wszMappedISAPI;
	WCHAR *wszExecutePath;
	BOOL  fMappedASP   = FALSE;
	BOOL  fMappedISAPI = FALSE;

	if (g_pVars->m_fExtensions && m_wszExt && MapScriptExtension(m_wszExt,&wszMappedISAPI,&fMappedASP)) {
		if (!fMappedASP) { 
			// If fMappedASP = TRUE we use asp.dll, otherwise wszMappedISAPI points to  ISAPI extension.
			fMappedISAPI = TRUE;
			wszExecutePath = wszMappedISAPI;
		}
		else
			wszExecutePath = m_wszPath;
	}
	else 
		wszExecutePath = m_wszPath;

	if (fMappedASP || fMappedISAPI) {
		// Using a script mapping
		if (m_pszPathInfo) {
			DEBUGCHK(0); // shouldn't be able to set path info on anything but .asp or .dll m_wszExt.
			MyFree(m_pszPathInfo);
		}
		if (NULL == (m_pszPathInfo = MySzDupA(m_pszURL))) {
			m_rs = STATUS_INTERNALERR;
			myleave(59);
		}
	}

	// If the file extension is .dll but the permissions flags don't have 
	// HSE_URL_FLAGS_EXECUTE, we send the dll as a file.  Like IIS.
	// If the VRoot was not executable we would download the dll, regardless of whether
	// extenions are a component or not.  Like IIS.
	if (GetScriptType() == SCRIPT_TYPE_EXTENSION || fMappedISAPI ||
	   (m_wszExt && (0==_wcsicmp(m_wszExt, L".DLL")))) 	{
		if (FALSE == g_pVars->m_fExtensions) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Cannot load ISAPI extension because ISAPI is not a component of httpd.dll\r\n"));
			m_rs = STATUS_NOTIMPLEM;
			myleave(88);
		}

		if (! IsLocalFile(wszExecutePath)) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Cannot load ISAPI extension because it is not on the local device\r\n"));
			m_rs = STATUS_FORBIDDEN;
			if (g_pVars->m_fFilters)
				CallFilter(SF_NOTIFY_ACCESS_DENIED);
			myleave(87);
		}

		if (! TranslateRequestToScript()) {
			ret = (m_rs != STATUS_OK); // return TRUE to stop remainder of HandleRequest processing on err
			goto done;
		}

		if (! (GetPerms() & HSE_URL_FLAGS_EXECUTE)) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: cannot load ISAPI extension because vroot does not have HSE_URL_FLAGS_EXECUTE set\r\n"));
			m_rs = STATUS_FORBIDDEN;
			
			if (g_pVars->m_fFilters)
				CallFilter(SF_NOTIFY_ACCESS_DENIED);
			myleave(79);
		}

		if (! SetPathTranslated()) {
			m_rs = STATUS_INTERNALERR;
			myleave(94);
		}

		if (! ExecuteISAPI(wszExecutePath)) {
			m_rs = STATUS_INTERNALERR;
			myleave(53);
		}
	}

	// check if it's an executable ASP.  If the appropriate permissions aren't set,
	// we send an access denied message.  Never download an ASP file's source
	// code under any conditions.
	else if(GetScriptType() == SCRIPT_TYPE_ASP || fMappedASP || 
	   m_wszExt && (0==_wcsicmp(m_wszExt, L".ASP"))) {
		if (FALSE == g_pVars->m_fASP) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Cannot load ASP interpretter because ASP is not a component of httpd.dll\r\n"));
			m_rs = STATUS_NOTIMPLEM;
			myleave(89);
		}

		if (!IsLocalFile(m_wszPath)) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Cannot load ASP page because it is not on the local device\r\n"));
			m_rs = STATUS_FORBIDDEN;

			if (g_pVars->m_fFilters)
				CallFilter(SF_NOTIFY_ACCESS_DENIED);
			myleave(87);
		}

		if (! TranslateRequestToScript()) {
			ret = (m_rs != STATUS_OK); // return TRUE to stop remainder of HandleRequest processing on err
			goto done;
		}

		if ( ! (GetPerms() & (HSE_URL_FLAGS_EXECUTE | HSE_URL_FLAGS_SCRIPT))) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: cannot load ASP because vroot does not have HSE_URL_FLAGS_EXECUTE | HSE_URL_FLAGS_SCRIPT set\r\n"));
			m_rs = STATUS_FORBIDDEN;
			
			if (g_pVars->m_fFilters)
				CallFilter(SF_NOTIFY_ACCESS_DENIED);
			myleave(79);
		}

		if (! SetPathTranslated()) {
			m_rs = STATUS_INTERNALERR;
			myleave(94);
		}

		if(!ExecuteASP()) {
			// ExecuteASP sets m_rs on error. 
			myleave(92);
		}
	}
	else { // Neither an ASP or ISAPI.
		ret = FALSE;
	}

done:
	DEBUGMSG_ERR(ZONE_REQUEST,(L"HTTPD: HandleScript failed, err = %d, m_rs = %d\r\n",err,m_rs));
	return ret;
}


//  wszFile is the physical file we're going to try to load.  Function returns
//  true if file is local and false if it is on a network drive.

//  The only ways a file can be non-local on CE are if it has a UNC name 
//  (\\machineshare\share\file) or if it is mapped under the NETWORK directory.
//  However, the Network folder doesn't have to be named "network", so we
//  use the offical method to get the name
BOOL IsLocalFile(PWSTR wszFile) {
	// Are we requested a UNC name
	if ( wcslen(wszFile) >= 2) 	{
		if ( (wszFile[0] == '\\' || wszFile[0] == '/') && 
		     (wszFile[1] == '\\' || wszFile[1] == '/'))  {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Extension or ASP requested is not on local file system, access denied\r\n"));
			return FALSE;
		}
	}

	CEOIDINFO ceOidInfo;
	DWORD dwNetworkLen;


	if (!CeOidGetInfo(OIDFROMAFS(AFS_ROOTNUM_NETWORK), &ceOidInfo))  {
		return TRUE;	// if we can't load it assume that it's not supported in general, so it is local file
	}

	dwNetworkLen =  wcslen(ceOidInfo.infDirectory.szDirName);
	if (0 == wcsnicmp(ceOidInfo.infDirectory.szDirName,wszFile,dwNetworkLen))  {
		DEBUGMSG(ZONE_ERROR,(L"HTTPD: Extension or ASP requested is not on local file system, access denied\r\n"));
		return FALSE;
	}

	return TRUE;
}

// dwMaxSizeToRead is HKLM\Comm\Httpd\PostReadSize in typcilac case, or
// is unread data if fInitialPostRead=0, which means that we're handling
// an error condition on keep-alive and need to read remaining post data.

// Note that we do NOT suck in remaining POST data if an ISAPI extension
// ran and had more data than was initially read in because it's the ISAPI's
// job to read all this data off the wire using ReadClient if they're going
// to do a keep-alive; if they don't do this then HTTPD will get parse errors,
// like IIS.

BOOL CHttpRequest::ReadPostData(DWORD dwMaxSizeToRead, BOOL fInitialPostRead, BOOL fSSLRenegotiate) {
	BOOL ret = TRUE;
	HRINPUT hi;
	
	if ((m_dwContentLength && dwMaxSizeToRead) || fSSLRenegotiate)  {
		DWORD dwRead = min(m_dwContentLength,dwMaxSizeToRead);

		hi = m_bufRequest.RecvBody(m_socket, dwRead, !fInitialPostRead,fInitialPostRead,this,fSSLRenegotiate);

		if (m_rs != STATUS_OK) {
			// if !STATUS_OK we've set err already, probably SSL forbidden issue.
			ret = FALSE;
		}
		else if ((hi != INPUT_OK) && (hi != INPUT_NOCHANGE))  { 
			m_rs = STATUS_BADREQ;
			ret = FALSE;
		}
		// If no new data was read (hi = INPUT_NOCHANGE) don't call filter.
		else if (g_pVars->m_fFilters  &&
		    hi != INPUT_NOCHANGE && 
		    ! CallFilter(SF_NOTIFY_READ_RAW_DATA)) {
			// let filter set error code.
			ret = FALSE;
		}	
	}

	if (ret == TRUE)
		m_dwInitialPostRead = m_bufRequest.m_iNextInFollow = m_bufRequest.m_iNextIn;

	return ret;
}

BOOL CHttpRequest::CheckAuth() {
	if (CheckAuth(GetAuthReq()))
		return TRUE;

	DEBUGMSG(ZONE_AUTH,(L"HTTPD: CheckAuth fails.  Access required=%d, access granted=%d\r\n",GetAuthReq(),m_AuthLevelGranted));
	if (g_pVars->m_fFilters)
		CallFilter(SF_NOTIFY_ACCESS_DENIED);

	return FALSE;
}


BOOL IsPathScript(WCHAR *szPath, SCRIPT_TYPE scriptType) {
	if ((scriptType == SCRIPT_TYPE_EXTENSION) || (scriptType == SCRIPT_TYPE_ASP))
		return TRUE;

	WCHAR *szISAPI;
	BOOL  fMappedASP;

	WCHAR *szExt = wcsrchr(szPath, '.');
	if (!szExt)
		return FALSE;

	if ((0 == _wcsicmp(szExt,L".dll")) || (0 == _wcsicmp(szExt,L".asp")))
		return TRUE;

	return (MapScriptExtension(szExt,&szISAPI,&fMappedASP));
}

// Checks to see if we're mapped to an ISAPI/ASP page.
// If fCheckAccess=TRUE, also verifies that required permissions to execute have been granted.

BOOL CHttpRequest::IsScript(BOOL fCheckAccess) {
	WCHAR *szISAPI = NULL;
	BOOL fMappedASP = FALSE;
	BOOL fMappedISAPI = (m_wszExt && MapScriptExtension(m_wszExt,&szISAPI,&fMappedASP) && !fMappedASP);

	// script map to an ISAPI, direct request to ISAPI ".dll", or vroot maps to ISAPI
	if (fMappedISAPI || (m_wszExt && (0==_wcsicmp(m_wszExt, L".DLL"))) || (GetScriptType() == SCRIPT_TYPE_EXTENSION))
		return fCheckAccess ? (GetPerms() & (HSE_URL_FLAGS_EXECUTE | HSE_URL_FLAGS_READ)) : TRUE;

	// script map to a ASP, direct request to file named *.asp , or vroot maps to ASP
	if (fMappedASP || ((m_wszExt && 0==_wcsicmp(m_wszExt, L".ASP"))) || (GetScriptType() == SCRIPT_TYPE_ASP))
		return fCheckAccess ? (GetPerms() & (HSE_URL_FLAGS_EXECUTE | HSE_URL_FLAGS_SCRIPT)) : TRUE;

	return FALSE;
}

// Is there a 'translate: f' HTTP header?  On return, one of three things can happen.
//   1. There's no translate header, so execute script as always (typical case)
//   2. There is a 'translate: f' header but no HSE_URL_FLAGS_SCRIPT_SOURCE access on vroot.
//        Send 403 to client.
//   3. There is a 'translate: f' header and script source access is granted.  HandleRequest 
//        processes remainder of request from then, most likely pushing off to WebDAV.
BOOL CHttpRequest::TranslateRequestToScript(void) {
	PSTR szHeader = FindHttpHeader(cszTranslate,ccTranslate);

	if (szHeader && (*szHeader == 'f' || *szHeader == 'F')) {
		DEBUGMSG(ZONE_REQUEST,(L"HTTPD: \"translate: 'f'\" header sent, will not forward request to script\r\n"));

		if (! (GetPerms() & HSE_URL_FLAGS_SCRIPT_SOURCE)) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: request to access script source fails,HSE_URL_FLAGS_SCRIPT_SOURCE for this vroot\r\n"));
			m_rs = STATUS_FORBIDDEN;
		}
		if ((GetScriptType() == SCRIPT_TYPE_EXTENSION) || (GetScriptType() == SCRIPT_TYPE_ASP)) {
			if ((m_idMethod != VERB_OPTIONS) && (m_idMethod != VERB_PROPFIND)) {
				DEBUGMSG(ZONE_ERROR,(L"HTTPD: request to skip translatition on script that is mapped directly to VRoot is not supported, returning 403\r\n"));
				m_rs = STATUS_FORBIDDEN;
			}
		}
		return FALSE;
	}

	return TRUE;
}

PSTR CHttpRequest::FindHttpHeader(PCSTR szHeaderName, DWORD ccHeaderName) {
	PSTR szTrav = m_bufRequest.Headers();

	DEBUGCHK(szHeaderName[ccHeaderName-1] == ':');
	DEBUGCHK(strlen(szHeaderName) == ccHeaderName);
	DEBUGCHK(!m_fHeadersInvalid); // no temporary \0's in header.

	while (*szTrav != '\r') {
		if (0 == _strnicmp(szHeaderName,szTrav,ccHeaderName)) {
			PSTR szHeaderValue = szTrav + ccHeaderName;
			while ( (szHeaderValue)[0] != '\0' && IsNonCRLFSpace((szHeaderValue)[0])) { ++(szHeaderValue); }

			return szHeaderValue;
		}
		if (NULL == (szTrav = strstr(szTrav,"\r\n")))
			break;

		szTrav += 2;
	}
	return NULL;
}

// We only call authenticate filter once per session.
BOOL CHttpRequest::CallAuthFilterIfNeeded(void) {
	if (g_pVars->m_fFilters && ! (m_dwAuthFlags & AUTH_FILTER_DONE)) {
		m_dwAuthFlags |= AUTH_FILTER_DONE;
		return AuthenticateFilter();
	}
	return TRUE;
}

⌨️ 快捷键说明

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