Re: help needed...
Tom Bowden <[email protected]> Sun, 13 Mar 2011 15:17:13 -0500
| Newsgroups | gmane.comp.web.fastcgi.devel |
|---|---|
| Message-ID | <[email protected]> |
A lot of my example is cut-pasted from the real examples :)
The parts that confused me for a while included (and why I did my own
example quotes):
- assignment of streams to streambufs so that you wouldn't have
to do the PutStr() functions and really could go straight to stdout;
- how to make the socket non-blocking so I can select on multiple
sockets and STILL process input, and
- the difference between FCGI_* and FCGX_*.
Thankfully those were all areas that I could create cookie cutter
routines for and forget.
In my experience those areas have always been complex - regardless of
what you're programming in... so it didn't seem unusual that I had to
deal with it.
And that is my ultimate metric: is it complex in the usual places.
Tom
On Mar 13, 2011, at 2:22 PM, David Birnbaum wrote:
> Tom,
>
> I think you have it right.
>
> I pretty much use FastCGI exclusively within the Perl paradigm, so
> I can't comment about the C portion, but yes, you have to use the
> FastCGI routines to read the environment and read/write to the
> streams. I thought there were some examples in the Dev kit, but
> your examples look great too.
>
> Cheers,
>
> David.
>
> -----
>
> On 3/13/11 6:39 AM, Tom Bowden wrote:
>> Of course -- I am operating under the assumption that the way I am
>> using FastCGI is right; and that my understanding of its
>> architecture is correct... neither of which may be true
>> statements - but at least it works for me :)
>>
>>
>> Tom
>>
>>
>> On Mar 11, 2011, at 8:12 PM, Tom Bowden wrote:
>>
>>> Speaking as a recent convert (of about a year or so) I would
>>> certainly hope that you don't lose hope with FastCgi.
>>>
>>> At first blush -- it isn't stdout that you're supposed to write
>>> to...
>>>
>>> Some tips/pointers that I have gleaned from this newsgroup and
>>> the examples in the code -- along with how I use fastcgi:
>>>
>>> I have applications that must select on sockets from postgres,
>>> inotifyd, and fastcgi -- so I can't use fcgi_* . So I use the
>>> thread-safe version of FCGX functions.
>>> I also have to play around a lot with headers -- to pass cookies,
>>> custom status codes, etc. So I create a number of ostringstream
>>> objects, write to them - and then dump them out as I need to with
>>> FCGX_PutStr().
>>>
>>> What helped me the most -- with the paradigm of fastcgi -- is
>>> that I'm not really receiving from stdin and stdout (anonymous
>>> pipes associated with program). Instead I am talking with
>>> sockets that are hidden by the API.
>>> Here's some snippets.. FWIW. If more complete examples are
>>> needed I can post them.,... but perhaps this is enough.
>>>
>>>
>>>
>>> In my startup of an object that communicates:
>>> void IDOTicket::startup()
>>> {
>>> FCGX_Init();
>>> FCGX_InitRequest(&_request, 0, 0);
>>> fcntl(FCGI_LISTENSOCK_FILENO, F_SETFL, O_NONBLOCK);
>>> _cin_streambuf = cin.rdbuf();
>>> _cout_streambuf = cout.rdbuf();
>>> _cerr_streambuf = cerr.rdbuf();
>>>
>>> }
>>>
>>> When I receive notification that there is a request to process:
>>>
>>> int IDOTicket::process_fastcgi_environment(Json::Value& pc)
>>> {
>>> int fcgx_method = FCGX_UNDEFINED;
>>> if (FCGX_Accept_r(&_request) != 0) {
>>> .. do stuff here ..
>>> }
>>>
>>>
>>>
>>>
>>> When I read from the socket:
>>>
>>> long IDOTicket::read_xml_request(std::string& content_string)
>>> {
>>> char * clenstr = FCGX_GetParam("CONTENT_LENGTH",
>>> _request.envp);
>>> unsigned long clen = STDIN_MAX;
>>> if (clenstr) {
>>> clen = strtol(clenstr, &clenstr, 10);
>>> if (*clenstr) {
>>> clen = STDIN_MAX;
>>> }
>>>
>>> // *always* put a cap on the amount of data that will
>>> be read
>>> if (clen > STDIN_MAX) {
>>> clen = STDIN_MAX;
>>> }
>>>
>>> content_string.resize( clen );
>>> std::string input_str;
>>> FCGX_GetStr((char*)content_string.data(), clen,
>>> _request.in);
>>> _ticket_interface_object->input(xmlParseMemory
>>> ( content_string.c_str(), content_string.size()));
>>>
>>> } else {
>>> // *never* read stdin when CONTENT_LENGTH is missing or
>>> unparsable
>>> content_string.empty();
>>> clen = 0;
>>> }
>>>
>>> // Chew up any remaining stdin - this shouldn't be necessary
>>> // but is because mod_fastcgi doesn't handle it correctly.
>>> // ignore() doesn't set the eof bit in some versions of
>>> glibc++
>>> // so use gcount() instead of eof()...
>>> do {
>>> cin.ignore(1024);
>>> } while (cin.gcount() == 1024);
>>>
>>> if ( content_string.empty() ) {
>>> return 0L;
>>> } else {
>>> return content_string.size();
>>> }
>>> }
>>>
>>> WHEN I READ An environmental variable passed from apache, created
>>> by the fastcgi manager, and then consumed in my app:
>>>
>>> char* const* envp = _request.envp;
>>>
>>> for ( envp = _request.envp; *envp; ++envp) {
>>> Json::Value p_context = Json::Value(objectValue);
>>> std::string name;
>>> std::string value;
>>> if ( IDOPattern( PCRE_POST_REQUEST_METHOD)->PartialMatch
>>> ( (*envp),&name, &value ) ) {
>>> fcgx_method = FCGX_POST;
>>> } else if ( IDOPattern( PCRE_GET_REQUEST_METHOD)-
>>> >PartialMatch( (*envp),&name, &value ) ) {
>>> fcgx_method = FCGX_GET;
>>> } else if ( IDOPattern( PCRE_QUERY_STRING)->PartialMatch
>>> ( (*envp), &name, &value) ) {
>>> std::string param_name;
>>> std::string param_value;
>>> std::string param_post;
>>> while ( IDOPattern( PCRE_SERIALIZED_FORM)-
>>> >PartialMatch( value.c_str(), ¶m_name, ¶m_value,
>>> ¶m_post) ) {
>>> p_context[HAS_NAME_OF] = param_name;
>>> p_context[HAS_TYPE_OF] = param_name;
>>> p_context[HAS_VALUE_OF] = param_value;
>>> pc.append(p_context);
>>> value = param_post;
>>> }
>>> }
>>> }
>>>
>>>
>>>
>>> WHEN I am writing to the socket:
>>>
>>> if ( data_stream.str().size() < 1 ) {
>>> http_stream << "Content-Length: " <<
>>> content_stream.str().size() << std::endl;
>>> } else {
>>> content_stream << data_stream.str() << std::endl;
>>> http_stream << "Content-Length: " <<
>>> content_stream.str().size() << std::endl;
>>> }
>>> header_stream << std::endl;
>>>
>>> if ( http_stream.str().size() > 0) {
>>> FCGX_PutStr(http_stream.str().c_str(), http_stream.str
>>> ().size(), _request.out);
>>> }
>>> if ( header_stream.str().size() > 0) {
>>> FCGX_PutStr(header_stream.str().c_str(),
>>> header_stream.str().size(), _request.out);
>>> }
>>> if ( content_stream.str().size() > 0) {
>>> FCGX_PutStr(content_stream.str().c_str(),
>>> content_stream.str().size(), _request.out);
>>> }
>>> }
>>>
>>>
>>> When I am finished with the socket/call of a single request:
>>>
>>> FCGX_Finish_r(&_request);
>>>
>>>
>>>
>>> AS FOR LINKING:
>>>
>>> Snippets from my Makefile
>>>
>>> INCS += -I/usr/include/fastcgi
>>>
>>> LIBS +=-lxslt
>>> LIBS +=-lfcgi++
>>> LIBS += $(PCRE_LIB_OPS) -lpcrecpp $(CURL_LIB_OPS) $
>>> (READLINE_LIB_OPS) \
>>> -L/usr/lib -lpthread -lm -ldl -lxml2 -lz
>>>
>>>
>>> On Mar 11, 2011, at 7:35 AM, Majed Al-Dolaimi wrote:
>>>
>>>> Hi guys,
>>>> I am a bit disappointed in the FastCGI documentation, as many
>>>> other people are. However I am not losing hope with it.
>>>>
>>>> 1 - I installed the apache mod_fcgid from SUSE website and it
>>>> seems to be working..
>>>> 2 - I configured, compiled the fcgi-(*-*).tar.gz and added the
>>>> libs to the /usr/lib.
>>>> 3 - Added the -Ifcgi++ (or -Ifcgi ) library to my Makefile... my
>>>> compiler is not complaining
>>>> 4 - Added the FCGI_Accept() loop to my main routing in my c++
>>>> app...
>>>>
>>>> RESULTS: When I run the whole thing ...
>>>> 5 - my app runs (it shows on the process monitor as a sleeping
>>>> process) and does not stop immediately which fine and dandy
>>>> 6 - I only get a blank page in the browser. Even an error
>>>> message from my WWW server does not show up.
>>>> I tried flushing the std::cout as well as writing to stdout file
>>>> descrptier then flush it... nothing shows up on the browser
>>>> screen..
>>>>
>>>> What I could not understand is making sure the linker searches
>>>> for the BSD socket library. Since the ldconfig did not complain,
>>>> I assumed it found it, right?
>>>>
>>>> Your help will pay back to fastcgi... so please help me out..
>>>>
>>>> Majed Dolaimi
>>>> C++/ web developer
>>>> _______________________________________________
>>>> FastCGI-developers mailing list
>>>> FastCGI-developers-xGejAJT2w6xVgU18Zptdi0EOCMrvLtNR@public.gmane.org
>>>> http://mailman.pins.net/mailman/listinfo.cgi/fastcgi-developers
>>>
>>
>> _______________________________________________
>> FastCGI-developers mailing list
>> FastCGI-developers-xGejAJT2w6xVgU18Zptdi0EOCMrvLtNR@public.gmane.org
>> http://mailman.pins.net/mailman/listinfo.cgi/fastcgi-developers
> _______________________________________________
> FastCGI-developers mailing list
> FastCGI-developers-xGejAJT2w6xVgU18Zptdi0EOCMrvLtNR@public.gmane.org
> http://mailman.pins.net/mailman/listinfo.cgi/fastcgi-developers