📄 davmain.cpp
字号:
}
if (! AddContentLocationHeaderIfNeeded())
goto done;
if (! HasBody())
fRet = SendProperties(DAV_PROP_ALL,FALSE);
else
fRet = SendSubsetOfProperties();
done:
return fRet;
}
BOOL CWebDav::DavProppatch(void) {
BOOL fRet = FALSE;
BOOL fProceed = TRUE;
CPropPatchParse cPropPatch(this);
CWebDavFileNode *pFileNode = NULL;
if (! (m_pRequest->GetPerms() & HSE_URL_FLAGS_WRITE)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: PROPPATCH fails, VRoot does not have HSE_URL_FLAGS_WRITE permission\r\n"));
SetStatus(STATUS_FORBIDDEN);
goto done;
}
if (! AddContentLocationHeaderIfNeeded())
goto done;
if (! CheckIfHeaders()) {
DEBUGCHK(m_pRequest->m_rs != STATUS_OK);
goto done;
}
if (! CheckLockHeader()) {
DEBUGCHK(m_pRequest->m_rs != STATUS_OK);
goto done;
}
// We need to explicitly look this file up in our lock manager cache because
// holding a file handle to a file (even with minimal sharing) will not prevent
// a call to SetFileAttributes on it from succeeding.
g_pFileLockManager->Lock();
if (! g_pFileLockManager->CanPerformLockedOperation(m_pRequest->m_wszPath,NULL,&m_lockIds,m_nLockTokens,&pFileNode,NULL)) {
DEBUGCHK(pFileNode);
SetStatusAndXMLBody(STATUS_LOCKED);
SendLockTags(pFileNode);
fProceed = FALSE;
}
g_pFileLockManager->Unlock();
if (!fProceed)
goto done;
if (ParseXMLBody(&cPropPatch,FALSE)) {
DEBUGCHK(m_pRequest->m_rs == STATUS_OK);
fRet = SendPropPatchResponse(STATUS_OK);
}
done:
return fRet;
}
BOOL CWebDav::DavMkcol(void) {
BOOL fRet = FALSE;
if (! (m_pRequest->GetPerms() & HSE_URL_FLAGS_WRITE)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MKCOL fails, VRoot does not have HSE_URL_FLAGS_WRITE permission\r\n"));
SetStatus(STATUS_FORBIDDEN);
goto done;
}
if (m_pRequest->m_dwContentLength || m_pRequest->FindHttpHeader(cszContent_Type,ccContent_Type)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MKCOL fails, client has sent body, server doesn't support body\r\n"));
SetStatus(STATUS_UNSUPPORTED_MEDIA_TYPE);
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 (IsSrcFileNameLenTooLong()) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MKCOl fails, request URI is too long\r\n"));
SetStatus(STATUS_REQUEST_TOO_LARGE);
goto done;
}
if (! CreateDirectoryW(m_pRequest->m_wszPath,NULL)) {
DWORD dwErr = GetLastError();
DEBUGMSG(ZONE_ERROR,(L"HTTPD: MKCOL fails, CreateDirectoryW fails, GLE=0x%08x\r\n",dwErr));
if ((dwErr == ERROR_FILE_EXISTS) || (dwErr == ERROR_ALREADY_EXISTS))
SetStatus(STATUS_METHODNOTALLOWED);
else if (dwErr == ERROR_PATH_NOT_FOUND)
SetStatus(STATUS_CONFLICT);
else
SetStatus(STATUS_INTERNALERR);
}
else {
AddContentLocationHeader();
CHttpResponse resp(m_pRequest,STATUS_CREATED);
resp.SetZeroLenBody();
resp.SendResponse();
fRet = TRUE;
}
done:
return fRet;
}
BOOL CWebDav::DavPut(void) {
BOOL fRet = FALSE;
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL fFileExists;
BOOL fLockedFile = FALSE;
if (! (m_pRequest->GetPerms() & HSE_URL_FLAGS_WRITE)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: PUT fails, VRoot does not have HSE_URL_FLAGS_WRITE permission\r\n"));
SetStatus(STATUS_FORBIDDEN);
goto done;
}
if (m_pRequest->FindHttpHeader(cszContent_Range,ccContent_Range)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: PUT fails, CE DAV does not support \"Content-Range\" setting\r\n"));
SetStatus(STATUS_NOTIMPLEM);
goto done;
}
#if 0
if (! m_pRequest->m_dwContentLength) { // NOTE: XP redirector frequently sends 0 length files, so this check is not safe.
// no chunked-encoding currently
if (! m_pRequest->FindHttpHeader(cszTransfer_Encoding,ccTransfer_Encoding)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: PUT fails because no content-length or transfer-encoding was set\r\n"));
SetStatus(STATUS_LENGTH_REQUIRED);
goto done;
}
}
#endif // 0
if (IsCollection()) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: PUT fails, attempting to write to a directory\r\n"));
SetStatus(STATUS_CONFLICT);
goto done;
}
if (IsSrcFileNameLenTooLong()) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: PUT fails, request URI is too long\r\n"));
SetStatus(STATUS_REQUEST_TOO_LARGE);
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 (INVALID_HANDLE_VALUE == (hFile = MyWriteFile(m_pRequest->m_wszPath))) {
if (CheckLockTokens()) {
// Does file have a lock and did client send lock tokens to access it?
CWebDavFileNode *pFileNode;
g_pFileLockManager->Lock();
if (g_pFileLockManager->CanPerformLockedOperation(m_pRequest->m_wszPath,NULL,&m_lockIds,m_nLockTokens,&pFileNode,NULL)) {
DEBUGCHK(g_pFileLockManager->IsLocked());
hFile = pFileNode->m_hFile;
SetFilePointer(hFile,0,NULL,FILE_BEGIN);
fLockedFile = TRUE;
}
g_pFileLockManager->Unlock();
}
}
if (INVALID_HANDLE_VALUE == hFile) {
DWORD dwErr = GetLastError();
DEBUGMSG(ZONE_ERROR,(L"HTTPD: PUT fails, unable to open file %s, GLE=0x%08x\r\n",m_pRequest->m_wszPath,dwErr));
SendLockedConflictOrErr(m_pRequest->m_wszPath);
goto done;
}
fFileExists = (GetLastError() == ERROR_ALREADY_EXISTS);
if (WriteBodyToFile(hFile,FALSE)) {
SetEndOfFile(hFile); // In event we're writing more data to file than existed previously.
CHttpResponse resp(m_pRequest,fFileExists ? STATUS_OK : STATUS_CREATED);
resp.SetBody(hFile,NULL,0);
resp.SetZeroLenBody();
resp.UnSetMimeType();
resp.SendResponse();
fRet = TRUE;
}
else {
SetStatus(GLEtoStatus());
}
done:
// Close file if its a valid handle, but only if it's not a previously locked file.
if ((hFile != INVALID_HANDLE_VALUE) && !fLockedFile)
CloseHandle(hFile);
return fRet;
}
BOOL CWebDav::DavDelete(void) {
BOOL fRet = FALSE;
if (! (m_pRequest->GetPerms() & HSE_URL_FLAGS_WRITE)) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: DELETE fails, VRoot does not have HSE_URL_FLAGS_WRITE permission\r\n"));
SetStatus(STATUS_FORBIDDEN);
goto done;
}
if (IsNull()) {
DEBUGMSG(ZONE_ERROR,(L"HTTPD: DELETE fails, file %s does not exist\r\n",m_pRequest->m_wszPath));
SetStatus(STATUS_NOTFOUND);
goto done;
}
if (! AddContentLocationHeaderIfNeeded())
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 (IsCollection()) {
fRet = DeleteCollection(m_pRequest->m_wszPath,m_pRequest->m_pszURL);
}
else { // single file
if (!DavDeleteFile(m_pRequest->m_wszPath)) {
// If we fail because we're locked, send this info to the client
if (! SendLockErrorInfoIfNeeded(m_pRequest->m_wszPath))
SetStatus(GLEtoStatus());
}
else
fRet = TRUE;
}
done:
if (fRet) {
CHttpResponse resp(m_pRequest,STATUS_NOCONTENT);
resp.SetZeroLenBody();
resp.SendResponse();
m_fSetStatus = TRUE;
}
// Possible for us to have returned multistatus contained detailed info,
// in which case HTTPD shouldn't put err messages on it.
return IS_STATUS_2XX(m_pRequest->m_rs);
}
// Unimplemented
BOOL CWebDav::DavUnsupported(void) {
SetStatus(STATUS_NOTIMPLEM);
return FALSE;
}
BOOL CWebDav::MoveCopyResource(BOOL fDeleteSrc) {
DWORD dwAccess = fDeleteSrc ? (HSE_URL_FLAGS_READ | HSE_URL_FLAGS_WRITE) : HSE_URL_FLAGS_READ;
BOOL fRet = FALSE;
// Pointer to original URL sent in HTTP headers, and ptr to '\0' to set to '\r'
PSTR szDestPrefix = NULL;
PSTR szDestURL = NULL;
PSTR szSave = NULL;
WCHAR *wszDestPath = NULL;
BOOL fDestExists = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -