Project

General

Profile

Lighty, FastCGI, C++

Added by Ejhuay about 7 years ago

Hello,

I have been trying to follow examples and read documentation to get lighty running with FastCGI connected to my own C++ application. I just can't quite get my feet off the ground and have a few questions that may help. Thank you for your time in reading this post and any potential assistance you may provide.

I am not using PHP or Rails. I am running on Ubuntu 10.10.

My FastCGI config block looks like this:

fastcgi.server = (
    "" => (
      "test.fastcgi.handler" => (
        "host" => "127.0.0.1",
    "port" => "5000",
        "check-local" => "disable",
      )
    )
  )

My C++ application code looks like this:

int main (void)
{

    FCGX_Request request;

    FCGX_Init();
    FCGX_InitRequest(&request, 0, 0);

    while (FCGX_Accept_r(&request) == 0)
    {
        //Do stuff here
    }

    return 0;
}

I startup lighty, and then run my application. It immediately drops out of the request loop (error -88).

I have tried a number of variations on the code (different examples), and I am always dropping out of my request loop with error -88.

This leads me to a number of questions that I am having a difficult time finding answers for:

1. Documentation refers to the "Fast CGI Process" running on its own thread. Is this my c++ application? Or, is there yet another service I need to be starting that lives in-between lighty and my c++ app?

2. What does error -88 mean?

3. I specify the connection address in lighty's config file (loopback 5000 in this case). Where do I specify this in my c++ application? None of the examples specify an address - do the fast cgi libraries magically line these up somehow? If so, where is that done, and do I need to do anything to make sure they match up?

Thank you for your time and consideration,
Ejhuay


Replies (5)

RE: Lighty, FastCGI, C++ - Added by ver about 7 years ago

Well to start with, I would suggest ensuring the return values of FCGX_Init and FCGX_InitRequest to narrow down where the issue could be.

I don't see a "bin-path" option in your config block, I assume you're using fcgid?

The FCGI particular code is executed on whichever thread you call it from in your code. If your code is single threaded, that's the thread.

You can accept, fork/thread, and let that worker thread go and accept the next request, if you like.

As for the return value, that looks like an accept() result, which you can display with perror(errno); after your FCGX_Accept_r call. Typically this suggests the pipe between lighty and the fcgi daemon has permissions which are preventing a successful connection.

RE: Lighty, FastCGI, C++ - Added by Ejhuay about 7 years ago

Thank you for the reply.

FCGX_Init and FCGX_InitRequest both return 0 (perror=Success)

FCGX_Accept_r returns -88. From the perror, I get:
socket operation on non-socket

One person has the same issue with apache, and it turned out they forgot to install the FCGI apache module. However, when I run lighty-enable-mod fastcgi, it tells me that it is both available and already enabled.
Is it possible the FCGI connection does not exist? My assumption was that when lighty starts up, it opens up the port I supplied in the config file. Any idea?

I have not been using fcgid. My plan was to start lighty, then start my c++ application in debug mode to connect. My understanding is that the FCGX_Accept_r method should block until a new request comes in. Is this correct? When I google fcgid, it looks like an apache or php specific module. I still don't quite understand what fcgid is.

To experiment some, I installed spawn-fcgid. When I start my application, it exits right away, just as when I debug it.

To further experiment, I placed the path to my C++ application in the bin-path setting in lighty's config file. I can run the following application to get a white screen on the browser:

int main (void)
{
    FCGX_Request request;

    int result = FCGX_Init();
    //perror("something happened");

    result = FCGX_InitRequest(&request, 0, 0);
    //perror("something happened");

    result = FCGX_Accept_r(&request);
    while (result == 0)
    {
        cout << "It Worked";

        result = FCGX_Accept_r(&request);
    }
    return 0;
}

I'm really not sure if the white screen (no html) is a step in the right direction or not.

If I change the bin-path to be incorrect, I instead get a generic "page not found" error.

Any thoughts or ideas would be greatly appreciated.

Thank You,
Ejhuay

RE: Lighty, FastCGI, C++ - Added by stbuehler about 7 years ago

use spawn-fcgi, and read the docs for fastcgi

RE: Lighty, FastCGI, C++ - Added by ver about 7 years ago

well.. you'll never see the cout line. to print data to the web client, use something like: FCGX_FPrintF( request.out, "It Worked" ); after accepting the request.

RE: Lighty, FastCGI, C++ - Added by s.gleissner about 7 years ago

Hi,

this is my config, which is working since three years (and the code is so old :-) ):

lighttpd.conf

fastcgi.server = (
  "/device" =>
  (( "host" => "127.0.0.1",
     "port" => 9000,
     "check-local" => "disable",
     "docroot" => "/" 
  ))
)

my web server thread:

void webserver::thread(void)
{
    char* envvar;
    do
    {
        while (FCGX_Accept(&in, &out, &err, &envp) >= 0)
        {    // the following block is only needed when data is send with a POST command
            envvar = FCGX_GetParam("CONTENT_LENGTH", envp);
            post_size = 0;
            if (envvar != NULL)
            {
                post_size = strtol(envvar, NULL, 10);
                if(!post_readheader())    // other code, not included here, see RFC2387
                    post_size=-1;
            }

            envvar = FCGX_GetParam("REQUEST_URI", envp);    // get URL, e.g. "/device?site=login.html" 

            // do something here with the URL
             // the result comes in 2 objects: header and content, both can be casted to normal c-strings

            FCGX_PutStr((char*)header, header.len(), out);
            FCGX_PutStr((char*)content, content.len(), out);
        } /* while */

        puts("ERROR: Webserver loop exited, restart it...");
    }
    while(true);
}

By the way, i do not use spawn-fcgi

Greetings,
Simon

    (1-5/5)