pickup unistd.h and environ
[catagits/fcgi2.git] / examples / echo-cpp.cpp
CommitLineData
c2a77fd4 1/*\r
2 * A simple FastCGI application example in C++.\r
3 * \r
4c0f03cc 4 * $Id: echo-cpp.cpp,v 1.2 2001/11/21 15:31:49 robs Exp $\r
c2a77fd4 5 * \r
6 * Copyright (c) 2001 Rob Saccoccio and Chelsea Networks\r
7 * All rights reserved.\r
8 * \r
9 * Redistribution and use in source and binary forms, with or without\r
10 * modification, are permitted provided that the following conditions\r
11 * are met:\r
12 * \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
20 * \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
31 */\r
32\r
33#include <stdlib.h>\r
34#ifdef _WIN32\r
35#include <process.h>\r
4c0f03cc 36#else\r
37#include <unistd.h>\r
38extern const char * const * environ;\r
c2a77fd4 39#endif\r
40#include "fcgio.h"\r
41\r
42// Maximum number of bytes allowed to be read from stdin\r
43static const unsigned long STDIN_MAX = 1000000;\r
44\r
45static void penv(const char * const * envp)\r
46{\r
47 cout << "<PRE>\n";\r
48 for ( ; *envp; ++envp) \r
49 {\r
50 cout << *envp << "\n";\r
51 }\r
52 cout << "</PRE>\n";\r
53}\r
54\r
55static long gstdin(FCGX_Request * request, char ** content)\r
56{\r
57 char * clenstr = FCGX_GetParam("CONTENT_LENGTH", request->envp);\r
58 unsigned long clen = STDIN_MAX;\r
59\r
60 if (clenstr)\r
61 {\r
62 clen = strtol(clenstr, &clenstr, 10);\r
63 if (*clenstr)\r
64 {\r
65 cerr << "can't parse \"CONTENT_LENGTH=" \r
66 << FCGX_GetParam("CONTENT_LENGTH", request->envp) \r
67 << "\"\n";\r
68 clen = STDIN_MAX;\r
69 }\r
70 }\r
71\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
74\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
77\r
78 *content = new char[clen];\r
79\r
80 cin.read(*content, clen);\r
81 clen = cin.gcount();\r
82\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
86\r
87 return clen;\r
88}\r
89\r
90int main (void)\r
91{\r
92 int count = 0;\r
93 long pid = getpid();\r
94\r
95 FCGX_Request request;\r
96\r
97 FCGX_Init();\r
98 FCGX_InitRequest(&request, 0, 0);\r
99\r
100 while (FCGX_Accept_r(&request) == 0) \r
101 {\r
102 fcgi_streambuf fin(request.in);\r
103 fcgi_streambuf fout(request.out);\r
104 fcgi_streambuf ferr(request.err);\r
105 \r
106#ifdef _WIN32\r
107 cin = &fin;\r
108 cout = &fout;\r
109 cerr = &ferr;\r
110#else\r
111 cin.rdbuf(&fin);\r
112 cout.rdbuf(&fout);\r
113 cerr.rdbuf(&ferr);\r
114#endif\r
115\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
119 char * content;\r
120 unsigned long clen = gstdin(&request, &content);\r
121\r
122 cout << "Content-type: text/html\r\n"\r
123 "\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
128\r
129 cout << "<H4>Request Environment</H4>\n";\r
130 penv(request.envp);\r
131\r
132 cout << "<H4>Process/Initial Environment</H4>\n";\r
133 penv(environ);\r
134\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
139\r
140 if (content) delete []content;\r
141 }\r
142\r
143 return 0;\r
144}\r