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

📄 parser.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if (!m_pWebsite) {
			m_pWebsite = g_pVars; // reset for when we write out log/filters.
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Unable to map website on socket %x\r\n",m_socket));
			m_rs = STATUS_NOTFOUND;
			myleave(297);
		}
		m_fResolvedHostWebSite = TRUE;
	}

	m_wszPath = m_pWebsite->m_pVroots->URLAtoPathW(m_pszURL, &m_pVRoot, &m_pszPathInfo,TRUE);

	if (g_pVars->m_fFilters &&
	    ! CallFilter(SF_NOTIFY_URL_MAP))
		myleave(293);

	// get extension
	if (m_wszPath && (pwszTemp = wcsrchr(m_wszPath, '.')))
		m_wszExt = MySzDupW(pwszTemp);

	if (m_wszPath)
		m_ccWPath = wcslen(m_wszPath);


	ret = TRUE;
done:
	DEBUGMSG_ERR(ZONE_PARSER,(L"HTTPD: Parse headers failed, err = %d\r\n",err));
	return ret;
}

VERB FindMethod(PCSTR pszMethod, int cbMethod) {
	for (int i = 0; i < cKnownMethods; i++) {
		if (0 == memcmp(pszMethod,rg_cszMethods[i],cbMethod)) {
			DEBUGCHK( (VERB_UNKNOWN+i+1) <= VERB_LAST_VALID);
			return (VERB) (VERB_UNKNOWN+i+1);
		}
	}
	return VERB_UNKNOWN;
}

BOOL CHttpRequest::ParseMethod(PCSTR pszMethod, int cbMethod) {
	DEBUG_CODE_INIT;
	PSTR pszTok, pszTok2;
	int iLen;
	BOOL ret = FALSE;

	// save method
	m_pszMethod = MySzDupA(pszMethod);
	m_idMethod = FindMethod(pszMethod,cbMethod);

	// get URL and HTTP/x.y together (allows for spaces in URL)
	if (!m_bufRequest.NextTokenEOL(&pszTok, &iLen))
		myretleave(FALSE, 201);

	// separate out the HTTP/x.y
	if (pszTok2 = strrchr(pszTok, ' ')) {
		*pszTok2 = 0;
		iLen = pszTok2-pszTok;
		pszTok2++;
	}
	
	// clean up & parse the URL
	if (! MyCrackURL(pszTok, iLen))
		goto done;
	
	// get version (optional. HTTP 0.9 wont have this)
	if (!pszTok2)
		m_dwVersion = MAKELONG(9, 0);
	else {
		int iMajor, iMinor;
		if (2 != sscanf(pszTok2, cszHTTPVER, &iMajor, &iMinor)) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: unable to parse HTTP version from request\r\n"));
			pszTok2[-1] = ' ';	// reset this to a space
			myretleave(FALSE,202);
		}
		m_dwVersion = MAKELONG(iMinor, iMajor);
		
		pszTok2[-1] = ' ';	// reset this to a space
	}
	ret = TRUE;

done:
	DEBUGMSG_ERR(ZONE_PARSER, (L"HTTPD: end ParseMethod (iGLE=%d iErr=%d)\r\n", GLE(err),err));
	return ret;
}

// We assume a raw URL in the form that we receive in the HTTP headers (no scheme, port number etc)
// We extract the path, extra-path, and query
BOOL CHttpRequest::MyCrackURL(PSTR pszRawURL, int iLen) {
	DEBUG_CODE_INIT;
	BOOL ret = FALSE;
	PSTR  pszDecodedURL=0, pszTemp=0;
	int iLen2;

	// special case handeling of 'OPTIONS *' case.
	if (*pszRawURL == '*' && *(pszRawURL+1) == 0 && (m_idMethod == VERB_OPTIONS)) {
		m_fOptionsAsterisk = TRUE;
		m_pszURL = MySzDupA("*");
		return TRUE;
	}

	// In all other cases, HTTPD and a number of ISAPIs assume that the path
	// begins with a '/'.  If it doesn't reject request now.
	if (*pszRawURL != '/') {
		m_rs = STATUS_BADREQ;
		goto done;
	}

	// decode URL (convert escape sequences etc)
	if (NULL == (pszDecodedURL = MyRgAllocNZ(CHAR, iLen+1)))
		myleave(382);

	// Use private Internet canonicalization to avoid wininet dependency.

	// There's no memory allocation in our version of this fcn, always succeeds.
	// The size needed to hold the unencoded URL will always be less than or
	// equal to the original URL.
	svsutil_HttpCanonicalizeUrlA(pszRawURL, pszDecodedURL);

	// get query string
	if (pszTemp = strchr(pszDecodedURL, '?')) {
		if (NULL == (m_pszQueryString = MySzDupA(pszTemp+1)))
			goto done;
		*pszTemp = 0;
	}

	// Searching for an embedded ISAPI dll name, ie /wwww/isapi.dll/a/b.
	// We load the file /www/isapi.dll and set PATH_INFO to /a/b
	// Emebbed ASP file names are handled similiarly.
	if (g_pVars->m_fExtensions) {
		if (pszTemp = strstr(pszDecodedURL,".dll/")) {
			m_pszPathInfo = MySzDupA(pszTemp + sizeof(".dll/") - 2);
			pszTemp[sizeof(".dll/") - 2] = 0;
		}
		else if (pszTemp = strstr(pszDecodedURL,".asp/")) {
			m_pszPathInfo = MySzDupA(pszTemp + sizeof(".asp/") - 2);
			pszTemp[sizeof(".asp/") - 2] = 0;
		}
	}
	
	// save a copy of the cleaned up URL (MINUS query!)
	// alloc one extra char in case we have to send a redirect back (see request.cpp)
	iLen2 = strlen(pszDecodedURL);
	if (NULL == (m_pszURL = MySzAllocA(1+iLen2)))
		goto done;

	Nstrcpy(m_pszURL, pszDecodedURL, iLen2); // copy null-term too.
		
	ret = TRUE;
done:
	MyFree(pszDecodedURL);  
	DEBUGMSG_ERR(ZONE_PARSER, (L"HTTPD: end MyCrackURL(%a) path=%s ext=%s query=%a (iGLE=%d iErr=%d)\r\n", 
		pszRawURL, m_wszPath, m_wszExt, m_pszQueryString, GLE(err), err));
	
	return ret;

}

BOOL CHttpRequest::ParseContentLength(PCSTR pszMethod, TOKEN id) {
	PSTR pszTok = 0;
	int iLen = 0;

	if (m_dwContentLength) {
		DEBUGMSG(ZONE_PARSER,(L"HTTPD: Error: Duplicate Content-length headers in request\r\n"));
		return FALSE;
	}
	
	// get length (first token after "Content-Type;")
	if (m_bufRequest.NextTokenEOL(&pszTok, &iLen) && pszTok && iLen) {
		m_dwContentLength = atoi(pszTok);
		if ((int)m_dwContentLength < 0) {
			DEBUGMSG(ZONE_ERROR,(L"HTTPD: Error: Content-Length = %d, negative.  Rejecting the request\r\n",(int)m_dwContentLength));
			return FALSE;
		}
		
		return TRUE;
	}

	return FALSE;
}

BOOL CHttpRequest::ParseCookie(PCSTR pszMethod, TOKEN id) {
	PSTR pszTok = 0;
	int iLen = 0;

	if (m_pszCookie) {
		DEBUGMSG(ZONE_PARSER,(L"HTTPD: Error: Duplicate Cookie headers in request\r\n"));
		return FALSE;
	}
	
	// get cookie (upto \r\n after "Cookies;")
	if (m_bufRequest.NextTokenEOL(&pszTok, &iLen) && pszTok && iLen) {
		if (NULL == (m_pszCookie = MySzDupA(pszTok)))
			return FALSE;
		return TRUE;
	}
	return FALSE;
}

BOOL CHttpRequest::ParseAccept(PCSTR pszMethod, TOKEN id) {
	PSTR pszTok = 0;
	int iLen = 0;

	if (m_pszAccept) {
		DEBUGMSG(ZONE_PARSER,(L"HTTPD: Error: Duplicate accept headers in request\r\n"));
		return FALSE;
	}
	
	// get cookie (upto \r\n after "Cookies;")
	if (m_bufRequest.NextTokenEOL(&pszTok, &iLen) && pszTok && iLen) {
		if (NULL == (m_pszAccept = MySzDupA(pszTok)))
			return FALSE;
		return TRUE;
	}
	return FALSE;
}


BOOL CHttpRequest::ParseContentType(PCSTR pszMethod, TOKEN id) {
	PSTR pszTok = 0;
	int iLen = 0;

	if (m_pszContentType) {
		DEBUGMSG(ZONE_PARSER,(L"HTTPD: Error: Duplicate content-type headers in request\r\n"));
		return FALSE;
	}

	// get type (first token after "Content-Type;")
	if (m_bufRequest.NextTokenEOL(&pszTok, &iLen) && pszTok && iLen) {
		if (NULL == (m_pszContentType = MySzDupA(pszTok)))
			return FALSE;
		return TRUE;
	}
	return FALSE;
}

const char cszDateParseFmt[] = " %*3s, %02hd %3s %04hd %02hd:%02hd:%02hd GMT; length=%d";

BOOL CHttpRequest::ParseIfModifiedSince(PCSTR pszMethod, TOKEN id) {
	PSTR pszTok = 0;
	int iLen = 0;
	int i = 0;
	char szMonth[10];
	SYSTEMTIME st;
	ZEROMEM(&st);

	if (m_ftIfModifiedSince.dwLowDateTime || m_ftIfModifiedSince.dwHighDateTime) {
		DEBUGMSG(ZONE_PARSER,(L"HTTPD:  Error: Duplicate if-modified-since headers in request\r\n"));
		return FALSE;
	}
	
	// get the date (rest of line after If-Modified-Since)
	// NOTE: Note we are handling only one date format (the "reccomended" one)
	if (m_bufRequest.NextTokenEOL(&pszTok, &iLen) && pszTok && iLen) 	{
		i = sscanf(pszTok, cszDateParseFmt, &st.wDay, szMonth, &st.wYear, &st.wHour, &st.wMinute, &st.wSecond, &m_dwIfModifiedLength);
		if ( i >= 6) {
			// try to match month
			for (i=0; rgMonth[i]; i++) {
				if (0==strcmpi(szMonth, rgMonth[i]))  {
					st.wMonth = i;
					// convert to filetime & store
					SystemTimeToFileTime(&st, &m_ftIfModifiedSince);
					return TRUE;
				}
			}
		}
		DEBUGMSG(ZONE_ERROR, (L"HTTPD: Failed to parse If-Modified-Since(%a) Parsed: day=%02d month=%a(%d) year=%04d time=%02d:%02d:%02d len=%d\r\n", 
			pszTok, st.wDay, szMonth, i, st.wYear, st.wHour, st.wMinute, st.wSecond, m_dwIfModifiedLength));
	}
	return FALSE;
}

BOOL CHttpRequest::ParseAuthorization(PCSTR pszMethod, TOKEN id) {
	DEBUG_CODE_INIT;
	BOOL ret = FALSE;
	PSTR pszTok=0;
	int iLen=0;

	if (m_pszAuthType || m_pszRawRemoteUser) {
		DEBUGMSG(ZONE_PARSER,(L"HTTPD: Error: Duplicate Authorization headers in request\r\n"));
		myretleave(FALSE,99);
	}

	// get the auth scheme (first token after "Authorization;")
	if (!m_bufRequest.NextTokenWS(&pszTok, &iLen) || !pszTok || !iLen)
		myretleave(FALSE, 91);

	if (NULL == (m_pszAuthType = MySzDupA(pszTok)))
		myretleave(FALSE,100);

	// Read in the authentication paramaters and store for after we do vroot parsing.
	if (!m_bufRequest.NextTokenWS(&pszTok, &iLen) || !pszTok || !iLen)
		myretleave(FALSE, 97);

	if (NULL == (m_pszRawRemoteUser = MySzDupA(pszTok)))
		myretleave(FALSE, 98);
	
	ret = TRUE;
done:
	DEBUGMSG_ERR(ZONE_ERROR, (L"HTTPD: Auth FAILED (err=%d ret=%d)\r\n", err, ret));
	return ret; 
}

BOOL CHttpRequest::ParseConnection(PCSTR pszMethod, TOKEN id) {
	PSTR pszTok = 0;
	int iLen = 0;
	
	// get first token after "Connnection;"
	if (m_bufRequest.NextTokenEOL(&pszTok, &iLen) && pszTok && iLen) {
		if (0==strcmpi(pszTok, cszKeepAlive))
			m_fKeepAlive = TRUE;
		return TRUE;
	}
	return FALSE;
}

BOOL CHttpRequest::ParseHost(PCSTR pszMethod, TOKEN id) {
	PSTR pszTok = 0;
	int iLen = 0;

	if (m_pszHost) {
		DEBUGMSG(ZONE_PARSER,(L"HTTPD:  Error: Duplicate host header in request\r\n"));
		return FALSE;
	}

	if (!m_bufRequest.NextTokenEOL(&pszTok, &iLen))
		return FALSE;

	if (NULL == (m_pszHost = MySzDupA(pszTok)))
		return FALSE;

	return TRUE;
}

⌨️ 快捷键说明

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