FCGX_Accept_r在没有有效请求的情况下返回成功

时间:2015-04-15 14:28:06

标签: c fastcgi

这是相关代码,我尽可能地将其缩短,希望不排除错误源。

DebugLogMsg是一个类似于printf的日志文件写入工具,可以认为它不会导致错误。

//Some init stuff and smthng
    while (1)
    {
        memset (&requestFcgx, 0, sizeof (requestFcgx));
        iRet = FCGX_InitRequest (&requestFcgx, 0, 0);
        DebugLogMsg ("FCGX_InitRequest() called!!\r\n");

        if (iRet != 0)
        {
            DebugLogMsg ("FCGX_InitRequest failed, return val:%d!\r\n", iRet);
            return NULL;
        }

        iRet = FCGX_Accept_r (&requestFcgx);

        if (iRet != 0)
        {
            DebugLogMsg1 ("FCGX_Accept_r failed!\r\n");
            continue;
        }

        char *foo = FCGX_GetParam("SOME_CUSTOM_VAL", requestFcgx.envp);
        DebugLogMsg ("CustomParam:%s\r\n", foo);

        do
        {
            //processing the request...
            if (ERROR == TRUE)
            {
                DebugLogMsg ("FatalError!\r\n");
                return NULL;
            }

            DebugLogMsg ("no errors occured!");
        }
        while (0);

        FCGX_Finish_r (&requestFcgx);
        DebugLogMsg ("Cleanup.... DONE!\r\n");
    }

我的问题是iRet = FCGX_Accept_r (&requestFcgx);不会阻止每次第二次通话,因为它应该。 (至少我希望这个功能应该阻止)

Web服务器发送请求后,函数会立即释放,在没有任何错误记录的情况下运行循环,调用Finish,循环到循环体的开头,再次调用iRet = FCGX_Accept_r (&requestFcgx);时,它返回立即使用iRet == 0,但requestFcgx结构似乎无效(由于甚至没有启动附加请求,因此可以预期)。相应的日志文件包含此过程:

[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040]    FCGX_InitRequest() called!
            ----------------------------------------
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040]    CustomParam:ExpectedStuff
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040]    no errors occured!
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040]    Cleanup.... DONE!

[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040]    FCGX_InitRequest() called!
            ----------------------------------------
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040]    CustomParam:(null)
[Wed Apr 15 15:41:26 2015][Thread:0;0x802420040]    FatalError!

//////////////////////////////
////////Protocol closed///////
//////////////////////////////

(请有人编辑Logtext,不要编码为代码,我不知道如何)

由于请求未提供信息并关闭,因此发生致命错误。关键是,为什么iRet = FCGX_Accept_r (&requestFcgx);0失败时会返回{{1}}?如果预计会这样做,我必须考虑这种行为。

1 个答案:

答案 0 :(得分:1)

有两个问题 -

    在进入FCGX_InitRequest(&requestFcgx, 0, 0)循环之前,需要调用
  1. while(1)
  2. SIGPIPE信号也可能导致此行为。试着忽略它。将此块添加到main()函数的开头 -

    struct sigaction sa_ign;
    sa_ign.sa_handler = SIG_IGN;
    sa_ign.sa_flags = 0;
    sigemptyset(&sa_ign.sa_mask);
    sigaction(SIGPIPE, &sa_ign, NULL);
    
  3. 您提到该应用是多线程的。如果是这样,您还必须致电FCGX_Init()。以下是来自fcgiapp.h标题文件 -

    的信息
    /*
     *----------------------------------------------------------------------
     *
     * FCGX_Init --
     *
     *      Initialize the FCGX library.  Call in multi-threaded apps
     *      before calling FCGX_Accept_r().
     *
     *      Returns 0 upon success.
     *
     *----------------------------------------------------------------------
     */
    DLLAPI int FCGX_Init(void);
    

    检查这个简单的多线程FastCGI应用程序 -

    http://www.fastcgi.com/devkit/examples/threaded.c