Boost logo

Boost-Commit :

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_;
+};


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk