Boost logo

Boost-Commit :

From: lists.drrngrvy_at_[hidden]
Date: 2008-03-29 14:40:42


Author: drrngrvy
Date: 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
New Revision: 43936
URL: http://svn.boost.org/trac/boost/changeset/43936

Log:
Merged revisions 43919-43935 via svnmerge from
https://svn.boost.org/svn/boost/sandbox/SOC/2007/cgi/trunk

........
  r43933 | drrngrvy | 2008-03-29 18:31:19 +0000 (Sat, 29 Mar 2008) | 1 line
  
  Better docs.
........
  r43934 | drrngrvy | 2008-03-29 18:35:24 +0000 (Sat, 29 Mar 2008) | 1 line
  
  Added documentation to the examples.
........
  r43935 | drrngrvy | 2008-03-29 18:36:55 +0000 (Sat, 29 Mar 2008) | 1 line
  
  Modify project-root.jam to allow user to set htdocs directory (for amortization example files).
........

Added:
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/amortization/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/amortization/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/echo/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/echo/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/hello_world/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/hello_world/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/echo/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/hello_world/
      - copied from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/hello_world/Jamfile.v2
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/hello_world/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/hello_world/main.cpp
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/main.cpp
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/amortization/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/echo/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/echo/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server1/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server2/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server2/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server3/
      - copied from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server3/
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server3/Jamfile.v2
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server3/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server3/doc.qbk
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server3/doc.qbk
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server3/main.cpp
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server3/main.cpp
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server4/
      - copied from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server4/
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server4/Jamfile.v2
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server4/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server4/main.cpp
      - copied unchanged from r43935, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server4/main.cpp
Removed:
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/servers/
Properties modified:
   sandbox/SOC/2007/cgi/branches/release/ (props changed)
Text files modified:
   sandbox/SOC/2007/cgi/branches/release/boost/cgi/response.hpp | 1
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/Jamfile.v2 | 23 ++++++-----
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/acknowledgements.qbk | 35 ++++++++++++++++--
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/cgi.qbk | 10 ++--
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/future_development.qbk | 28 ++------------
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/introduction.qbk | 24 +++++++++---
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/preface.qbk | 42 ++++++++++++++++++----
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/user_guide.qbk | 4 -
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/user_guide/examples.qbk | 75 ----------------------------------------
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/amortization/main.cpp | 40 ++++++++++++--------
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/echo/main.cpp | 48 +++++++++++++++----------
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/hello_world/main.cpp | 4 ++
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/echo/main.cpp | 16 ++++----
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/amortization/main.cpp | 6 ++
   sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server2/main.cpp | 71 ++++++++++++-------------------------
   sandbox/SOC/2007/cgi/branches/release/project-root.jam | 39 ++++++++++++++++++++
   16 files changed, 237 insertions(+), 229 deletions(-)

Modified: sandbox/SOC/2007/cgi/branches/release/boost/cgi/response.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/boost/cgi/response.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/boost/cgi/response.hpp 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -95,6 +95,7 @@
       ostream_.clear();
       headers_.clear();
       headers_terminated_ = false;
+ //buffer_->consume(
     }
 
     /// Return the response to the 'just constructed' state.

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/Jamfile.v2 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -11,32 +11,35 @@
 import doxygen ;
 
 # compile the doxygen sources here
-#doxygen cgi_dox
-# :
+doxygen cgi_dox
+ :
 # [ glob-tree ../../../boost/cgi/*.hpp : .svn ]
 # [ glob-tree ../../../boost/libs/cgi/src/*.cpp : .svn ]
 
-# [ glob ../../../boost/cgi/*.hpp ]
+ [ glob ../../../boost/cgi/*.hpp ]
+ [ glob ../../../boost/cgi/fcgi*.hpp ]
+ [ glob ../../../boost/cgi/acgi*.hpp ]
+ [ glob ../../../boost/cgi/cgi*.hpp ]
 # [ glob ../../../boost/cgi/gateway_impl/*.hpp ]
 # [ glob ../../../boost/cgi/gateway_service/*.hpp ]
-# [ glob ../../../boost/cgi/http/*.hpp ]
+ [ glob ../../../boost/cgi/http/*.hpp ]
 # [ glob ../../../boost/cgi/connections/*.hpp ]
 # [ glob ../../../boost/cgi/request_impl/*.hpp ]
 # [ glob ../../../boost/cgi/request_service/*.hpp ]
-# :
+ :
 # <doxygen:param>HIDE_UNDOC_MEMBERS=NO
-# <doxygen:param>EXTRACT_PRIVATE=NO
+ <doxygen:param>EXTRACT_PRIVATE=NO
 # #<doxygen:param>EXTRACT_ALL=YES
-# <doxygen:param>SEARCH_INCLUDES=YES
+ <doxygen:param>SEARCH_INCLUDES=YES
 # <doxygen:param>INCLUDE_PATH=$(BOOST_ROOT)
-# ;
+ ;
 
 xml cgi_xml : src/cgi.qbk ;
 
 boostbook standalone
   :
     cgi_xml
-# cgi_dox
+ cgi_dox
   :
     <doxygen.processor>doxproc
     <doxygen.doxproc.index>no
@@ -49,7 +52,7 @@
     # the depth (of sub-pages) the TOC shows
     <xsl:param>toc.max.depth=1
     # Path to the stylesheet
- <xsl:param>html.stylesheet=../../../../../../../../boost/trunk/doc/html/boostbook.css
+ <xsl:param>html.stylesheet=../../../../../../boost/trunk/doc/html/boostbook.css
  
     #
     <xsl:param>toc.section.depth=2

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/acknowledgements.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/acknowledgements.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/acknowledgements.qbk 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -7,14 +7,39 @@
 
 [section Acknowledgements]
 
-Provided courtesy of the Google Summer of Code (GSoC '08)!
+The library in its current form was started as part of the Google Summer of Code (GSoC '07) - in my case a union of [@http://code.google.com/soc Google] collaborating with [@http://boost.org Boost]!
 
-Christopher Kohlhoff: for crafting Boost.Asio, which does most of the hard stuff. Chris mentored me through the GSoC (no mean feat!), without which this library would not be in your hands.
+People involved in the development of this library:
 
-Phil Endecott: for offering use-cases and encouragement at the start of the GSoC and for coming up with many further suggestions (such as the Client concept) in the months since.
+* [*Christopher Kohlhoff]: for crafting __asio__, which does most of the hard stuff. Chris mentored me through the GSoC (no mean feat!), without which this library would be neither in your hands, nor modelled the way it is.
 
-The Boost mailing lists: for so many deeply critical and objective comments about the library. :) That, is a relentless and ['Good Thing].
+* [*Phil Endecott]: for offering use-cases and encouragement at the start of the GSoC and for coming up with many further suggestions (such as the Client concept) in the months since.
 
-[-forgetting everyone's names:] Jeff Dunlap
+* [*Peter Simons]: His FastCGI library [@http://cryp.to/libfastcgi libfastcgi] provided initial motivation for this library. Also his article [@http://cryp.to/publications/fastcgi/ "FastCGI - The Forgotten Treasure"] is an good read for those not sold on FastCGI.
+
+Also many thanks to:
+
+* [*Jeff Dunlap]: for help with testing and for pushing the idea of supporting HTML templates. Jeff provided an online version of the amortization example which I aimed to replicate using this library and Google.cTemplate.
+
+* [*Jeff Garland]: for organising access to Boost's SVN repo, being involved in early discussion and probably being involved in my SoC application having any chance. :)
+
+* [*Christian Henning]: for help testing early code.
+
+The [*Boost mailing lists]: for so many helpful and objective comments about the library.
+
+Discussions on the Boost lists included:
+
+* *Martin Wille*
+* *Mathias Gaunard*
+* *Peter Foley*
+* *'Jose'*
+* *'Shams'*
+* *Peter Dimov*
+* *Simon Richter*
+* *Cris Frey*
+* *Sohail Somani*
+* *Jean-Christophe Roux*
+
+[-forgetting everyone's names:] Apologies to anyone missed... tell me, please!
 
 [endsect]

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/cgi.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/cgi.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/cgi.qbk 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -40,10 +40,10 @@
 [def __tutorial__ [link boost.cgi.tutorial tutorial]]
 [def __reference__ [link /doc/html/cgi/reference.html reference]]
 
-[def __current_branch__ http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/acceptor_work]
+[def __current_branch__ http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/release]
 
-[def __examples__ [@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example examples]]
-[def __amort_example__ [@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization Amortization]]
+[def __examples__ [@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/release/libs/cgi/example examples]]
+[def __amort_example__ [@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/amortization Amortization]]
 
 
 [def __GET__ `GET` ]
@@ -52,7 +52,7 @@
 [def __PUT__ `PUT` ]
 
 
-[def __Service__ [@http://asio.sourceforge.net/boost_asio_0_3_8/libs/asio/doc/html/boost_asio/reference/Service.html Service]]
+[def __Service__ [@http://asio.sourceforge.net/boost_asio_0_3_9/libs/asio/doc/html/boost_asio/reference/Service.html Service]]
 
 [/def __boost_thread__ #link#to#boost#thread#docs#]
 [/def __IoService__ #link#to#io#service#docs#]
@@ -117,4 +117,4 @@
 
 [include:server_support user_guide/server_support.qbk]
 
-[/include acknowledgements.qbk]
+[include acknowledgements.qbk]

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/future_development.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/future_development.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/future_development.qbk 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -13,13 +13,13 @@
 
 [h4 SCGI support.]
 
-Due to configuration issues, this isn't functional yet.
+I haven't managed to get apache/lighttpd configured properly for SCGI, so this isn't functional yet.
 
 [h4 FastCGI support.]
 
 FastCGI support is essential to any modern CGI library. There is currently ['no] known FastCGI library for C or C++ that aims to implement the complete [@http://www.fastcgi.com/devkit/doc/fcgi-spec.html FastCGI 1.0] specification. Providing support for multiplexing FastCGI daemons is one of this library's major goals.
 
-There are a couple of issues that have yet to be worked out, but in general the new framework is known to 'fit' with all the details of FastCGI and should lend itself to an efficient implementation. It's only partially working at the moment.
+There are a couple of issues that have yet to be worked out, but FastCGI is working in a basic way now.
 
 [h4 Access to error output streams]
 
@@ -106,32 +106,14 @@
 
 [h4 Support for environment Passed on Command Line]
 
-See section 4.4 of [@http://www.ietf.org/rfc/rfc3875].
+See section 4.4 of [@http://www.ietf.org/rfc/rfc3875]. Should be easy to do by modifying the `acgi::service` class.
 
 [h4 Support for Multi-part POST Forms]
 
-
-
-[h4 `operator[]` Overloading]
-
-What is currently:
-``
-request req;
-std::string a( req.form_("a") );
-map& forms = req.form_();
-``
-could become:
-``
-request req;
-std::string a(req[form_, "a"]);
-map& forms = req[form_];
-a = req[form_]["a"]; // better to the above, plus is more 'standard'
-``
+This has been added to the CGI part of the library, but it's very ugly and hackish. The idea is to create a `form_parser` class that can be used both internally and externally to parse multipart forms.
 
 [/h4 Removing aCGI/CGI Divide]
 
-[/h4 Support for wide characters]
-
-[/The library generally works on octets, but there should be some way to ]
+[/h4 Unicode Support]
 
 [endsect]

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/introduction.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/introduction.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/introduction.qbk 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -22,11 +22,15 @@
 
   return_(req, resp, 0); // write the response and 'return 0;'
 }
+``
 
 Example request:
+``
 example.com/program_name?name=Mr.+Allison
+``
 
-Output:
+Output (as viewed in a web browser):
+``
 Hello there, Universe. -- Mr. Allison
 
 ``
@@ -39,7 +43,7 @@
 
 [h4 Concepts]
 
-The library provides abstractions which hide details of the vastly different specifications of CGI, FastCGI and SCGI. The main abstractions are, briefly:
+The library provides abstractions which hide details of the varying specifications of CGI, FastCGI and SCGI. The main abstractions are, briefly:
 
 [table
 [
@@ -72,17 +76,23 @@
 
 [h4 Protcols]
 
-[:['See __protocol_details__ for more.]]
+[:['See __protocol_details__ for more.]] [/ **FIXME** ]
 
-In a nutshell, CGI is the simple and 'original' way of communicating with web servers. I'll assume you know what it is: one request per process and communication using standard input/output. A nice and simple way of making ['web pages that can change].
+In a nutshell, CGI is the simple and 'original' way of communicating with web servers. I'll assume you know what it is: one request per process and communication using standard input/output. A nice and simple way of making ['dynamic web pages].
 
-FastCGI was then developed as a means of allowing much more scalable CGI-like programs to be written. In fact, the FastCGI specification implies scalability was the main motivation for the protocol. Communication with the server works over sockets or pipes (only TCP sockets are supported for now). Each process and each connection can be used for handling multiple requests. In theory this means you could have a single monolithic process behind your HTTP server handling all incoming requests concurrently.
+[tip If you're new to CGI, have a look at this: [@http://hoohoo.ncsa.uiuc.edu/cgi/]]
+
+__FastCGI__ was then developed as a means of allowing much more scalable CGI-like programs to be written. In fact, the FastCGI specification implies scalability was the main motivation for the protocol. Communication with the server works over sockets or pipes (only TCP sockets are supported for now). Each process and each connection can be used for handling multiple requests. In theory this means you could have a single monolithic process behind your HTTP server handling all incoming requests concurrently.
+
+[note
+ Some initial benchmarks show that simple FastCGI programs are 3-5x faster than their CGI counterparts. When using database connections and/or HTML templates, the gap should get even bigger.
+]
 
-SCGI is essentially a simpler version - hence [*S]imple[*CGI] - of FastCGI but is still a significant step up from vanilla CGI, mainly because each process can handle multiple requests. Use of FastCGI is recommended over SCGI, but unfortunately support for FastCGI is unreliable and buggy with some servers and/or you may not have that option.
+__SCGI__ is essentially a simpler version of FastCGI - hence [*S]imple[*CGI] - but is still a significant step up from vanilla CGI, mainly because each process can handle multiple requests. Use of FastCGI is recommended over SCGI, but unfortunately support for FastCGI is unreliable and buggy with some servers and/or you may not have that option. [/ **FIXME**] SCGI support isn't included yet.
 
 [h4 Multiple Requests per Process]
 
-So I keep harping on about this, that's because it removes so many limitations of traditional CGI programming. Your programs can become servers, capable of handling an arbitrary number of requests with each invocation (assuming they don't crash, or leak memory!). This gives you the freedom to keep database connections open between requests or cache ready-parsed responses, for example. Processing of a client request can even be continued in the case of the client crashing - the `response` can then be stored and given to them when they return - saving precious CPU cycles.
+Having persistent processes is very handy. It removes so many of the limitations of traditional CGI programming; suddenly CGI programs aren't so different to desktop applications. CGI 'scripts' become FastCGI servers, capable of handling an arbitrary number of requests with each invocation (assuming they don't crash, or leak memory!). This gives you the freedom to keep database connections open between requests or cache ready-parsed responses, for example. Processing of a client request can even be continued in the case of the client crashing - the `response` can then be stored and given to them when they return - saving precious CPU cycles.
 
 The downside is added complexity: managing multiple requests and having to keep a tight reign on memory/resource consumption.
 

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/preface.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/preface.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/preface.qbk 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -23,7 +23,7 @@
 
 [h3 Motivation]
 
-C++ isn't the language of choice for many CGI programmers, despite being a powerful one that can be used to produce scalable, maintainable and uncompromisingly efficient applications.
+C++ may not be the most common language used for CGI programming, but it is a powerful one that can be used to produce scalable, maintainable and uncompromisingly efficient applications.
 
 A discussion about the benefits of CGI programming in C++ is beyond the scope of this document and I've assumed you're here because you want to try C++ CGI programming, but here is a short list anyway:
 
@@ -31,9 +31,9 @@
 
 * C++ has a very large and professional user base, providing a wealth of expertise and experience.
 
-* Billions of lines of C++ code can be reused to reduce development/testing times.
+* Millions of lines of C++ code can be reused to reduce development/testing times.
 
-* In places where RAD (rapid application development) is of the utmost importance, scripting languages can still be used, for instance by using [link __boost_python__ Boost.Python] - though it could be argued that C++ and RAD are not mutually exclusive.
+* In places where RAD (rapid application development) is of the utmost importance, scripting languages can still be used, for instance by using [link __boost_python__ Boost.Python.
 
 * C++ is ['fast]. You can rest assured that the language will never be a bottleneck for your applications.
 
@@ -45,23 +45,47 @@
 
 The generally poor support for CGI programming for C++ - most libraries are either unmaintained, or don't take advantage of modern C++ capabilities - has driven the development of this library. [-moremoremore]
 
-[h3 How to use this manual]
+[section:using How to use this manual]
 
 [note
-At the moment, the Boost [@http://www.boost.org/more/lib_guide.htm#Guidelines style guidelines] aren't honoured properly or consistently. Please ignore this for now, as the ambiguity is intentional (['since this [*is not] a Boost library]) and is simple enough to rectify.
+At the moment, the Boost [@http://www.boost.org/more/lib_guide.htm#Guidelines style guidelines] aren't honoured properly or consistently. Please ignore this for now, as the ambiguity is half-intentional (['since this [*is not] a Boost library]). It's simple enough to rectify.
 ]
 
-Start with the introduction, then the tutorial. You can skip the 'scripting' section, as that is a quickstart and the information in it is repeated throughout the rest of the manual. The doxygen header reference is very ugly for now and is going to be heavily reworked and reorganised.
-
 [h4 Naming Conventions]
 
+[h5 Headers]
+
+[table What Headers to Include
+ [[Protocol] [`#include` line]]
+ [[All] [`#include <boost/cgi.hpp>`]]
+ [[CGI] [`#include <boost/cgi/cgi.hpp>`]]
+ [[aCGI] [`#include <boost/cgi/acgi.hpp>`]]
+ [[FastCGI] [`#include <boost/cgi/fcgi.hpp>`]]
+]
+
+[h5 Namespaces]
+
+The classes/functions that are shared between protocols are in the `cgi::common` namespace. Using the above headers dumps these into the relevant namespace.
+
+[table
+ [[Protocol] [`namespace`]]
+ [[CGI] [`namespace boost::cgi`
+ `namespace cgi::cgi`]]
+ [[aCGI] [`namespace boost::acgi`
+ `namespace cgi::acgi`]]
+ [[FastCGI] [`namespace boost::fcgi`
+ `namespace cgi::fcgi`]]
+]
+
 [h5 Macros]
 
 Macros are prefixed with `BOOST_CGI_*` .
 
+[/ **FIXME**] There aren't any tested public macros yet, when there are they will be listed here.
+
 [h5 Code snippets]
 
-As you are probably used to, it is assumed that code snippets in this manual have the correct `#include`s and "`using namespace cgi;`" prepended to them. Information about the correct headers to include can be found [link __headers__ here].
+As you are probably used to, it is assumed that code snippets in this manual have the correct `#include`s and "`using namespace boost::<protocol>;`" prepended to them.
 
 [h3 Comments and Support]
 
@@ -71,4 +95,6 @@
 
 or thereabouts.
 
+[endsect][/ using]
+
 [endsect]

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/user_guide.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/user_guide.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/user_guide.qbk 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -13,15 +13,13 @@
 
 [include:server_config user_guide/server_configuration.qbk]
 
-[include:headers user_guide/headers.qbk]
-
 [endsect]
 
 [/include:protocols user_guide/protocols.qbk]
 
 [/include:tutorial user_guide/tutorial.qbk]
 
-[include:examples user_guide/examples.qbk]
+[include:examples ../../example/doc.qbk]
 
 [include user_guide/tutorial/tutorial.qbk]
 

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/user_guide/examples.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/user_guide/examples.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/doc/src/user_guide/examples.qbk 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -1,76 +1 @@
 
-[section Examples]
-
-[template example_link[protocol example_name link_text] [@../../example/\ [protocol]/[example_name]/main.cpp [link_text]]]
-
-The examples can be built by going into their directory and typing `bjam`. If you have a server set up and wish to test the applications behind them, you can automatically copy them to your server's cgi-bin (or fcgi-bin or scgi-bin) one of two ways:
-
-* `bjam install --cgi-bin=/usr/lib/cgi-bin` - installs the program (or set of programs) into `/usr/lib/cgi-bin` [*iff] they are a CGI program. If you want to install examples in the `/libs/cgi/example/fcgi/` directory, for instance, type the above but replace `--cgi-bin` to `--fcgi-bin`.
-
-* set the environment variable `BOOST_CGI_BIN_PATH` (or `BOOST_FCGI_BIN_PATH`/`BOOST_SCGI_BIN_PATH`) and just type `bjam install`. The example(s) will be installed into the relevant directory.
-
-[note
- The command line option will override the environment variable, so you can use the environment variables for default installation.
-]
-
-[section aCGI]
-
-[import ../../../example/cgi/echo/main.cpp]
-
-Linky: [example_link acgi..echo..aCGI Echo example]
-
-[@../../../example/cgi/echo/main.cpp]
-
-[file]
-
-[endsect] [/ acgi]
-
-[section CGI]
-
-[endsect] [/ cgi]
-
-[section FastCGI]
-
-[def __fcgi_hello_world__ ../../../example/fcgi/hello_world/main.cpp]
-[def __fcgi_echo__ ../../../example/fcgi/echo/main.cpp]
-
-[section "Hello, world."]
-
-[import ../../../example/fcgi/hello_world/main.cpp]
-
-Click to see the [link __fcgi_hello_world__ source file]
-
-[file]
-
-[endsect] [/ hello_world]
-
-[section Echo]
-
-[/import __fcgi_echo__]
-
-[template call_import[protocol_t example_name]
-[import ../../example/\ [protocol_t]/[name]/main.cpp]
-]
-
-[call_import fcgi..amortization]
-
-[template import_example[protocol name]
-
-[import ../../example/[protocol]/[name]/main.cpp]
-
-Click to see the [@../../../example/[protocol]/[name]/main.cpp source file].
-
-]
-
-[import_example fcgi..echo]
-
-Click to see the [/example_link[fcgi..echo..source file]].
-
-[fcgi_echo]
-
-[endsect] [/ echo]
-
-[endsect] [/ fastcgi]
-
-[endsect]
-

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/amortization/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/amortization/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/amortization/main.cpp 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -7,6 +7,8 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[acgi_amort
+//
 // Amortization Calculator
 // -----------------------
 //
@@ -116,7 +118,8 @@
     // header - followed by a blank line - first though!).
     std::string output;
     tmpl->Expand(&output, &dict);
- std::cout<< output;
+ std::cout<< "Content-type: text/html\r\n\r\n"
+ << output;
   }else
   if (arg == "2")
   {
@@ -124,32 +127,37 @@
     // Should be expensive, but doesn't seem to impact performance hugely...
     std::string output;
     tmpl->Expand(&output, &dict);
- resp<< output;
+ resp<< content_type("text/html")
+ << output;
   }else
-// if (arg == "3")
-// {
-// // Expand the string to a vector<const_buffer>, which should minimise any
-// // copying of data. This requires a modified version of Google.cTemplate, but
-// // doesn't seem to add anything to performance. Will have to check if there's a
-// // better way to do it.
-// std::string s;
-// std::vector<boost::asio::const_buffer> out;
-//
-// tmpl->Expand(&s, &out, &dict);
-// write(req.client(), out);
-// }else
+ // if (arg == "3")
+ // {
+ // // Expand the string to a vector<const_buffer>, which should minimise any
+ // // copying of data. This requires a modified version of Google.cTemplate, but
+ // // doesn't seem to add anything to performance. Will have to check if there's a
+ // // better way to do it.
+ // std::string s;
+ // std::vector<boost::asio::const_buffer> out;
+ //
+ // tmpl->Expand(&s, &out, &dict);
+ // write(req.client(), out);
+ // }else
   if (arg == "4")
   {
     // Write the output directly to the request's client.
+ std::string headers("Content-type: text/html\r\n\r\n");
+ write(req.client(), buffer(headers));
     std::string output;
     tmpl->Expand(&output, &dict);
     write(req.client(), buffer(output));
   }else
- if (arg == "5")
+ if (arg == "5")
   {
     // An alternative to { arg == "1" }, which seems to be slightly faster.
     std::string output;
     tmpl->Expand(&output, &dict);
+ const char* headers = "Content-type: text/html\r\n\r\n";
+ std::cout.write(headers, strlen(headers));
     std::cout.write(output.c_str(), output.size());
   }else
   {
@@ -160,7 +168,6 @@
 int main()
 {
   try{
- std::cout<< "Content-type: text/html\r\n\r\n"; // just for debugging
     service s;
     request req(s);
     req.load(true);
@@ -174,4 +181,5 @@
       << "ERROR!! BOOM!";
   }
 }
+//]
 

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/echo/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/echo/main.cpp 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -7,6 +7,8 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[acgi_echo
+//
 // This example simply echoes all variables back to the user. ie.
 // the environment and the parsed GET, POST and cookie variables.
 // Note that GET and cookie variables come from the environment
@@ -15,15 +17,14 @@
 
 #include <boost/cgi/acgi.hpp>
 #include <fstream>
-//#include <google/template.h>
 
 using namespace std;
 using namespace boost::acgi;
 
 // 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 MapT, typename OStreamT>
-void show_map_contents(MapT& m, OStreamT& os, const std::string& title)
+template<typename OStream, Ttypename MapT>
+void show_map_contents(OStreamT& os, MapT& m, const std::string& title)
 {
   os<< "<h3>" << title << "</h3>";
   if (m.empty()) os<< "NONE<br />";
@@ -52,7 +53,7 @@
       {
         response resp;
         resp
- << content_type("text/plain")
+ << content_type("text/html")
         << "Error " << ec.value() << ": " << ec.message() << "<p />"
            "--Original message follows--"
            "<p />";
@@ -73,34 +74,43 @@
              "</form><p />"
              "boundary marker = " << req.boundary_marker() << "<p />";
 
- show_map_contents(req.GET(), resp, "GET Variables");
- show_map_contents(req.POST(), resp, "POST Variables");
- show_map_contents(req.cookie(), resp, "Cookie Variables");
- show_map_contents(req.env(), resp, "Environment Variables");
+ show_map_contents(resp, req[get_data], "GET Variables");
+ show_map_contents(resp, req[post_data], "POST Variables");
+ show_map_contents(resp, req[cookie_data], "Cookie Variables");
+ show_map_contents(resp, req[env_data], "Environment Variables");
 
- //resp<< content_type("text/html");
- resp.send(req.client());
+ return_(resp, req, 0); // All ok.
 
- }catch(boost::system::error_code& ec){
+ }
+ catch(boost::system::system_error& ec)
+ { // This is the type of error this library throws.
       response resp;
- resp<< content_type("text/plain") << "Error " << ec.value() << ": "
- << ec.message();
- }catch(std::exception& e){
+ resp<< content_type("text/plain") << "Error " << ec.code() << ": "
+ << ec.what()
+ << http::internal_server_error; // note the status_code
+ return_(resp, req, 1);
+ }
+ catch(std::exception* e)
+ {
       response resp;
- resp<< content_type("text/plain") << "Error: " << e.what();
+ resp<< content_type("text/plain") << "Error: " << e->what()
+ << http::internal_server_error;
       return_(resp, req, 2);
     }
 
+ // The request object will be destroyed before the next exception handlers
+ // are reached.
+
   }catch(std::exception* e){
- std::cout
+ std::cerr
     << content_type("text/plain").content
     << "Exception: " << e->what();
- //resp.send(req.client());
     return 3;
   }catch(...){
- std::cout<< content_type("text/plain").content
+ std::cerr<< content_type("text/plain").content
              << "Unknown error.";
     return 4;
   }
- return 0;
 }
+//]
+

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/hello_world/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/hello_world/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/hello_world/main.cpp 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -7,6 +7,8 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[acgi_hello_world
+//
 // The simplest CGI program, outputs only "Hello there, universe."
 //
 
@@ -30,3 +32,5 @@
   // Leave this function, after sending the response and closing the request.
   return_(resp, req, 0); // Note the underscore: returns "0" to the OS.
 }
+//]
+

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/echo/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/echo/main.cpp 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -7,22 +7,22 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[cgi_echo
+//
 // This example simply echoes all variables back to the user. ie.
 // the environment and the parsed GET, POST and cookie variables.
 // Note that GET and cookie variables come from the environment
 // variables QUERY_STRING and HTTP_COOKIE respectively.
 //
 
-//[file
 #include <boost/cgi/cgi.hpp>
 
-using namespace std;
 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 MapT, typename OStreamT>
-void show_map_contents(MapT& m, OStreamT& os, const std::string& title)
+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 />";
@@ -40,10 +40,10 @@
 
   response resp;
 
- show_map_contents(req.env(), resp, "Environment Variables");
- show_map_contents(req.GET(), resp, "GET Variables");
- show_map_contents(req.POST(), resp, "POST Variables");
- show_map_contents(req.cookie(), resp, "Cookie Variables");
+ show_map_contents(resp, req[env_data], "Environment Variables");
+ show_map_contents(resp, req[get_data], "GET Variables");
+ show_map_contents(resp, req[post_data], "POST Variables");
+ show_map_contents(resp, req[cookie_data], "Cookie Variables");
 
   // Note that this (and any other) HTTP header can go either before or after
   // the response contents.

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/amortization/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/amortization/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/amortization/main.cpp 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -7,6 +7,8 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[fcgi_amort
+//
 // Amortization Calculator
 // -----------------------
 //
@@ -185,7 +187,8 @@
   try{
 
     service s;
- acceptor a(s, true);
+ acceptor a(s, true); // The true means default-initialise.
+ // Unfortunately this only works on linux w. apache for now.
 
     accept_requests(a);
     
@@ -199,4 +202,5 @@
     std::cerr<< "ERROR!! BOOM!" << std::endl;
   }
 }
+//]
 

Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server2/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server2/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/server2/main.cpp 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -34,13 +34,11 @@
 using namespace std;
 using namespace boost::fcgi;
 
-// This is a file to put internal logging info into
-#define LOG_FILE "/var/www/log/fcgi_server2.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 />";
@@ -51,32 +49,13 @@
   }
 }
 
-/// The handle_request member function is used to handle requests.
+/// Handle one request and return.
 /**
- * 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).
+ * If it returns != 0 then an error has occurred. Sets ec to the error_code
+ * corresponding to the error.
  */
-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)
+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;
 
@@ -87,13 +66,9 @@
         << "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());
+ format_map(resp, req[env_data], "Environment Variables");
+ format_map(resp, req[get_data], "GET Variables");
+ format_map(resp, req[cookie_data], "Cookie Variables");
 
     //log_<< "Handled request, handling another." << std::endl;
 
@@ -109,10 +84,6 @@
     // Note: in this case `program_status == 0`.
   }
 
-private:
- std::ofstream log_;
-};
-
 
 /// The server is used to abstract away protocol-specific setup of requests.
 /**
@@ -126,6 +97,8 @@
 class server
 {
 public:
+ typedef fcgi::service service_type;
+ typedef fcgi::acceptor acceptor_type;
   typedef fcgi::request request_type;
   typedef boost::function<
             int ( request_type&
@@ -138,7 +111,7 @@
     , acceptor_(service_)
   {}
 
- void run()
+ void run(int num_threads = 0)
   {
     // Create a new request (on the heap - uses boost::shared_ptr<>).
     request_type::pointer new_request = request_type::create(service_);
@@ -146,7 +119,12 @@
     requests_.insert(new_request);
 
     start_accept(new_request);
- service_.run();
+ boost::thread_group tgroup;
+ for(int i(num_threads); i != 0; --i)
+ {
+ tgroup.create_thread(boost::bind(&service_type::run, &service_));
+ }
+ tgroup.join_all();
   }
 
   void start_accept(request_type::pointer& new_request)
@@ -196,21 +174,18 @@
 
 private:
   function_type handler_;
- fcgi::service service_;
- fcgi::acceptor acceptor_;
+ service_type service_;
+ acceptor_type acceptor_;
   std::set<request_type::pointer> requests_;
 };
 
 int main()
 try
 {
- request_handler rh(LOG_FILE);
-
- server s(boost::bind(&request_handler::handle_request
- , &rh, _1, _2)
- );
+ server s(&handle_request);
 
- s.run();
+ // Run the server with 10 threads handling the asynchronous functions.
+ s.run(10);
 
   return 0;
   

Modified: sandbox/SOC/2007/cgi/branches/release/project-root.jam
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/project-root.jam (original)
+++ sandbox/SOC/2007/cgi/branches/release/project-root.jam 2008-03-29 14:40:40 EDT (Sat, 29 Mar 2008)
@@ -40,7 +40,7 @@
     }
     else
     {
- return $(top)/$(protocol:L)"-bin" ;
+ return "$(top)/$(protocol:L)-bin" ;
     }
   }
 }
@@ -49,6 +49,43 @@
 path-constant fcgi-bin : [ get-bin-dir "fcgi" ] ;
 path-constant scgi-bin : [ get-bin-dir "scgi" ] ;
 
+#############################################################################
+# Rule to extract the directory for web documents (some servers call it
+# the htdocs folder). The amortization examples will want this to be set.
+#
+# User can pass either:
+#
+# --htdocs=/path/to/htdocs
+#
+# on the bjam command line OR set the environment variable:
+#
+# BOOST_CGI_HTDOCS_PATH
+#
+# Note that the command line will override the environment variable!
+#############################################################################
+local rule get-htdocs-dir ( )
+{
+ local dir = [ MATCH "^--htdocs=(.*)" : [ modules.peek : ARGV ] ] ;
+ if $(dir)
+ {
+ return $(dir) ;
+ }
+ else
+ {
+ dir = [ os.environ "BOOST_CGI_HTDOCS_PATH" ] ;
+ if $(dir)
+ {
+ return $(dir) ;
+ }
+ else
+ {
+ return "$(top)/htdocs" ;
+ }
+ }
+}
+
+path-constant htdocs : [ get-htdocs-dir ] ;
+
 
 use-project /boost/ : $(boost-root) ;
 use-project /boost/cgi/ : $(top)/libs/cgi/build ;


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