remove bloody CRs
[catagits/fcgi2.git] / examples / echo-cpp.cpp
index 080b72a..a95b685 100644 (file)
-/*\r
- *  A simple FastCGI application example in C++.\r
- *  \r
- *  $Id: echo-cpp.cpp,v 1.4 2001/11/21 20:18:46 robs Exp $\r
- *  \r
- *  Copyright (c) 2001  Rob Saccoccio and Chelsea Networks\r
- *  All rights reserved.\r
- *  \r
- *  Redistribution and use in source and binary forms, with or without\r
- *  modification, are permitted provided that the following conditions\r
- *  are met:\r
- *  \r
- *  1. Redistributions of source code must retain the above copyright\r
- *     notice, this list of conditions and the following disclaimer.\r
- *  2. Redistributions in binary form must reproduce the above copyright\r
- *     notice, this list of conditions and the following disclaimer in the\r
- *     documentation and/or other materials provided with the distribution.\r
- *  3. The name of the author may not be used to endorse or promote products\r
- *     derived from this software without specific prior written permission.\r
- *  \r
- *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
- *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
- *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
- *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include <stdlib.h>\r
-#ifdef _WIN32\r
-#include <process.h>\r
-#else\r
-#include <unistd.h>\r
-extern char ** environ;\r
-#endif\r
-#include "fcgio.h"\r
-\r
-// Maximum number of bytes allowed to be read from stdin\r
-static const unsigned long STDIN_MAX = 1000000;\r
-\r
-static void penv(const char * const * envp)\r
-{\r
-    cout << "<PRE>\n";\r
-    for ( ; *envp; ++envp) \r
-    {\r
-        cout << *envp << "\n";\r
-    }\r
-    cout << "</PRE>\n";\r
-}\r
-\r
-static long gstdin(FCGX_Request * request, char ** content)\r
-{\r
-    char * clenstr = FCGX_GetParam("CONTENT_LENGTH", request->envp);\r
-    unsigned long clen = STDIN_MAX;\r
-\r
-    if (clenstr)\r
-    {\r
-        clen = strtol(clenstr, &clenstr, 10);\r
-        if (*clenstr)\r
-        {\r
-            cerr << "can't parse \"CONTENT_LENGTH=" \r
-                 << FCGX_GetParam("CONTENT_LENGTH", request->envp) \r
-                 << "\"\n";\r
-            clen = STDIN_MAX;\r
-        }\r
-    }\r
-\r
-    // Note that *you* should not read stdin when CONTENT_LENGTH\r
-    // is missing or unparsable (this is a demo/test program).\r
-\r
-    // *always* put a cap on the amount of data that will be read\r
-    if (clen > STDIN_MAX) clen = STDIN_MAX;\r
-\r
-    *content = new char[clen];\r
-\r
-    cin.read(*content, clen);\r
-    clen = cin.gcount();\r
-\r
-    // chew up any remaining stdin - this shouldn't be necessary\r
-    // but is because mod_fastcgi doesn't handle it correctly\r
-    do cin.ignore(1024); while (! cin.eof());\r
-\r
-    return clen;\r
-}\r
-\r
-int main (void)\r
-{\r
-    int count = 0;\r
-    long pid = getpid();\r
-\r
-    FCGX_Request request;\r
-       \r
-    FCGX_Init();\r
-    FCGX_InitRequest(&request, 0, 0);\r
-\r
-    while (FCGX_Accept_r(&request) == 0) \r
-    {\r
-        // Note that the default bufsize (0) will cause the use of iostream\r
-        // methods that require positioning (such as peek(), seek(), \r
-        // unget() and putback()) to fail (in favour of more efficient IO).\r
-        fcgi_streambuf fin(request.in);\r
-        fcgi_streambuf fout(request.out);\r
-        fcgi_streambuf ferr(request.err);\r
-\r
-#ifdef _WIN32\r
-        cin = &fin;\r
-        cout = &fout;\r
-        cerr = &ferr;\r
-#else\r
-        cin.rdbuf(&fin);\r
-        cout.rdbuf(&fout);\r
-        cerr.rdbuf(&ferr);\r
-#endif\r
-\r
-        // Although FastCGI supports writing before reading,\r
-        // many http clients (browsers) don't support it (so  \r
-        // the connection deadlocks until a timeout expires!).\r
-        char * content;\r
-        unsigned long clen = gstdin(&request, &content);\r
-\r
-        cout << "Content-type: text/html\r\n"\r
-                "\r\n"\r
-                "<TITLE>echo-cpp</TITLE>\n"\r
-                "<H1>echo-cpp</H1>\n"\r
-                "<H4>PID: " << pid << "</H4>\n"\r
-                "<H4>Request Number: " << ++count << "</H4>\n";\r
-\r
-        cout << "<H4>Request Environment</H4>\n";\r
-        penv(request.envp);\r
-\r
-        cout << "<H4>Process/Initial Environment</H4>\n";\r
-        penv(environ);\r
-\r
-        cout << "<H4>Standard Input - " << clen;\r
-        if (clen == STDIN_MAX) cout << " (STDIN_MAX)";\r
-        cout << " bytes</H4>\n";\r
-        if (clen) cout.write(content, clen);\r
-\r
-        if (content) delete []content;\r
-\r
-        // If the output streambufs had non-zero bufsizes and\r
-        // were constructed outside of the accept loop (i.e.\r
-        // their destructor won't be called here), they would\r
-        // have to be flushed here.\r
-    }\r
-\r
-    return 0;\r
-}\r
+/*
+ *  A simple FastCGI application example in C++.
+ *  
+ *  $Id: echo-cpp.cpp,v 1.5 2001/11/21 21:15:36 robs Exp $
+ *  
+ *  Copyright (c) 2001  Rob Saccoccio and Chelsea Networks
+ *  All rights reserved.
+ *  
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *  
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#ifdef _WIN32
+#include <process.h>
+#else
+#include <unistd.h>
+extern char ** environ;
+#endif
+#include "fcgio.h"
+
+// Maximum number of bytes allowed to be read from stdin
+static const unsigned long STDIN_MAX = 1000000;
+
+static void penv(const char * const * envp)
+{
+    cout << "<PRE>\n";
+    for ( ; *envp; ++envp) 
+    {
+        cout << *envp << "\n";
+    }
+    cout << "</PRE>\n";
+}
+
+static long gstdin(FCGX_Request * request, char ** content)
+{
+    char * clenstr = FCGX_GetParam("CONTENT_LENGTH", request->envp);
+    unsigned long clen = STDIN_MAX;
+
+    if (clenstr)
+    {
+        clen = strtol(clenstr, &clenstr, 10);
+        if (*clenstr)
+        {
+            cerr << "can't parse \"CONTENT_LENGTH=" 
+                 << FCGX_GetParam("CONTENT_LENGTH", request->envp) 
+                 << "\"\n";
+            clen = STDIN_MAX;
+        }
+    }
+
+    // Note that *you* should not read stdin when CONTENT_LENGTH
+    // is missing or unparsable (this is a demo/test program).
+
+    // *always* put a cap on the amount of data that will be read
+    if (clen > STDIN_MAX) clen = STDIN_MAX;
+
+    *content = new char[clen];
+
+    cin.read(*content, clen);
+    clen = cin.gcount();
+
+    // chew up any remaining stdin - this shouldn't be necessary
+    // but is because mod_fastcgi doesn't handle it correctly
+    do cin.ignore(1024); while (! cin.eof());
+
+    return clen;
+}
+
+int main (void)
+{
+    int count = 0;
+    long pid = getpid();
+
+    FCGX_Request request;
+       
+    FCGX_Init();
+    FCGX_InitRequest(&request, 0, 0);
+
+    while (FCGX_Accept_r(&request) == 0) 
+    {
+        // Note that the default bufsize (0) will cause the use of iostream
+        // methods that require positioning (such as peek(), seek(), 
+        // unget() and putback()) to fail (in favour of more efficient IO).
+        fcgi_streambuf fin(request.in);
+        fcgi_streambuf fout(request.out);
+        fcgi_streambuf ferr(request.err);
+
+#ifdef _WIN32
+        cin = &fin;
+        cout = &fout;
+        cerr = &ferr;
+#else
+        cin.rdbuf(&fin);
+        cout.rdbuf(&fout);
+        cerr.rdbuf(&ferr);
+#endif
+
+        // Although FastCGI supports writing before reading,
+        // many http clients (browsers) don't support it (so  
+        // the connection deadlocks until a timeout expires!).
+        char * content;
+        unsigned long clen = gstdin(&request, &content);
+
+        cout << "Content-type: text/html\r\n"
+                "\r\n"
+                "<TITLE>echo-cpp</TITLE>\n"
+                "<H1>echo-cpp</H1>\n"
+                "<H4>PID: " << pid << "</H4>\n"
+                "<H4>Request Number: " << ++count << "</H4>\n";
+
+        cout << "<H4>Request Environment</H4>\n";
+        penv(request.envp);
+
+        cout << "<H4>Process/Initial Environment</H4>\n";
+        penv(environ);
+
+        cout << "<H4>Standard Input - " << clen;
+        if (clen == STDIN_MAX) cout << " (STDIN_MAX)";
+        cout << " bytes</H4>\n";
+        if (clen) cout.write(content, clen);
+
+        if (content) delete []content;
+
+        // If the output streambufs had non-zero bufsizes and
+        // were constructed outside of the accept loop (i.e.
+        // their destructor won't be called here), they would
+        // have to be flushed here.
+    }
+
+    return 0;
+}