📄 vroots.hpp
字号:
m_pVRoots[i].iURLLen--; // -1 for null-term
m_pVRoots[i].iPathLen = wcslen(wszPath);
// If a URL is named '/foo/', store it as '/foo' for requests that request /foo.
if (m_pVRoots[i].iURLLen != 1 && IsSlash(pszURL[m_pVRoots[i].iURLLen-1])) {
pszURL[m_pVRoots[i].iURLLen-1] = L'\0';
m_pVRoots[i].iURLLen--;
}
// If the path is "$REDIRECT", web server will send "302" with location in Redirect REG_SZ.
if (0 == wcsicmp(wszPath,REDIRECT_VALUE)) {
WCHAR wszRedirectURL[MAX_PATH];
m_pVRoots[i].fRedirect = TRUE;
if (! subreg.ValueSZ(RV_REDIRECT,wszRedirectURL,CCHSIZEOF(wszRedirectURL)) ||
(NULL == (m_pVRoots[i].pszRedirectURL = MySzDupWtoA(wszRedirectURL))))
{
DEBUGMSG(ZONE_ERROR,(L"HTTPD: Did not initialize vroot %s, %s value must be present on redirects!\r\n",wszURL,RV_REDIRECT));
subreg.Reset();
continue;
}
if (NULL == (m_pVRoots[i].pszURL = MySzDupA(pszURL)))
{ myleave(84); }
// don't bother reading any other values in this case.
subreg.Reset();
PREFAST_SUPPRESS(394,"Incrementing loop pointer like this is safe - only done on some paths, and only once per iteration, so no chance of going off array");
i++;
continue;
}
// check to see if Vroot ends in .dll or .asp, in this case we send
// client not to the directory but to the script page.
if (m_pVRoots[i].iPathLen > SVSUTIL_CONSTSTRLEN(cszDLL) &&
0 == wcsicmp(wszPath + m_pVRoots[i].iPathLen - SVSUTIL_CONSTSTRLEN(cszDLL),cszDLL))
{
m_pVRoots[i].ScriptType = SCRIPT_TYPE_EXTENSION;
}
else if (m_pVRoots[i].iPathLen > SVSUTIL_CONSTSTRLEN(cszASP) &&
0 == wcsicmp(wszPath + m_pVRoots[i].iPathLen - SVSUTIL_CONSTSTRLEN(cszASP),cszASP))
{
m_pVRoots[i].ScriptType = SCRIPT_TYPE_ASP;
}
else
{
m_pVRoots[i].ScriptType = SCRIPT_TYPE_NONE;
}
// If one of URL or path ends in a slash, the other must too.
// If either the URL ends in a "/" or when the path ends in "\", we remove
// the extra symbol. However, in the case where either URL or path is
// root we don't do this.
if (m_pVRoots[i].iURLLen == 1 && pszURL[0]=='/' && m_pVRoots[i].ScriptType == SCRIPT_TYPE_NONE) {
// if it's the root URL, make sure correspinding path ends with "\"
// (if it's a directory only, leave ASP + ISAPI's alone)
if (wszPath[m_pVRoots[i].iPathLen-1] != L'\\') {
wszPath[m_pVRoots[i].iPathLen] = L'\\';
m_pVRoots[i].iPathLen++;
wszPath[m_pVRoots[i].iPathLen] = L'\0';
}
}
// If Path ends in "\" (and it's not the root path or root virtual root)
// remove the "\"
if (m_pVRoots[i].iURLLen != 1 && m_pVRoots[i].iPathLen != 1 && wszPath[m_pVRoots[i].iPathLen-1]==L'\\') {
wszPath[m_pVRoots[i].iPathLen-1] = L'\0';
m_pVRoots[i].iPathLen--;
}
else if (m_pVRoots[i].iPathLen == 1 && wszPath[0]==L'\\') {
/*
// Trailing "/" must match "\".
if (pszURL[m_pVRoots[i].iURLLen-1] != '/') {
pszURL[m_pVRoots[i].iURLLen] = '/';
m_pVRoots[i].iURLLen++;
pszURL[m_pVRoots[i].iURLLen] = '\0';
}
*/
m_pVRoots[i].fRootDir = TRUE;
}
m_pVRoots[i].fDirBrowse = subreg.ValueDW(RV_DIRBROWSE,fDefaultDirBrowse);
m_pVRoots[i].fNTLM = subreg.ValueDW(RV_NTLM,fDefaultNTLM);
m_pVRoots[i].fBasic = subreg.ValueDW(RV_BASIC,fDefaultBasic);
m_pVRoots[i].fNegotiate = subreg.ValueDW(RV_NEGOTIATE,fDefaultNegotiate);
m_pVRoots[i].wszPath = MySzDupW(wszPath);
m_pVRoots[i].pszURL = MySzDupA(pszURL);
if (! m_pVRoots[i].wszPath || ! m_pVRoots[i].pszURL) {
MyFree(m_pVRoots[i].wszPath);
MyFree(m_pVRoots[i].pszURL);
myleave(85);
}
// OK for userlist to be NULL.
m_pVRoots[i].wszUserList = MySzDupW( subreg.ValueSZ(RV_USERLIST));
// default permissions is Read & Execute
m_pVRoots[i].dwPermissions = subreg.ValueDW(RV_PERM, HTTP_DEFAULTP_PERMISSIONS);
if ((m_pVRoots[i].dwPermissions & HSE_URL_FLAGS_REQUIRE_CERT) && !(m_pVRoots[i].dwPermissions & (HSE_URL_FLAGS_SSL | HSE_URL_FLAGS_SSL128))) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: Client requires HSE_URL_FLAGS_REQUIRE_CERT but did not set SSL for VRoot %s, auto-setting HSE_URL_FLAGS_SSL to this vroot\r\n",wszPath));
m_pVRoots[i].dwPermissions |= HSE_URL_FLAGS_SSL;
}
// default authentication is public
m_pVRoots[i].AuthLevel = (AUTHLEVEL)subreg.ValueDW(RV_AUTH, (DWORD)AUTH_PUBLIC);
// Count # of slashes now, skipping initial one.
m_pVRoots[i].iNumSlashes = CountSignificantSlashesInURL(m_pVRoots[i].pszURL,m_pVRoots[i].iURLLen);
DEBUGMSG(ZONE_VROOTS, (L"HTTPD: VROOT: (%a)=>(%s) perm=%d auth=%d ScriptType=%d\r\n", m_pVRoots[i].pszURL,
m_pVRoots[i].wszPath, m_pVRoots[i].dwPermissions, m_pVRoots[i].AuthLevel,m_pVRoots[i].ScriptType));
}
subreg.Reset();
i++;
}
// We now want to sort the VRoots in descending order of URL-length so
// that when we match we'll find the longest match first!!
do{
fChange = FALSE;
PREFAST_SUPPRESS(12009,"m_nVRoots is always small. It is # of registry keys and is read from protected registry");
for(i=0; i<m_nVRoots-1; i++) {
if(m_pVRoots[i].iURLLen < m_pVRoots[i+1].iURLLen) {
// swap the 2 vroots
VROOTINFO vtemp = m_pVRoots[i+1];
m_pVRoots[i+1] = m_pVRoots[i];
m_pVRoots[i] = vtemp;
fChange = TRUE;
}
}
} while(fChange);
done:
if(err) {
DEBUGMSG(ZONE_ERROR, (L"HTTPD: CVRoots::ctor FAILED due to err=%d GLE=%d (num=%d i=%d pVRoots=0x%08x url=%s path=%s)\r\n",
err, GetLastError(), m_nVRoots, i, m_pVRoots, wszURL, wszPath));
return FALSE;
}
return TRUE;
}
void Cleanup() {
if(!m_pVRoots)
return;
for(int i=0; i<m_nVRoots; i++) {
MyFree(m_pVRoots[i].pszURL);
MyFree(m_pVRoots[i].wszPath);
MyFree(m_pVRoots[i].wszUserList);
MyFree(m_pVRoots[i].pszRedirectURL);
}
MyFree(m_pVRoots);
}
public:
CVRoots(CReg *pWebsite, BOOL fDefaultDirBrowse, BOOL fDefaultBasic, BOOL fDefaultNTLM, BOOL fDefaultNegotiate) { ZEROMEM(this); Init(pWebsite, fDefaultDirBrowse, fDefaultBasic, fDefaultNTLM, fDefaultNegotiate); }
~CVRoots() { Cleanup(); }
DWORD Count() { return m_nVRoots; }
PWSTR URLAtoPathW(PSTR pszInputURL, PVROOTINFO *ppVRootInfo=NULL, PSTR *ppszPathInfo=0, BOOL fAcceptRedirect=FALSE) {
WCHAR *wszTemp = NULL;
int iInputLen = strlen(pszInputURL);
PVROOTINFO pVRoot = MatchVRoot(pszInputURL, iInputLen);
if(!pVRoot)
return NULL;
if (ppVRootInfo)
*ppVRootInfo = pVRoot;
if (pVRoot->fRedirect) {
// There are cases where if we see a redirect URL we want to act like it
// doesn't exist (i.e. during Script Mapping).
if (!fAcceptRedirect)
return FALSE;
DEBUGCHK(ppVRootInfo);
return NULL; // calling function ignores return value, looks at *ppVRootInfo for where to redirect to.
}
int iOutLen = 2 + pVRoot->iPathLen + (iInputLen - pVRoot->iURLLen);
PWSTR wszOutPath = MyRgAllocNZ(WCHAR, iOutLen+1);
if (!wszOutPath)
return NULL;
// assemble the path. First, the mapped base path
if (pVRoot->iPathLen != 1)
memcpy(wszOutPath, pVRoot->wszPath, sizeof(WCHAR)*pVRoot->iPathLen);
// If the vroot specifies an ISAPI dll or ASP page don't copy path info over.
if (pVRoot->ScriptType != SCRIPT_TYPE_NONE) {
if ( ppszPathInfo && pszInputURL[pVRoot->iURLLen] != 0) {
SetPathInfo(ppszPathInfo,pszInputURL,pVRoot->iURLLen);
}
wszOutPath[pVRoot->iPathLen] = L'\0';
ConvertSlashes(wszOutPath);
return wszOutPath;
}
// next the remainder of the URL, converted to wide
if (iOutLen-pVRoot->iPathLen == 1) {
wszOutPath[pVRoot->iPathLen] = L'\0';
}
else {
int iOffset;
if (pVRoot->iPathLen == 1 && iOutLen==3) {
// This is special case where virtual root mapped to '\' receives request to '/'.
wszOutPath[0] = L'\\';
wszOutPath[1] = 0;
return wszOutPath;
}
else if (pVRoot->iPathLen == 1 && pVRoot->iURLLen == 1) {
// This is special case where virtual root '/' maps to '\', need to include the beginning '/' in URL
wszOutPath[0] = L'\\';
iOffset = 1;
}
else if (pVRoot->iPathLen == 1) {
// virtual root maps to '/' but we're requesting a file.
// We have to do this extra special case handeling because when a vroot
// maps to a directory the directory doesn't store trailing '\', but in this case
// where filename is only '\' we do have it.
iOffset = 0;
}
else {
iOffset = pVRoot->iPathLen;
}
int iRet = MyA2W(pszInputURL+pVRoot->iURLLen, wszOutPath+iOffset, iOutLen-iOffset-1);
DEBUGCHK(iRet);
}
DEBUGCHK((int)(wcslen(wszOutPath) + 1) <= iOutLen);
ConvertSlashes(wszOutPath);
return wszOutPath;
}
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -