$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: lists.drrngrvy_at_[hidden]
Date: 2008-04-19 09:25:09
Author: drrngrvy
Date: 2008-04-19 09:25:08 EDT (Sat, 19 Apr 2008)
New Revision: 44574
URL: http://svn.boost.org/trac/boost/changeset/44574
Log:
Small fixes to examples.
Added:
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/server.hpp   (contents, props changed)
Text files modified: 
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/Jamfile.v2            |     2                                         
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/doc.qbk          |     4                                         
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/main.cpp     |    19 ++-                                     
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/main.cpp |   191 ++++++++++----------------------------- 
   4 files changed, 64 insertions(+), 152 deletions(-)
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/Jamfile.v2	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/Jamfile.v2	2008-04-19 09:25:08 EDT (Sat, 19 Apr 2008)
@@ -38,6 +38,8 @@
     <location>$(fcgi-bin)
   ;
 
+alias install : cgi//install acgi//install fcgi//install ;
+
 explicit cgi-install  ;
 explicit acgi-install ;
 explicit fcgi-install ;
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/doc.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/doc.qbk	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/doc.qbk	2008-04-19 09:25:08 EDT (Sat, 19 Apr 2008)
@@ -1,6 +1,10 @@
 
 [section aCGI Examples]
 
+Things in the `acgi` namespace are 'Asio-enabled' versions of those in the `cgi` namespace. The aCGI (*a* for asynchronous) parts of the library are especially useful if you are writing long-running CGI applications that could benefit from using asynchronous I/O or asynchronous event dispatching.
+
+If not, there may be a small speed/size gain to be had from the plain CGI components.
+
 [include hello_world/doc.qbk]
 
 [include echo/doc.qbk]
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/main.cpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/main.cpp	2008-04-19 09:25:08 EDT (Sat, 19 Apr 2008)
@@ -19,25 +19,26 @@
 
 using namespace boost::cgi;
 
+//
 // This function writes the title and map contents to the ostream in an
 // HTML-encoded format (to make them easier on the eye).
+//
 template<typename OStreamT, typename MapT>
 void show_map_contents(OStreamT& os, MapT& m, const std::string& title)
 {
   os<< "<h3>" << title << "</h3>";
-  if (m.empty()) os<< "NONE<br />";
-  for (typename MapT::iterator i = m.begin(); i != m.end(); ++i)
-  {
-    os<< "<b>" << i->first << "</b> = <i>" << i->second << "</i><br />";
-  }
+  
+  if (m.empty())
+    os<< "NONE<br />";
+  else
+    for (typename MapT::const_iterator i = m.begin(); i != m.end(); ++i)
+      os<< "<b>" << i->first << "</b> = <i>" 
+                 << i->second << "</i><br />";
 }
 
 int main()
 {
-  request req;
-
-  req.load(true); // The 'true' means parse STDIN data too.
-
+  request req; // A basic CGI request auto-parses everything (including POST data).
   response resp;
 
   show_map_contents(resp, req[env_data], "Environment Variables");
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/main.cpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/main.cpp	2008-04-19 09:25:08 EDT (Sat, 19 Apr 2008)
@@ -20,23 +20,16 @@
 // This is very similar to the fcgi_echo example.
 //
 
-#include <fstream>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/program_options/environment_iterator.hpp>
-
 #include <boost/cgi/fcgi.hpp>
+#include "server.hpp"
 
 using namespace std;
 using namespace boost::fcgi;
 
-// This is a file to put internal logging info into
-#define LOG_FILE "/var/www/log/fcgi_server1.txt"
-
 // This function writes the title and map contents to the ostream in an
 // HTML-encoded format (to make them easier on the eye).
-template<typename Map, typename OStream>
-void format_map(Map& m, OStream& os, const std::string& title)
+template<typename OStream, typename Map>
+void format_map(OStream& os, Map& m, const std::string& title)
 {
   os<< "<h2>" << title << "</h2>";
   if (m.empty()) os<< "NONE<br />";
@@ -47,150 +40,62 @@
   }
 }
 
-/// The handle_request member function is used to handle requests.
-/**
- * A struct is used here just so a single log file can be shared between
- * requests. Note that access to the log file isn't synchronised (this doesn't
- * matter with this example).
- */
-struct request_handler
-{
-  request_handler(const std::string& file_name)
-    : log_(file_name.c_str())
-  {
-    if (!log_)
-    {
-      std::cerr<< "[fcgi] Couldn't open file: \"" LOG_FILE "\"." << endl;
-      throw std::runtime_error("Couldn't open log file");
-    }
-
-    log_<< boost::posix_time::second_clock::local_time() << endl;
-  }
-  
-  int handle_request(fcgi::request& req, boost::system::error_code& ec)
-  {
-    std::ofstream log_(LOG_FILE, std::ios::app);
-    //log_<< "Handling request" << endl
-    //    << "QUERY_STRING := " << req.query_string() << std::endl;
-
-    // Construct a `response` object (makes writing/sending responses easier).
-    response resp;
-
-    // Responses in CGI programs require at least a 'Content-type' header. The
-    // library provides helpers for several common headers:
-    resp<< content_type("text/html")
-    // You can also stream text to a response object. 
-        << "Hello there, universe!<p />";
-
-    // Use the function defined above to show some of the request data.
-    format_map(req.env(), resp, "Environment Variables");
-    format_map(req.GET(), resp, "GET Variables");
-    format_map(req.cookie(), resp, "Cookie Variables");
-
-    // Response headers can be added at any time before send/flushing it:
-    resp<< "<content-length == " << content_length(resp.content_length())
-        << content_length(resp.content_length());
-
-    //log_<< "Handled request, handling another." << std::endl;
-
-    // This funky macro finishes up:
-    return_(resp, req, 0);
-    // It is equivalent to the below, where the third argument is represented by
-    // `program_status`:
-    //
-    // resp.send(req.client());
-    // req.close(resp.status(), program_status);
-    // return program_status;
-    //
-    // Note: in this case `program_status == 0`.
-  }
-
-private:
-  std::ofstream log_;
-};
-
-
-/// The server is used to abstract away protocol-specific setup of requests.
-/**
- * This server only works with FastCGI, but as you can see in the
- * request_handler::handle_request() function above, the request in there could
- * just as easily be a cgi::request.
- *
- * Later examples will demonstrate making protocol-independent servers.
- * (**FIXME**)
- */
-class server
+/// The handle_request function handles a single request.
+int handle_request(fcgi::request& req, boost::system::error_code& ec)
 {
-public:
-  typedef fcgi::request                         request_type;
-  typedef boost::function<
-            int ( request_type&
-                , boost::system::error_code&)
-          >                                     function_type;
-
-  server(const function_type& handler)
-    : handler_(handler)
-    , service_()
-    , acceptor_(service_)
-  {}
+  // Construct a `response` object (makes writing/sending responses easier).
+  response resp;
 
-  int run()
-  {
-    // Create a new request (on the heap - uses boost::shared_ptr<>).
-    request_type::pointer new_request = request_type::create(service_);
-    // Add the request to the set of existing requests.
-    requests_.insert(new_request);
-    
-    int ret(0);
-    for (;;)
-    {
-      boost::system::error_code ec;
-
-      acceptor_.accept(*new_request, ec);
-
-      if (ec) 
-      {
-        std::cerr<< "Error accepting: " << ec.message() << std::endl;
-        return 5;
-      }
-  
-      // Load in the request data so we can access it easily.
-      new_request->load(ec, true); // The 'true' means read and parse POST data.
-
-      ret = handler_(*new_request, ec);
-
-      if (ret)
-        break;
-    }
-    return ret;
-  }
-
-private:
-  function_type handler_;
-  fcgi::service service_;
-  fcgi::acceptor acceptor_;
-  std::set<request_type::pointer> requests_;
-};
+  // Responses in CGI programs require at least a 'Content-type' header. The
+  // library provides helpers for several common headers:
+  resp<< content_type("text/html")
+      // You can also stream text to a response object.
+      << "Hello there, universe!<p />";
+
+  // Use the function defined above to show some of the request data.
+  format_map(resp, req[env_data],    "Environment Variables");
+  format_map(resp, req[get_data],    "GET Variables");
+  format_map(resp, req[cookie_data], "Cookie Variables");
+   // Response headers can be added at any time before send/flushing it:
+  resp<< "<h3>Response Length</h3>" << resp.content_length()
+      // response::content_length() returns the length of the *body*
+      // of the response (ie. not including the headers).
+      << content_length(resp.content_length());
+
+  // This funky macro finishes up:
+  return_(resp, req, 0);
+  // It is equivalent to the below, where the third argument is represented by
+  // `program_status`:
+  //
+  // resp.send(req.client());
+  // req.close(resp.status(), program_status);
+  // return program_status;
+  //
+  // Note: in this case `program_status == 0`.
+}
 
+///////////////////////////////////////////////////////////
 int main()
+///////////////////////////////////////////////////////////
 try
 {
-  request_handler rh(LOG_FILE);
-
-  server s(boost::bind(&request_handler::handle_request
-                      , &rh, _1, _2)
-          );
+  server4 s(&handle_request);
 
   return s.run();
-  
-}catch(boost::system::system_error& se){
-  cerr<< "[fcgi] System error: " << se.what() << endl;
+
+}
+catch(boost::system::system_error& se){
+  cerr<< "[fcgi] System error (" << se.code() << "): "
+      << se.what() << endl;
   return 1313;
-}catch(exception& e){
+}
+catch(exception& e){
   cerr<< "[fcgi] Exception: " << e.what() << endl;
   return 666;
-}catch(...){
-  cerr<< "[fcgi] Uncaught exception!" << endl;
+}
+catch(...){
+  cerr<< "[fcgi] Unknown exception!" << endl;
   return 667;
 }
 //]
+
Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/server.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/server.hpp	2008-04-19 09:25:08 EDT (Sat, 19 Apr 2008)
@@ -0,0 +1,81 @@
+//                 -- server1/server.hpp --
+//
+//           Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+//
+
+// standard includes
+#include <set>
+// external includes
+#include <boost/function.hpp>
+// internal includes
+#include <boost/cgi/fcgi.hpp>
+
+/// The server is used to abstract away protocol-specific setup of requests.
+/**
+ * This server only works with FastCGI. Later examples will show you how to
+ * make a protocol-independent server.
+ *
+ * Later examples will demonstrate making protocol-independent servers.
+ * (**FIXME**)
+ */
+class server4
+{
+public:
+  typedef boost::fcgi::request                  request_type;
+  typedef boost::function<
+            int ( request_type&
+                , boost::system::error_code&)
+          >                                     function_type;
+
+  server4(const function_type& handler)
+    : handler_(handler)
+    , service_()
+    , acceptor_(service_)
+  {}
+
+  int run()
+  {
+    // Create a new request (on the heap - uses boost::shared_ptr<>).
+    request_type::pointer new_request = request_type::create(service_);
+    // Add the request to the set of existing requests.
+    requests_.insert(new_request);
+
+    int ret(0);
+    for (;;)
+    {
+      boost::system::error_code ec;
+
+      acceptor_.accept(*new_request, ec);
+
+      if (ec)
+      {
+        std::cerr<< "Error accepting: " << ec.message() << std::endl;
+        return 5;
+      }
+
+      // Load in the request data so we can access it easily.
+      new_request->load(ec, true); // The 'true' means read and parse POST data.
+
+      // Call the request handler and capture the result of handling the request.
+      ret = handler_(*new_request, ec);
+
+      // A non-zero return value indicates an error.
+      // Note: bailing out here isn't strictly necessary, but easier and safer,
+      //       given the current state of the library.
+      if (ret)
+        break;
+    }
+    return ret;
+  }
+
+private:
+  function_type handler_;
+  boost::fcgi::service service_;
+  boost::fcgi::acceptor acceptor_;
+  std::set<request_type::pointer> requests_;
+};