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

📄 cgiapp.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: cgiapp.cpp,v $ * PRODUCTION Revision 1000.2  2004/06/01 18:39:07  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.53 * PRODUCTION * =========================================================================== *//*  $Id: cgiapp.cpp,v 1000.2 2004/06/01 18:39:07 gouriano Exp $* ===========================================================================**                            PUBLIC DOMAIN NOTICE*               National Center for Biotechnology Information**  This software/database is a "United States Government Work" under the*  terms of the United States Copyright Act.  It was written as part of*  the author's official duties as a United States Government employee and*  thus cannot be copyrighted.  This software/database is freely available*  to the public for use. The National Library of Medicine and the U.S.*  Government have not placed any restriction on its use or reproduction.**  Although all reasonable efforts have been taken to ensure the accuracy*  and reliability of the software and data, the NLM and the U.S.*  Government do not and cannot warrant the performance or results that*  may be obtained by using this software or data. The NLM and the U.S.*  Government disclaim all warranties, express or implied, including*  warranties of performance, merchantability or fitness for any particular*  purpose.**  Please cite the author in any work or product based on this material.** ===========================================================================** Author: Eugene Vasilchenko, Denis Vakatov, Anatoliy Kuznetsov** File Description:*   Definition CGI application class and its context class.*/#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <corelib/ncbienv.hpp>#include <corelib/ncbireg.hpp>#include <cgi/cgiapp.hpp>#include <cgi/cgictx.hpp>#ifdef NCBI_OS_UNIX#  include <unistd.h>#endifBEGIN_NCBI_SCOPE///////////////////////////////////////////////////////// CCgiApplication//CCgiApplication* CCgiApplication::Instance(void){    return dynamic_cast<CCgiApplication*> (CParent::Instance());}int CCgiApplication::Run(void){    // Value to return from this method Run()    int result;    // Try to run as a Fast-CGI loop    if ( x_RunFastCGI(&result) ) {        return result;    }    /// Run as a plain CGI application    // Make sure to restore old diagnostic state after the Run()    CDiagRestorer diag_restorer;    // Compose diagnostics prefix#if defined(NCBI_OS_UNIX)    PushDiagPostPrefix(NStr::IntToString(getpid()).c_str());#endif    PushDiagPostPrefix(GetEnvironment().Get(m_DiagPrefixEnv).c_str());    // Timing    CTime start_time(CTime::eCurrent);    // Logging for statistics    bool is_stat_log =        GetConfig().GetBool("CGI", "StatLog", false, CNcbiRegistry::eReturn);    auto_ptr<CCgiStatistics> stat(is_stat_log ? CreateStat() : 0);    // Logging    ELogOpt logopt = GetLogOpt();    if (logopt == eLog) {        x_LogPost("(CGI) CCgiApplication::Run ",                  0, start_time, &GetEnvironment(), fBegin);    }    try {        _TRACE("(CGI) CCgiApplication::Run: calling ProcessRequest");        m_Context.reset( CreateContext() );        ConfigureDiagnostics(*m_Context);        x_AddLBCookie();        result = ProcessRequest(*m_Context);        _TRACE("CCgiApplication::Run: flushing");        m_Context->GetResponse().Flush();        _TRACE("CCgiApplication::Run: return " << result);    }    catch (exception& e) {        // Call the exception handler and set the CGI exit code        result = OnException(e, NcbiCout);        // Logging        {{            string msg = "(CGI) CCgiApplication::ProcessRequest() failed: ";            msg += e.what();            if (logopt != eNoLog) {                x_LogPost(msg.c_str(), 0, start_time, 0, fBegin|fEnd);            } else {                ERR_POST(msg);  // Post error notification even if no logging            }            if ( is_stat_log ) {                stat->Reset(start_time, result, &e);                msg = stat->Compose();                stat->Submit(msg);            }        }}        // Exception reporting        {{            CException* ex = dynamic_cast<CException*> (&e);            if ( ex ) {                NCBI_RETHROW_SAME((*ex), "(CGI) CCgiApplication::Run");            }        }}    }    // Logging    if (logopt == eLog) {        x_LogPost("(plain CGI) CCgiApplication::Run ",                  0, start_time, 0, fEnd);    }    if ( is_stat_log ) {        stat->Reset(start_time, result);        string msg = stat->Compose();        stat->Submit(msg);    }    return result;}CCgiContext& CCgiApplication::x_GetContext( void ) const{    if ( !m_Context.get() ) {        ERR_POST("CCgiApplication::GetContext: no context set");        throw runtime_error("no context set");    }    return *m_Context;}CNcbiResource& CCgiApplication::x_GetResource( void ) const{    if ( !m_Resource.get() ) {        ERR_POST("CCgiApplication::GetResource: no resource set");        throw runtime_error("no resource set");    }    return *m_Resource;}void CCgiApplication::Init(void){    // Disable background reporting by default    CException::EnableBackgroundReporting(false);    // Convert multi-line diagnostic messages into one-line ones by default    SetDiagPostFlag(eDPF_PreMergeLines);    SetDiagPostFlag(eDPF_MergeLines);    CParent::Init();    m_Resource.reset(LoadResource());    m_DiagPrefixEnv = GetConfig().Get("CGI", "DiagPrefixEnv");}void CCgiApplication::Exit(void){    m_Resource.reset(0);    CParent::Exit();}CNcbiResource* CCgiApplication::LoadResource(void){    return 0;}CCgiServerContext* CCgiApplication::LoadServerContext(CCgiContext& /*context*/){    return 0;}CCgiContext* CCgiApplication::CreateContext(CNcbiArguments*   args, CNcbiEnvironment* env, CNcbiIstream*     inp, CNcbiOstream*     out, int               ifd, int               ofd){    int errbuf_size =        GetConfig().GetInt("CGI", "RequestErrBufSize", 256,                           CNcbiRegistry::eReturn);    return       new CCgiContext(*this, args, env, inp, out, ifd, ofd,                     (errbuf_size >= 0) ? (size_t) errbuf_size : 256,                     m_RequestFlags);}void CCgiApplication::SetCafService(CCookieAffinity* caf){    m_Caf.reset(caf);}// Flexible diagnostics support//class CStderrDiagFactory : public CDiagFactory{public:    virtual CDiagHandler* New(const string&) {        return new CStreamDiagHandler(&NcbiCerr);    }};class CAsBodyDiagFactory : public CDiagFactory{public:    CAsBodyDiagFactory(CCgiApplication* app) : m_App(app) {}    virtual CDiagHandler* New(const string&) {        CCgiResponse& response = m_App->GetContext().GetResponse();        CDiagHandler* result   = new CStreamDiagHandler(&response.out());        response.SetContentType("text/plain");        response.WriteHeader();        response.SetOutput(0); // suppress normal output        return result;    }private:    CCgiApplication* m_App;};CCgiApplication::CCgiApplication(void)  : m_HostIP(0),    m_Iteration(0),   m_RequestFlags(0){    DisableArgDescriptions();    RegisterDiagFactory("stderr", new CStderrDiagFactory);    RegisterDiagFactory("asbody", new CAsBodyDiagFactory(this));}CCgiApplication::~CCgiApplication(void){    ITERATE (TDiagFactoryMap, it, m_DiagFactories) {        delete it->second;    }    if ( m_HostIP )        free(m_HostIP);}int CCgiApplication::OnException(exception& e, CNcbiOstream& os){    os << "Status: 500 Error processing HTTP request" HTTP_EOL;    os << "Content-Type: text/html" HTTP_EOL HTTP_EOL;    os << e.what();    if ( !os.good() ) {        ERR_POST("CCgiApplication::OnException() failed to send error page"                 " back to the client");        return -1;    }    return 0;}void CCgiApplication::RegisterDiagFactory(const string& key,                                          CDiagFactory* fact){    m_DiagFactories[key] = fact;}CDiagFactory* CCgiApplication::FindDiagFactory(const string& key){    TDiagFactoryMap::const_iterator it = m_DiagFactories.find(key);    if (it == m_DiagFactories.end())        return 0;    return it->second;}void CCgiApplication::ConfigureDiagnostics(CCgiContext& context){    // Disable for production servers?    ConfigureDiagDestination(context);    ConfigureDiagThreshold(context);    ConfigureDiagFormat(context);}void CCgiApplication::ConfigureDiagDestination(CCgiContext& context){    const CCgiRequest& request = context.GetRequest();    bool   is_set;    string dest   = request.GetEntry("diag-destination", &is_set);    if ( !is_set )        return;    SIZE_TYPE colon = dest.find(':');    CDiagFactory* factory = FindDiagFactory(dest.substr(0, colon));    if ( factory ) {        SetDiagHandler(factory->New(dest.substr(colon + 1)));    }}void CCgiApplication::ConfigureDiagThreshold(CCgiContext& context){    const CCgiRequest& request = context.GetRequest();    bool   is_set;    string threshold = request.GetEntry("diag-threshold", &is_set);    if ( !is_set )        return;    if (threshold == "fatal") {        SetDiagPostLevel(eDiag_Fatal);    } else if (threshold == "critical") {        SetDiagPostLevel(eDiag_Critical);    } else if (threshold == "error") {        SetDiagPostLevel(eDiag_Error);    } else if (threshold == "warning") {        SetDiagPostLevel(eDiag_Warning);    } else if (threshold == "info") {        SetDiagPostLevel(eDiag_Info);    } else if (threshold == "trace") {        SetDiagPostLevel(eDiag_Info);        SetDiagTrace(eDT_Enable);    }}void CCgiApplication::ConfigureDiagFormat(CCgiContext& context){    const CCgiRequest& request = context.GetRequest();    typedef map<string, TDiagPostFlags> TFlagMap;    static TFlagMap s_FlagMap;    TDiagPostFlags defaults = (eDPF_Prefix | eDPF_Severity                               | eDPF_ErrCode | eDPF_ErrSubCode);    TDiagPostFlags new_flags = 0;    bool   is_set;    string format = request.GetEntry("diag-format", &is_set);    if ( !is_set )        return;    if (s_FlagMap.empty()) {        s_FlagMap["file"]        = eDPF_File;        s_FlagMap["path"]        = eDPF_LongFilename;        s_FlagMap["line"]        = eDPF_Line;        s_FlagMap["prefix"]      = eDPF_Prefix;        s_FlagMap["severity"]    = eDPF_Severity;        s_FlagMap["code"]        = eDPF_ErrCode;        s_FlagMap["subcode"]     = eDPF_ErrSubCode;        s_FlagMap["time"]        = eDPF_DateTime;        s_FlagMap["omitinfosev"] = eDPF_OmitInfoSev;        s_FlagMap["all"]         = eDPF_All;        s_FlagMap["trace"]       = eDPF_Trace;        s_FlagMap["log"]         = eDPF_Log;    }    list<string> flags;    NStr::Split(format, " ", flags);    ITERATE(list<string>, flag, flags) {        TFlagMap::const_iterator it;        if ((it = s_FlagMap.find(*flag)) != s_FlagMap.end()) {            new_flags |= it->second;        } else if ((*flag)[0] == '!'                   &&  ((it = s_FlagMap.find(flag->substr(1)))                        != s_FlagMap.end())) {            new_flags &= ~(it->second);        } else if (*flag == "default") {            new_flags |= defaults;        }    }    SetDiagPostAllFlags(new_flags);}CCgiApplication::ELogOpt CCgiApplication::GetLogOpt() const{    string log = GetConfig().Get("CGI", "Log");    CCgiApplication::ELogOpt logopt = eNoLog;    if ((NStr::CompareNocase(log, "On") == 0) ||        (NStr::CompareNocase(log, "true") == 0)) {        logopt = eLog;    } else if (NStr::CompareNocase(log, "OnError") == 0) {        logopt = eLogOnError;    }#ifdef _DEBUG    else if (NStr::CompareNocase(log, "OnDebug") == 0) {        logopt = eLog;    }#endif    return logopt;}void CCgiApplication::x_LogPost(const char*             msg_header,                                unsigned int            iteration,                                const CTime&            start_time,                                const CNcbiEnvironment* env,                                TLogPostFlags           flags)    const{    CNcbiOstrstream msg;    const CNcbiRegistry& reg = GetConfig();    if ( msg_header ) {        msg << msg_header << NcbiEndl;    }    if ( flags & fBegin ) {        bool is_print_iter = reg.GetBool("FastCGI", "PrintIterNo",                                         false, CNcbiRegistry::eErrPost);        if ( is_print_iter ) {            msg << " Iteration = " << iteration << NcbiEndl;        }    }

⌨️ 快捷键说明

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