2 * A simple FastCGI application example in C++.
\r
4 * $Id: echo-cpp.cpp,v 1.2 2001/11/21 15:31:49 robs Exp $
\r
6 * Copyright (c) 2001 Rob Saccoccio and Chelsea Networks
\r
7 * All rights reserved.
\r
9 * Redistribution and use in source and binary forms, with or without
\r
10 * modification, are permitted provided that the following conditions
\r
13 * 1. Redistributions of source code must retain the above copyright
\r
14 * notice, this list of conditions and the following disclaimer.
\r
15 * 2. Redistributions in binary form must reproduce the above copyright
\r
16 * notice, this list of conditions and the following disclaimer in the
\r
17 * documentation and/or other materials provided with the distribution.
\r
18 * 3. The name of the author may not be used to endorse or promote products
\r
19 * derived from this software without specific prior written permission.
\r
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
\r
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
\r
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
\r
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\r
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
\r
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
35 #include <process.h>
\r
38 extern const char * const * environ;
\r
42 // Maximum number of bytes allowed to be read from stdin
\r
43 static const unsigned long STDIN_MAX = 1000000;
\r
45 static void penv(const char * const * envp)
\r
48 for ( ; *envp; ++envp)
\r
50 cout << *envp << "\n";
\r
55 static long gstdin(FCGX_Request * request, char ** content)
\r
57 char * clenstr = FCGX_GetParam("CONTENT_LENGTH", request->envp);
\r
58 unsigned long clen = STDIN_MAX;
\r
62 clen = strtol(clenstr, &clenstr, 10);
\r
65 cerr << "can't parse \"CONTENT_LENGTH="
\r
66 << FCGX_GetParam("CONTENT_LENGTH", request->envp)
\r
72 // Note that *you* should not read stdin when CONTENT_LENGTH
\r
73 // is missing or unparsable (this is a demo/test program).
\r
75 // *always* put a cap on the amount of data that will be read
\r
76 if (clen > STDIN_MAX) clen = STDIN_MAX;
\r
78 *content = new char[clen];
\r
80 cin.read(*content, clen);
\r
81 clen = cin.gcount();
\r
83 // chew up any remaining stdin - this shouldn't be necessary
\r
84 // but it is because mod_fastcgi doesn't handle it correctly
\r
85 do cin.ignore(1024); while (! cin.eof());
\r
93 long pid = getpid();
\r
95 FCGX_Request request;
\r
98 FCGX_InitRequest(&request, 0, 0);
\r
100 while (FCGX_Accept_r(&request) == 0)
\r
102 fcgi_streambuf fin(request.in);
\r
103 fcgi_streambuf fout(request.out);
\r
104 fcgi_streambuf ferr(request.err);
\r
116 // Although FastCGI supports writing before reading,
\r
117 // many http clients (browsers) don't support it (so
\r
118 // the connection deadlocks until a timeout expires!).
\r
120 unsigned long clen = gstdin(&request, &content);
\r
122 cout << "Content-type: text/html\r\n"
\r
124 "<TITLE>echo-cpp</TITLE>\n"
\r
125 "<H1>echo-cpp</H1>\n"
\r
126 "<H4>PID: " << pid << "</H4>\n"
\r
127 "<H4>Request Number: " << ++count << "</H4>\n";
\r
129 cout << "<H4>Request Environment</H4>\n";
\r
130 penv(request.envp);
\r
132 cout << "<H4>Process/Initial Environment</H4>\n";
\r
135 cout << "<H4>Standard Input - " << clen;
\r
136 if (clen == STDIN_MAX) cout << " (STDIN_MAX)";
\r
137 cout << " bytes</H4>\n";
\r
138 if (clen) cout.write(content, clen);
\r
140 if (content) delete []content;
\r