📄 davmain.cpp
字号:
PVROOTINFO pVRoot; // Use destinations VROOT and permission (not m_pRequest's necessarily) to determine what we can do.
WIN32_FILE_ATTRIBUTE_DATA wDestAttribs;
if (! (m_pRequest->GetPerms() & dwAccess)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MOVE/COPY fails, action is forbidden\r\n"));
SetStatus(STATUS_FORBIDDEN);
goto done;
}
GetOverwrite();
// Depth for MOVE must be infinite. For copy it may be 0 or infinite.
if (!GetDepth() || (fDeleteSrc && (m_Depth != DEPTH_INFINITY)) ||
(!fDeleteSrc && (m_Depth != DEPTH_INFINITY && m_Depth != DEPTH_ZERO))) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MOVE/COPY fails, depth header is corrupt or invalid for verb requested\r\n"));
SetStatus(STATUS_BADREQ);
goto done;
}
if (! CheckIfHeaders()) {
DEBUGCHK(m_pRequest->m_rs != STATUS_OK);
goto done;
}
if (! CheckLockHeader()) {
DEBUGCHK(m_pRequest->m_rs != STATUS_OK);
goto done;
}
if (NULL == (szDestURL = GetDestinationHeader(&szDestPrefix,&szDestURL,&szSave))) {
DEBUGCHK(! IS_STATUS_2XX(m_pRequest->m_rs));
goto done;
}
if (IsNull()) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MOVE/COPY fails, resource to move (%s) does not exist\r\n",m_pRequest->m_wszPath));
SetStatus(STATUS_NOTFOUND);
goto done;
}
wszDestPath = m_pRequest->m_pWebsite->m_pVroots->URLAtoPathW(szDestURL,&pVRoot);
if (IsSrcFileNameLenTooLong() || IsFileNameTooLongForFilesys(wszDestPath)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: move/copy fails, source or dest file name too long for filesys\r\n"));
SetStatus(STATUS_REQUEST_TOO_LARGE);
goto done;
}
if (!HasAccessToDestVRoot(szDestURL,wszDestPath,pVRoot)) {
SetStatus(STATUS_UNAUTHORIZED);
goto done;
}
if ((*wszDestPath == '/' || *wszDestPath == '\\') && (*(wszDestPath+1) == 0)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MOVE/COPY fails, request set destination as root of filesystem\r\n"));
SetStatus(STATUS_FORBIDDEN);
goto done;
}
if (! GetFileAttributesEx(wszDestPath,GetFileExInfoStandard,&wDestAttribs)) {
if (GetLastError() == ERROR_ACCESS_DENIED) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MOVE/COPY fails, GLE=0x%08x\r\n"));
SetStatus(STATUS_FORBIDDEN);
goto done;
}
fDestExists = FALSE;
}
if (!fDestExists) {
if (!m_pRequest->m_bufRespHeaders.AddHeader(cszLocation,szDestPrefix))
goto done;
}
if (fDestExists && IsDirectory(&wDestAttribs) &&
!(pVRoot->dwPermissions & HSE_URL_FLAGS_READ)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MOVE/COPY fails, destination directory does not have read permissions enabled\r\n"));
SetStatus(STATUS_FORBIDDEN);
goto done;
}
if (IsPathSubDir(m_pRequest->m_wszPath,m_pRequest->m_ccWPath,wszDestPath,wcslen(wszDestPath))) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MOVE/COPY fails, destination or source url is subset of the other path, not allowed\r\n"));
SetStatus(STATUS_FORBIDDEN);
goto done;
}
// Only add location header on copy because on move, src will be deleted on success.
if (!fDeleteSrc && !AddContentLocationHeaderIfNeeded())
goto done;
if ((! (m_Overwrite & OVERWRITE_YES)) && fDestExists) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MOVE/COPY fails, destination exists but overwrite option is turned off\r\n"));
SetStatus(STATUS_PRECONDITION_FAILED);
goto done;
}
// delete the destination before copying, per spec.
if ((m_Overwrite & OVERWRITE_YES) && fDestExists) {
if (IsDirectory(&wDestAttribs)) {
if (! DeleteCollection(wszDestPath,szDestURL)) {
fRet = (m_pRequest->m_rs == STATUS_MULTISTATUS);
goto done;
}
}
else { // Single file
if (!DavDeleteFile(wszDestPath)) {
SendLockedConflictOrErr(wszDestPath);
goto done;
}
}
}
if (IsCollection()) {
DEBUGCHK(! URLHasTrailingSlashW(m_pRequest->m_wszPath));
CMoveCopyContext cMoveContext(fDeleteSrc,m_pRequest->GetPerms(),pVRoot->dwPermissions,szDestURL,wszDestPath,m_pRequest->m_ccWPath);
fRet = MoveCopyCollection(&cMoveContext);
}
else {
if (FALSE == MoveCopyFile(fDeleteSrc,m_pRequest->m_wszPath,wszDestPath)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: WebDav move or copy fails, GLE = 0x%08x\r\n"));
SendLockedConflictOrErr(wszDestPath,m_pRequest->m_wszPath);
fRet = (m_pRequest->m_rs == STATUS_MULTISTATUS);
goto done;
}
fRet = TRUE;
}
done:
if (fRet && (m_pRequest->m_rs != STATUS_MULTISTATUS)) {
DEBUGCHK(m_pRequest->m_rs == STATUS_OK);
CHttpResponse resp(m_pRequest,fDestExists ? STATUS_NOCONTENT : STATUS_CREATED);
resp.SetZeroLenBody();
resp.SendResponse();
}
if (szSave) {
*szSave = '\r';
m_pRequest->DebugSetHeadersInvalid(FALSE);
}
MyFreeNZ(szDestURL);
MyFreeNZ(wszDestPath);
return fRet;
}
BOOL CWebDav::DavMove(void) {
return MoveCopyResource(TRUE);
}
BOOL CWebDav::DavCopy(void) {
return MoveCopyResource(FALSE);
}
#if 0
BOOL CWebDav::DavSearch(void) { return DavUnsupported(); }
BOOL CWebDav::DavSubscribe(void) { return FALSE; }
BOOL CWebDav::DavUnsubscribe(void) { return FALSE; }
BOOL CWebDav::DavPoll(void) { return FALSE; }
BOOL CWebDav::DavBDelete(void) { return FALSE; }
BOOL CWebDav::DavBCopy(void) { return FALSE; }
BOOL CWebDav::DavBMove(void) { return FALSE; }
BOOL CWebDav::DavBProppatch(void) { return FALSE; }
BOOL CWebDav::DavBPropfind(void) { return FALSE; }
BOOL CWebDav::DavX_MS_Enumatts(void) { return FALSE; }
#endif
// Constant strings relating to WebDAV
// DAV XML strings
const CHAR cszXMLVersionA[] = "<?xml version=\"1.0\" ?>";
const DWORD ccXMLVersionA = SVSUTIL_CONSTSTRLEN(cszXMLVersionA);
const CHAR cszMultiStatusNS[] = "multistatus xmlns:a=\"DAV:\" xmlns:b=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\" xmlns:c=\"xml:\" xmlns:d=\"urn:schemas-microsoft-com:\"";
const DWORD ccMultiStatusNS = SVSUTIL_CONSTSTRLEN(cszMultiStatusNS);
const CHAR cszMultiStatus[] = "multistatus";
const DWORD ccMultiStatus = SVSUTIL_CONSTSTRLEN(cszMultiStatus);
const CHAR cszResponse[] = "response";
const DWORD ccResponse = SVSUTIL_CONSTSTRLEN(cszResponse);
const CHAR cszHref[] = "href";
const DWORD ccHref = SVSUTIL_CONSTSTRLEN(cszHref);
const CHAR cszPropstat[] = "propstat";
const DWORD ccPropstat = SVSUTIL_CONSTSTRLEN(cszPropstat);
const CHAR cszProp[] = "prop";
const DWORD ccProp = SVSUTIL_CONSTSTRLEN(cszProp);
const CHAR cszPropNS[] = "prop xmlns:a=\"DAV:\"";
const DWORD ccPropNS = SVSUTIL_CONSTSTRLEN(cszPropNS);
const CHAR cszStatus[] = "status";
const DWORD ccStatus = SVSUTIL_CONSTSTRLEN(cszStatus);
const CHAR cszGetcontentLengthNS[] = "getcontentlength b:dt=\"int\"";
const DWORD ccGetcontentLengthNS = SVSUTIL_CONSTSTRLEN(cszGetcontentLengthNS);
const CHAR cszGetcontentLength[] = "getcontentlength";
const DWORD ccGetcontentLength = SVSUTIL_CONSTSTRLEN(cszGetcontentLength);
const CHAR cszDisplayName[] = "displayname";
const DWORD ccDisplayName = SVSUTIL_CONSTSTRLEN(cszDisplayName);
const CHAR cszCreationDateNS[] = "creationdate b:dt=\"dateTime.tz\"";
const DWORD ccCreationDateNS = SVSUTIL_CONSTSTRLEN(cszCreationDateNS);
const CHAR cszCreationDate[] = "creationdate";
const DWORD ccCreationDate = SVSUTIL_CONSTSTRLEN(cszCreationDate);
const CHAR cszGetETag[] = "getetag";
const DWORD ccGetETag = SVSUTIL_CONSTSTRLEN(cszGetETag);
const CHAR cszLastModifiedNS[] = "getlastmodified b:dt=\"dateTime.rfc1123\"";
const DWORD ccLastModifiedNS = SVSUTIL_CONSTSTRLEN(cszLastModifiedNS);
const CHAR cszLastModified[] = "getlastmodified";
const DWORD ccLastModified = SVSUTIL_CONSTSTRLEN(cszLastModified);
const CHAR cszResourceType[] = "resourcetype";
const DWORD ccResourceType = SVSUTIL_CONSTSTRLEN(cszResourceType);
const CHAR cszCollection[] = "collection";
const DWORD ccCollection = SVSUTIL_CONSTSTRLEN(cszCollection);
const CHAR cszIsHiddenNS[] = "ishidden b:dt=\"boolean\"";
const DWORD ccIsHiddenNS = SVSUTIL_CONSTSTRLEN(cszIsHiddenNS);
const CHAR cszIsHidden[] = "ishidden";
const DWORD ccIsHidden = SVSUTIL_CONSTSTRLEN(cszIsHidden);
const CHAR cszIsCollectionNS[] = "iscollection b:dt=\"boolean\"";
const DWORD ccIsCollectionNS = SVSUTIL_CONSTSTRLEN(cszIsCollectionNS);
const CHAR cszIsCollection[] = "iscollection";
const DWORD ccIsCollection = SVSUTIL_CONSTSTRLEN(cszIsCollection);
const CHAR cszSupportedLock[] = "supportedlock";
const DWORD ccSupportedLock = SVSUTIL_CONSTSTRLEN(cszSupportedLock);
const CHAR cszLockEntry[] = "lockentry";
const DWORD ccLockEntry = SVSUTIL_CONSTSTRLEN(cszLockEntry);
const CHAR cszTextXML[] = "text/xml";
const DWORD ccTextXML = SVSUTIL_CONSTSTRLEN(cszTextXML);
const CHAR cszApplicationXML[] = "application/xml";
const DWORD ccApplicationXML = SVSUTIL_CONSTSTRLEN(cszApplicationXML);
const CHAR cszGetcontentType[] = "getcontenttype";
const DWORD ccGetcontentType = SVSUTIL_CONSTSTRLEN(cszGetcontentType);
// Win32 specific proptags. We only currently support setting Win32FileAttributes.
const CHAR cszMSNamespace[] = "urn:schemas-microsoft-com:";
const DWORD ccMSNamespace = SVSUTIL_CONSTSTRLEN(cszMSNamespace);
const CHAR cszWin32FileAttribs[] = "Win32FileAttributes";
const DWORD ccWin32FileAttribs = SVSUTIL_CONSTSTRLEN(cszWin32FileAttribs);
const CHAR cszWin32LastAccessTime[] = "Win32LastAccessTime";
const DWORD ccWin32LastAccessTime = SVSUTIL_CONSTSTRLEN(cszWin32LastAccessTime);
const CHAR cszWin32LastModifiedTime[] = "Win32LastModifiedTime";
const DWORD ccWin32LastModifiedTime = SVSUTIL_CONSTSTRLEN(cszWin32LastModifiedTime);
const CHAR cszWin32CreationTime[] = "Win32CreationTime";
const DWORD ccWin32CreationTime = SVSUTIL_CONSTSTRLEN(cszWin32CreationTime);
// LOCK XML strings
const CHAR cszLockDiscovery[] = "lockdiscovery";
const DWORD ccLockDiscovery = SVSUTIL_CONSTSTRLEN(cszLockDiscovery);
const CHAR cszActiveLock[] = "activelock";
const DWORD ccActiveLock = SVSUTIL_CONSTSTRLEN(cszActiveLock);
const CHAR cszLockType[] = "locktype";
const DWORD ccLockType = SVSUTIL_CONSTSTRLEN(cszLockType);
const CHAR cszWrite[] = "write";
const DWORD ccWrite = SVSUTIL_CONSTSTRLEN(cszWrite);
const CHAR cszLockScope[] = "lockscope";
const DWORD ccLockScope = SVSUTIL_CONSTSTRLEN(cszLockScope);
const CHAR cszShared[] = "shared";
const DWORD ccShared = SVSUTIL_CONSTSTRLEN(cszShared);
const CHAR cszExclusive[] = "exclusive";
const DWORD ccExclusive = SVSUTIL_CONSTSTRLEN(cszExclusive);
const CHAR cszLockTokenTag[] = "locktoken";
const DWORD ccLockTokenTag = SVSUTIL_CONSTSTRLEN(cszLockTokenTag);
const CHAR cszOwner[] = "owner";
const DWORD ccOwner = SVSUTIL_CONSTSTRLEN(cszOwner);
const CHAR cszTimeoutTag[] = "timeout";
const DWORD ccTimeoutTag = SVSUTIL_CONSTSTRLEN(cszTimeoutTag);
const CHAR cszDepthTag[] = "depth";
const DWORD ccDepthTag = SVSUTIL_CONSTSTRLEN(cszDepthTag);
const CHAR cszSecond[] = "Second-";
const DWORD ccSecond = SVSUTIL_CONSTSTRLEN(cszSecond);
const CHAR cszInfinite[] = "Infinite";
const DWORD ccInfinite = SVSUTIL_CONSTSTRLEN(cszInfinite);
const CHAR cszNot[] = "not";
const DWORD ccNot = SVSUTIL_CONSTSTRLEN(cszNot);
// DAV header data
const CHAR csz0[] = "0";
const DWORD cc0 = SVSUTIL_CONSTSTRLEN(csz0);
const CHAR csz1[] = "1";
const DWORD cc1 = SVSUTIL_CONSTSTRLEN(csz1);
const CHAR cszInfinity[] = "infinity";
const DWORD ccInfinity = SVSUTIL_CONSTSTRLEN(cszInfinity);
const CHAR csz1NoRoot[] = "1, noroot";
const DWORD cc1NoRoot = SVSUTIL_CONSTSTRLEN(csz1NoRoot);
// const CHAR cszInfinityNoRoot = "infinity,noroot";
const char cszPrefixBraceOpen[] = "<a:";
const DWORD ccPrefixBraceOpen = SVSUTIL_CONSTSTRLEN(cszPrefixBraceOpen);
const char cszPrefixBraceEnd[] = "</a:";
const DWORD ccPrefixBraceEnd = SVSUTIL_CONSTSTRLEN(cszPrefixBraceEnd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -