void RequestHandler::deleteFile()

in host/cxpslib/requesthandler.cpp [1183:1367]


void RequestHandler::deleteFile()
{
    SCOPE_GUARD sessionLogoutGuard = MAKE_SCOPE_GUARD(boost::bind(&RequestHandler::sessionLogout, this));
    SCOPE_GUARD resetGuard = MAKE_SCOPE_GUARD(boost::bind(&RequestHandler::reset, this));

    m_requestTelemetryData.AcquiredRequestType(RequestType_DeleteFile);

    if (!m_loggedIn) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_NotLoggedIn);
        badRequest(AT_LOC, "not logged in\n");
        return;
    }

    // NOTE: allow delete file to complete even if putfile in progress so no need to check putFileInProgress
    tagValue_t::iterator nameTagValue(m_requestInfo.m_params.find(HTTP_PARAM_TAG_NAME));
    if (m_requestInfo.m_params.end() == nameTagValue) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_MissingFileName);
        badRequest(AT_LOC, "missing name");
        return;
    }

    if ((*nameTagValue).second.empty()) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_MissingFileName);
        badRequest(AT_LOC, "missing name");
        return;
    }

    tagValue_t::iterator fileSpecTagValue(m_requestInfo.m_params.find(HTTP_PARAM_TAG_FILESPEC));
    std::string fileSpec = (m_requestInfo.m_params.end() == fileSpecTagValue ? std::string() : (*fileSpecTagValue).second);
    m_requestTelemetryData.AcquiredFilePath(fileSpec.empty() ? nameTagValue->second : fileSpec);

    int mode = FindDelete::FILES_ONLY;
    tagValue_t::iterator modeTagValue(m_requestInfo.m_params.find(HTTP_PARAM_TAG_MODE));
    if (m_requestInfo.m_params.end() != modeTagValue) {
        mode = boost::lexical_cast<int>((*modeTagValue).second);
    }

    std::string ver;
    if (!getVersion(ver)) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_MissingVer);
        badRequest(AT_LOC, "missing ver");
        return;
    }

    tagValue_t::iterator idTagValue(m_requestInfo.m_params.find(HTTP_PARAM_TAG_ID));
    if (m_requestInfo.m_params.end() == idTagValue) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_MissingId);
        badRequest(AT_LOC, "missing id");
        return;
    }

    tagValue_t::iterator reqIdTagValue(m_requestInfo.m_params.find(HTTP_PARAM_TAG_REQ_ID));
    if (m_requestInfo.m_params.end() == reqIdTagValue) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_MissingReqId);
        badRequest(AT_LOC, "missing reqid");
        return;
    }

    bool shouldUpdateThrottlingCache = true;
    CxpsTelemetry::FileType filetype;
    std::string deviceId;

    tagValue_t::iterator filetypeTagValue(m_requestInfo.m_params.find(HTTP_PARAM_TAG_FILETYPE));
    if (m_requestInfo.m_params.end() == filetypeTagValue || filetypeTagValue->second.empty()) {
        shouldUpdateThrottlingCache = false;
    }
    else
    {
        filetype = (CxpsTelemetry::FileType)boost::lexical_cast<int>(filetypeTagValue->second);
    }

    tagValue_t::iterator diskidTagValue(m_requestInfo.m_params.find(HTTP_PARAM_TAG_DISKID));
    if (m_requestInfo.m_params.end() == diskidTagValue || diskidTagValue->second.empty()) {
        shouldUpdateThrottlingCache = false;
    }
    else
    {
        deviceId = diskidTagValue->second;
        boost::algorithm::to_lower(deviceId);
    }

    boost::uint32_t reqId = boost::lexical_cast<boost::uint32_t>((*reqIdTagValue).second);
    if (reqId <= m_reqId) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_InvalidReqId);
        badRequest(AT_LOC, "invalid request id");
        return;
    }

    logRequestBegin();

    if (!Authentication::verifyDeleteFileId(m_hostId,
                                            m_serverOptions->password(),
                                            HTTP_METHOD_GET,
                                            HTTP_REQUEST_DELETEFILE,
                                            m_cnonce,
                                            m_sessionId,
                                            m_snonce,
                                            (*nameTagValue).second,
                                            fileSpec,
                                            ver,
                                            reqId,
                                            (*idTagValue).second)) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_VerifDelFile);

        std::string msg("invalid id for host: ");
        msg += m_hostId;
        msg += " request: ";
        msg += HTTP_REQUEST_DELETEFILE;
        badRequest(AT_LOC, msg.c_str());
        return;
    }
    m_reqId = reqId;

    m_requestTelemetryData.StartingOp();

    std::replace((*nameTagValue).second.begin(), (*nameTagValue).second.end(), '\\', '/');

    std::string result;
    try {
        SCOPE_GUARD logXferGuard = MAKE_SCOPE_GUARD(boost::bind(&RequestHandler::logXferDeleteFile,
                                                                this,
                                                                (*nameTagValue).second,
                                                                fileSpec,
                                                                mode,
                                                                (char*)0));

        boost::filesystem::path fullNamePath;
        getFullPathName((*nameTagValue).second, fullNamePath);
        std::string sessionId = g_sessionTracker->checkOpenFile(fullNamePath, false, false);
        if (!sessionId.empty()) {
            m_requestTelemetryData.SetRequestFailure(RequestFailure_FileOpenInSession);

            m_putFileInfo.m_name.clear(); // this prevents this session from deleting the putfile while another session is using it
            throw ERROR_EXCEPTION << "(sid: " << m_sessionId << ") delete file "
                                  << (*nameTagValue).second << " currently opened by session "
                                  << sessionId << " can not be deleted at this time";
        }
        result = FindDelete::remove((*nameTagValue).second,
                                    fileSpec,
                                    mode,
                                    MAKE_GET_FULL_PATH_CALLBACK_MEM_FUN(&RequestHandler::getFullPathNameWrapper, this),
                                    MAKE_CLOSE_FILE_CALLBACK_MEM_FUN(&RequestHandler::closeFileCallback, this));
        if (result.empty()) {
            m_requestTelemetryData.CompletingOp();

            logXferGuard.dismiss();
            logXferDeleteFile((*nameTagValue).second,
                              fileSpec,
                              mode,
                              "success");
            sendSuccess();
            logRequestDone();
            if (!fullNamePath.empty() && fullNamePath.has_extension() && boost::iequals(fullNamePath.extension().string(), ".dat") &&
                g_diffResyncThrottlerInstance && shouldUpdateThrottlingCache)
            {
                g_diffResyncThrottlerInstance->reduceCachedPendingDataSize(boost::algorithm::to_lower_copy(m_hostId), deviceId, filetype,
                    boost::filesystem::exists(fullNamePath) && boost::filesystem::is_regular_file(fullNamePath) ?
                    boost::filesystem::file_size(fullNamePath) : 0ull);
            }
        }
    } catch (std::exception const & e) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_DeleteFileUnknownError);

        throw ERROR_EXCEPTION << (*nameTagValue).second << " - "
                              <<  fileSpec
                              << " - " << mode << " failed: " << e.what();
    } catch (...) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_DeleteFileUnknownError);

        throw ERROR_EXCEPTION << (*nameTagValue).second << " - "
                              << fileSpec
                              << " - " << mode << " failed: unknown exception.";
    }

    if (!result.empty()) {
        m_requestTelemetryData.SetRequestFailure(RequestFailure_DeleteFileFailed);

        throw ERROR_EXCEPTION << (*nameTagValue).second << " - "
                              << fileSpec
                              << " - " << mode << " failed: " << result;
    }

    sessionLogoutGuard.dismiss();
    m_requestInfo.m_completedCallback();
}