Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62027 - in sandbox/SOC/2007/cgi/trunk: . boost/cgi/common libs/cgi/build/msvc/9.0/Boost.CGI/cgi_cookies libs/cgi/doc libs/cgi/doc/src libs/cgi/doc/src/overview libs/cgi/doc/src/tutorial libs/cgi/doc/src/utilities libs/cgi/doc/src/utilities/sessions libs/cgi/example libs/cgi/example/cgi libs/cgi/example/cgi/authorizer libs/cgi/example/cgi/cookies libs/cgi/example/cgi/cookies2 libs/cgi/example/cgi/stencil
From: lists.drrngrvy_at_[hidden]
Date: 2010-05-16 05:28:10


Author: drrngrvy
Date: 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
New Revision: 62027
URL: http://svn.boost.org/trac/boost/changeset/62027

Log:
* Modified some documentation files.
* Fixed bug with dependent typedef lookup in the request_data class (broken on linux).
* Added some missing files.
* Minor cleanups to some examples.
Added:
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/sessions.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/traits.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/installation.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/sessions.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/sessions/sessions.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/sessions/sessions_quickstart.html (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/stencils.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/authorizer/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/authorizer/main.cpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies/doc.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/Jamfile.v2 (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/doc.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/index.html (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/main.cpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/main.js (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/style.css (contents, props changed)
Text files modified:
   sandbox/SOC/2007/cgi/trunk/README.txt | 20 ++++++++-
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_data.hpp | 24 ++++++++++++
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_cookies/cgi_cookies.vcproj | 4 +-
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/Jamfile.v2 | 7 ++-
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/cgi.qbk | 27 +++++++------
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/future_development.qbk | 20 ++++-----
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/introduction.qbk | 2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/acceptors.qbk | 56 +++++++++++++++++++++++++---
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/responses.qbk | 46 +----------------------
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi_quickstart.cpp | 76 +++++++++++++++++++++------------------
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies/main.cpp | 56 ++++++++--------------------
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/doc.qbk | 2 -
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/stencil/doc.qbk | 4 +
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/stencil/main.cpp | 37 ++++++++++---------
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/doc.qbk | 8 ++--
   15 files changed, 207 insertions(+), 182 deletions(-)

Modified: sandbox/SOC/2007/cgi/trunk/README.txt
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/README.txt (original)
+++ sandbox/SOC/2007/cgi/trunk/README.txt 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -1,13 +1,23 @@
 Comments/critique are welcome and can be directed to one of:
 
   cgi-devel @ cgi dot sourceforge dot net
- lists dot drrngrvy @ gmail dot com
+ darren dt garvey @ gmail dt com
 
 ------------------------------------------------------------
 
+== DISCLAIMER ==
+
+Note: This library is *not* a Boost library. It uses Boost coding conventions and will be proposed for review in due course.
+
+Please do not confuse the code style with any mark of approval coming from the members of Boost. Said approval is still to be obtained.
+
+== / DISCLAIMER ==
+
 Websites for more information on this library are:
  http://cgi.sf.net
  http://omnisplat.com
+
+Documentation is being updated so the documentation up on these sites is quite out of date. The examples in this package are by far the best teaching aid for the moment.
 
 Check the library works ok by first running the tests + compiling the examples.
 
@@ -17,7 +27,7 @@
 
 directory (see Jamfile.v2 for build instructions).
 
-Note that some of the examples (ie. the "stencil" examples) require cTemplate, so they will fail to compile unless you have that installed.
+Note that some of the examples (ie. the "stencil" examples) require Google's cTemplate, so they will fail to compile unless you have that installed.
 
 The tests aren't exhaustive - this library is still under development.
 
@@ -27,6 +37,10 @@
 Ubuntu 9.10 desktop 32bit
 Ubuntu 8.04 server 64bit
 MSVC 2008 Windows XP
+MSVC 2008 Windows 7
+
+FastCGI stuff works on linux and Windows under Apache 2.2 and mod_fcgid. Currently external fastcgi servers (eg. on mod_fastcgi) are only supported on linux.
 
-FastCGI stuff only works on linux at the moment. FastCGI is supported on Windows as an external server, tested against Apache 2.2 with mod_fastcgi (obsolete) and mod_fcgid. mod_fcgid has been merged with upstream Apache and should become part of a future release.
+Bleeding edge code is at https://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/trunk
 
+Check out the latest code with: svn co https://svn.boost.org/svn/boost/sandbox/SOC/2007/cgi/trunk

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_data.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_data.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_data.hpp 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -22,6 +22,18 @@
     : public data_map_proxy<T>
   {
   public:
+ typedef T map_type;
+ typedef data_map_proxy<map_type> self_type;
+ typedef typename map_type::key_type key_type;
+ typedef typename map_type::value_type value_type;
+ typedef typename map_type::mapped_type mapped_type;
+ typedef typename map_type::size_type size_type;
+ typedef typename map_type::iterator iterator;
+ typedef typename map_type::const_iterator const_iterator;
+ typedef typename map_type::reverse_iterator reverse_iterator;
+ typedef typename map_type::const_reverse_iterator const_reverse_iterator;
+ typedef typename map_type::allocator_type allocator_type;
+
     using data_map_proxy<T>::operator[];
   };
 
@@ -33,7 +45,17 @@
     : public data_map_proxy<T>
   {
   public:
- typedef typename T::iterator iterator;
+ typedef T map_type;
+ typedef data_map_proxy<map_type> self_type;
+ typedef typename map_type::key_type key_type;
+ typedef typename map_type::value_type value_type;
+ typedef typename map_type::mapped_type mapped_type;
+ typedef typename map_type::size_type size_type;
+ typedef typename map_type::iterator iterator;
+ typedef typename map_type::const_iterator const_iterator;
+ typedef typename map_type::reverse_iterator reverse_iterator;
+ typedef typename map_type::const_reverse_iterator const_reverse_iterator;
+ typedef typename map_type::allocator_type allocator_type;
 
     std::pair<iterator, iterator> equal_range( const key_type& key ) {
       return impl()equal_range(key);

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_cookies/cgi_cookies.vcproj
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_cookies/cgi_cookies.vcproj (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_cookies/cgi_cookies.vcproj 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -89,7 +89,7 @@
                         />
                         <Tool
                                 Name="VCPostBuildEventTool"
- CommandLine="copy &quot;$(TargetPath)&quot; &quot;\code\c++\boost.cgi\cgi-bin\$(TargetName)&quot;&#x0D;&#x0A;copy &quot;$(SolutionDir)\..\..\..\..\example\cgi\cookies\index.html&quot; &quot;c:\code\c++\boost.cgi\stencils\index.html&quot;&#x0D;&#x0A;"
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;\code\c++\boost.cgi\cgi-bin\$(TargetName)&quot;&#x0D;&#x0A;copy &quot;$(SolutionDir)\..\..\..\..\example\cgi\cookies\index.html&quot; &quot;\code\c++\boost.cgi\stencils\index.html&quot;&#x0D;&#x0A;"
                         />
                 </Configuration>
                 <Configuration
@@ -167,7 +167,7 @@
                         />
                         <Tool
                                 Name="VCPostBuildEventTool"
- CommandLine="copy &quot;$(TargetPath)&quot; &quot;\code\c++\boost.cgi\cgi-bin\$(TargetName)&quot;&#x0D;&#x0A;copy &quot;$(SolutionDir)\..\..\..\..\example\cgi\cookies\index.html&quot; &quot;c:\code\c++\boost.cgi\stencils\index.html&quot;&#x0D;&#x0A;"
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;\code\c++\boost.cgi\cgi-bin\$(TargetName)&quot;&#x0D;&#x0A;copy &quot;$(SolutionDir)\..\..\..\..\example\cgi\cookies\index.html&quot; &quot;\code\c++\boost.cgi\stencils\index.html&quot;&#x0D;&#x0A;"
                         />
                 </Configuration>
         </Configurations>

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/Jamfile.v2 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -131,7 +131,10 @@
     # Max depth in each TOC:
     <xsl:param>toc.max.depth=2
     # How far down we go with TOC's
- <xsl:param>generate.section.toc.level=1
+ <xsl:param>generate.section.toc.level=3
+ #<xsl:param>%div.title.content="'false'"
+ <xsl:param>$nav.border="'None'"
+ <xsl:param>djg.nonav="'ok'"
     #<xsl:param>generate.toc="chapter nop section nop"
 
     #<xsl:param>root.filename="svg_plot"
@@ -139,7 +142,7 @@
     <xsl:param>boost.image.src="../doc/src/images"
     <xsl:param>project.image.src="../doc/src/images"
 
- # <xsl:param>project.root=http://beta.boost.org/development
+ <xsl:param>project.root=http://omnisplat.com
     # <xsl:param>annotation.support=1
     # <xsl:param>quickbook.source.style.show="'true'"
 

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/cgi.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/cgi.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/cgi.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -5,12 +5,12 @@
  / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  /]
 
-[library CGI
+[library FastCGI / CGI
     [quickbook 1.5]
- [version 0.6]
+ [version 0.7]
     [dirname the_document_dir]
- [copyright 2007-2009 Darren Garvey]
- [purpose Documentation for CGI / FastCGI Library]
+ [copyright 2007-2010 Darren Garvey]
+ [purpose Documentation for CGI / FastCGI C++ Library]
     [authors [Garvey, Darren]]
     [license
         Distributed under the Boost Software License, Version 1.0.
@@ -30,7 +30,6 @@
 [def __fcgi__ [@http://en.wikipedia.org/wiki/FastCGI FastCGI]]
 
 [def __FastCGI__ [link boost.cgi.reference.protocols.fcgi FastCGI]]
-[def __SCGI__ [link boost.cgi.reference.protocols.scgi SCGI]]
 
 [def __boost__ [@http://boost.org/ Boost]]
 [def __asio__ [@http://asio.sourceforge.net Boost.Asio]]
@@ -54,6 +53,10 @@
 [def __HEAD__ `HEAD`]
 [def __PUT__ `PUT` ]
 
+[def __Boost__ [@http://boost.org Boost]]
+
+[def __ProtocolService__ `ProtocolService`]
+[def __Request__ `Request`]
 
 [def __Service__ [@http://asio.sourceforge.net/boost_asio_0_3_9/libs/asio/doc/html/boost_asio/reference/Service.html Service]]
 
@@ -81,12 +84,14 @@
 ]
 
 [important
-This manual does [*not] document a library that is a part of __Boost__. The major part of it has been developed this summer as part of the Google Summer of Code, '[@http://code.google.com/soc/2007 GSoC07]'. Everything from here on in is alpha-grade, some bits more than others; [link boost.cgi.preface.comments_and_support comments and bug reports] are welcome.
+This manual does [*not] document a library that is a part of __Boost__. The library was started just before the summer of 2007 and worked on during the [@http://code.google.com/soc/2007 Google Summer of Code 2007].
+
+There has been a lot of changes recently (as of May 2010) and the interface has reached a relatively stable state. Comments and bug reports are most welcome and should be directed to cgi-devel at lists.sf.net.
 
-These documents are either hosted at [@http://sourceforge.net/projects/cgi/ sourceforge], or at [@http://svn.boost.org/svn/boost/browser/sandbox/SOC/2007/cgi svn.boost.org]. For free!
+The project is hosted at [@http://sourceforge.net/projects/cgi/ sourceforge] and the bleeding edge code is in the [@http://svn.boost.org/svn/boost/browser/sandbox/SOC/2007/cgi/trunk Boost SVN sandbox].
 ]
 
-[include preface.qbk]
+[/include preface.qbk]
 
 [include:intro introduction.qbk]
 
@@ -96,19 +101,17 @@
 
 [include utilities.qbk]
 
-[/xinclude ../cgi_dox.xml]
-
 [include:examples examples.qbk]
 
 [/include:reference reference.qbk]
 
-[/include:future future_development.qbk]
+[include:future future_development.qbk]
 
 [/include:server_support user_guide/server_support.qbk]
 
 [/include troubleshooting.qbk]
 
-[/include acknowledgements.qbk]
+[include acknowledgements.qbk]
 
 [/xinclude index.xml]
 

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/future_development.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/future_development.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/future_development.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2007 Darren Garvey
+ / Copyright (c) 2007-2010 Darren Garvey
  /
  / 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)
@@ -9,17 +9,19 @@
 
 [h4 Iostream functionality.]
 
-Streamed IO, likely to be similar to Boost.Asio's `basic_socket_stream<>` is required.
+Streamed IO, likely to be similar to Boost.Asio's `basic_socket_stream<>` would be nice, although .
 
 [h4 SCGI support.]
 
 I haven't managed to get apache/lighttpd configured properly for SCGI, so this isn't functional yet.
 
-[h4 FastCGI support.]
+[h4 FastCGI client support.]
+
+FastCGI is supported in server-side applications. Support for client-side applications would be useful.
 
-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.
+[h4 FastCGI support.]
 
-There are a couple of issues that have yet to be worked out, but FastCGI is working in a basic way now.
+I would like to add to the FastCGI functionality on Windows, where currently only anonymous pipes are supported. It is possible to customise the library to use external FastCGI apps, but this is not documented.
 
 [h4 Access to error output streams]
 
@@ -36,16 +38,12 @@
 
 Access to the above streams will be implemented as a __Service__, which can be switched on or off at runtime. Output can be sent either to stdout, stderr, or both simultaneously. If this isn't enough, a user can add their own custom service layer, which can manipulate the data as it is read/written in any way they wish (such as logging to a database, url-encoding/filtering data, or playing an April Fool's prank on your website visitors).
 
-[h4 Session handling.]
-
-Access to persistent session data is a very useful stop-gap to using a complete RDBMS to store/retrieve data. In some cases, such as when an object is supposed to stay in active memory, a RDBMS will not be efficient, so session management fits in nicely. A templated `basic_session<>` will be provided so various session-storage methods can be used. Boost.Interprocess is an ideal default, while Boost.UUID can be used to generate unique session identifiers.
-
 [h4 Concept Documentation]
 
 Even though this library introduces very few new concepts, they are not currently documented. Links to Boost.Asio's concept documentation is also required (essentially as part of a reworking of the doxygen reference section).
 
-[/h4 Removing aCGI/CGI Divide]
+[h4 Unicode Support]
 
-[/h4 Unicode Support]
+The library currently makes no documented provisions for Internationalisation support. The string type used in the library is templated but this is as far as support goes. A Boost.Unicode library would help a lot with adding this support. Comments on this topic by domain experts are most welcome.
 
 [endsect]

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/introduction.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/introduction.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/introduction.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2007 Darren Garvey
+ / Copyright (c) 2007-2010 Darren Garvey
  /
  / 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)

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,18 @@
+
+[section Overview]
+
+[include overview/requests.qbk]
+
+[include overview/responses.qbk]
+
+[include overview/services.qbk]
+
+[include overview/acceptors.qbk]
+
+[include overview/clients.qbk]
+
+[include overview/sessions.qbk]
+
+[include overview/traits.qbk]
+
+[endsect]
\ No newline at end of file

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/acceptors.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/acceptors.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/acceptors.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -13,27 +13,31 @@
 
 A [classref cgi::basic_request_acceptor `basic_request_acceptor<>`] is responsible for accepting requests. The following `typedefs` are provided for typical use:
 ``
-cgi::acceptor // CGI
-fcgi::acceptor // FastCGI
+boost::cgi::acceptor // CGI
+boost::fcgi::acceptor // FastCGI
 ``
 
 Accepting requests is considered distinct to the [link __loading__ loading] stage for several reasons, the most significant of which is to allow for multiplexing protocols like FastCGI work with the other protocols.
 
-A `basic_request_acceptor<>` takes an instance of a __ProtocolService__ in its constructor. The following member functions are available (take xcgi to imply one of cgi/fcgi):
+A `basic_request_acceptor<>` takes an instance of a __ProtocolService__ in its constructor. The following member functions are available, where Request is any class that models the __Request__ concept:
 
 [table
   [[Function signature] [Purpose]]
   [
- [`void accept(xcgi::request& empty_request)`]
+ [`void accept(Request& empty_request)`]
     [Takes an empty request and blocks until a request is waiting to be handled. This will throw if the accept fails.]
   ]
   [
     [`boost::system::error_code&
- accept(xcgi::request& empty_request, boost::system::error_code& ec)`]
+ accept(Request& empty_request, boost::system::error_code& ec)`]
     [Takes an empty request and blocks until a request is waiting to be handled. `ec` will be set such that `!ec == false` if the accept fails with an error code `ec`.]
   ]
   [
- [`void async_accept(xcgi::request& empty_request, Handler handler)`]
+ [`void accept(RequestHandler handler)`]
+ [Accepts a new request and calls `handler` with the new request. A `RequestHandler` takes a request by reference and should match the signature `function<int (Request& req)>`.]
+ ]
+ [
+ [`void async_accept(Request& empty_request, Handler handler)`]
     [Takes an empty request and asynchronously accepts a request. `handler` must be a model of __Handler__ and will be invoked when a request is accepted or an error occurs. The function always returns immediately.]
   ]
   [
@@ -42,7 +46,43 @@
   ]
 ] [/table]
 
-[h5 Example]
+[section:example1 Example 1]
+
+A simple example that runs a handler function for each request that is accepted. The requests are handled one at a time.
+
+``
+#include <boost/cgi/fcgi.hpp>
+
+namespace fcgi = boost::fcgi;
+
+int handler(fcgi::request& req)
+{
+ // use the request.
+}
+
+int main()
+{
+ // create a ProtocolService
+ fcgi::service service;
+
+ // create an acceptor
+ fcgi::acceptor acceptor(service);
+
+ int status(0)
+ while(!status) {
+ // accept a request
+ status = acceptor.accept(&handler);
+ }
+
+ return status;
+}
+``
+
+[endsect] [/ example1]
+
+[section:example2 Example 2]
+
+Another example that allows you to construct your own request object and then accept a new request into the object. Useful if you need to store a list of requests in your application.
 
 ``
 #include <boost/cgi/fcgi.hpp>
@@ -73,6 +113,8 @@
 }
 ``
 
+[endsect][/ example2]
+
 [endsect] [/ accepting]
 
 [endsect] [/ acceptors]

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/responses.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/responses.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/responses.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -5,52 +5,12 @@
 
 While you may sometimes want to respond to a request by writing directly back to the client, more often that not it is preferable to buffer your response. You can never tell how successful a request is going to be from the start, or whether an exception is going to be throw. Being able to rewrite your response at any time is a requirement for real-world applications.
 
-The library provides the [classref boost::cgi::response response] class to make buffering your response simpler. Here is an example of using it:
+The library provides the [classref boost::cgi::response response] class to make buffering your response simpler.
 
 [tip
- If you're keen to use HTML templates, consider looking at the [classref boost::cgi::stencil stencil] class, which uses cTemplate to allow you to write
-maintainable [@http://wikipedia.org/wiki/Model%2Dview%2Dcontroller Model-View-Controller] apps. This class is just a wrapper over cTemplate and is [*currently experimental].
+ If you're keen to use HTML templates, consider looking at the [classref boost::cgi::stencil stencil] class, which uses Google's cTemplate library to allow you to write
+maintainable [@http://wikipedia.org/wiki/Model%2Dview%2Dcontroller Model-View-Controller] apps. This class is just a lightweight wrapper over cTemplate and is [*currently experimental].
 ]
 
-[section:example Short Example]
-
-[/import __doxamples__/response_1.cpp]
-
-First, include the correct header.
-
-[includes]
-
-Then define your `response` object.
-
-[enter_main]
-
-Now we can write to `resp` like we would with any other output stream. Below you can see how you can stream [classref cgi::header] objects to the response, which are completely independent of the response body. After all, if we're going to buffer our reply, we may as well take advantage of it. As you can see, we can explicitly mark that no more headers can be added by streaming a default-constructed `header` object. This is useful if you have flushed the response (more on this later) and the header block has already been sent to the client.
-
-[stream_headers]
-
-If for any reason we need to get rid of the headers we have two options. One is `response::clear_headers()`, which simply deletes the current headers. This will assert if the headers have already been terminated. The alternative is `response::reset_headers()`, which indescriminately clears the headers and resets the 'terminated' toggle (__FIXME__ This could probably do with being a bit uglier, or at least providing a warning).
-
-[clear_headers]
-
-The file <boost/cgi/header.hpp> defines some helper classes so you can stream known types of header with the assurance that typos won't slip into a compiled program. A complete list of these can be found [link __FIXME__ here].
-
-[helper_types]
-
-You may also set headers directly. In the second call, we are using __boost_lexical_cast__ to cast the response content length into a string so it can be set in the header. If you're not familiar with `lexical_cast<>`, you should take a look at it.
-
-[set_headers_directly]
-
-Finally, we need to send the response somewhere. This can be done to any model of the __SyncReadStream__ concept. This could be anything from a IP/TCP socket, to a remote database, whatever you like. As noted, a request from this library is a special case, so you can just pass it directly, even though it doesn't deal with reading or writing itself.
-
-[sending]
-
-And that's most of what you need to know to get using the `response`. Check out the [classref cgi::response] for the rest.
-
-[endsect] [/ example]
-
-[section:api `cgi::response` Interface]
-
-[endsect] [/ api]
-
 [endsect] [/ responses]
 

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/sessions.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/sessions.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,25 @@
+
+[section:sessions Sessions]
+
+[note
+Sessions are disabled by default and are only enabled when you define `BOOST_CGI_ENABLE_SESSIONS`. Supporting sessions adds a dependency on Boost.Serialization and also on the Boost.Uuid library (which was newly added in Boost 1.42).
+]
+
+In a typical CGI program, you will want to keep track of the user's current state as they navigate through the application / website. The CGI protocol itself doesn't keep track of state, but using cookies it is possible to save information on the client's machine. The information will identify them to your application each time they make a request.
+
+Cookies aren't the best vehicle for session information for a few reasons:
+
+# They are limited in size. The maximum size of a cookie is 4kB and each domain can have 20 cookies[footnote [@http://www.15seconds.com/faq/Cookies/388.htm http://www.15seconds.com/faq/Cookies/388.htm]]. Realistically the actual limit may be higher, but relying on other limits may give unportable results.
+# They aren't inherently secure. Cookies are sent between the client and the server almost every time they communicate and they are commonly stored in a plain text file on the client's machine. Clearly, saving personal data in a cookie isn't a very good idea.
+
+What cookies are especially well-suited for is saving less-secure session information. Think styling information, user preferences, session ids...
+
+[h4 Session IDs]
+
+It is advisable to keep secure user information on the server. The standard way to link the user's active session to their data is using a session id. This is simply a unique string that is generated for the user (eg. automatically or when they log in) and thereafter identifies them to the server / application. The lifetime of the cookie can be set to a specified time in the future or will expire when they close their browser (the default behaviour) or manually remove the cookie. Most applications will also give users some way of logging out.
+
+[h4 Session State]
+
+By default, sessions are stored on the filesystem, with one file per session. This may be an issue for high-traffic sites. If you find you need / want a different serialization strategy, you can easily integrate your own session handling with the library.
+
+[endsect] [/ sessions]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/traits.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/traits.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,6 @@
+
+[section:traits Protocol Traits]
+
+['[*TODO]: Document using `protocol_traits<>` to customise the library]
+
+[endsect]
\ No newline at end of file

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,20 @@
+[/
+ / Copyright (c) 2007-2009 Darren Garvey
+ /
+ / 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)
+ /]
+
+[section Tutorial]
+
+[include tutorial/cgi.qbk]
+
+[include tutorial/fastcgi.qbk]
+
+[include tutorial/running.qbk]
+
+[include tutorial/installation.qbk]
+
+[/include:wrapping_up wrapping_up.qbk]
+
+[endsect]

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi_quickstart.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi_quickstart.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi_quickstart.cpp 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -78,7 +78,7 @@
 response and does all request-specific work. Later, we will look at writing
 the code that calls this function.
>*/
-int handle_request(fcgi::request& req, fcgi::response& resp)
+int handle_request(fcgi::request& req)
 {
 /*<
 A FastCGI request is not loaded or parsed by default.
@@ -105,22 +105,25 @@
   ]
   [
     [GET] [`req.get`] [The variables passed in the query string of an HTTP GET
- request.]
+ request. The `get_data` map is multivalued and mimics a `std::multimap<>`.]
   ]
   [
     [POST] [`req.post`] [The HTTP POST data that is sent in an HTTP request's
- body. File uploads are not stored in this map.]
+ body. For file uploads, only the filename is stored in this map. As with
+ `get`, the `post_data` map is multivalued and mimics a `std::multimap<>`.]
   ]
   [
     [Cookies] [`req.cookies`] [Cookies are sent in the HTTP_COOKIE environment
- variable. These can store limited amounts session information on the client's
- machine, such as database session ids or tracking information.]
+ variable. These can store limited amounts session information on the
+ client's machine, such as database session ids or tracking information. As
+ with `get`, the `cookie_data` map is multivalued and mimics a
+ `std::multimap<>`.]
   ]
   [
     [File Uploads] [`req.uploads`] [File uploads, sent in an HTTP POST where
     the body is MIME-encoded as multipart/form-data. Uploaded files are read
     onto the server's file system. The value of an upload variable is the path
- of the file.]
+ of the file. The `upload_data` map is also multivalued.]
   ]
   [
     [Form] [`req.form`] [The form variables are either the GET variables or
@@ -128,6 +131,33 @@
   ]
 ]
>*/
+
+ fcgi::response resp;/*<
+The `response` class provides a streaming interface for writing replies. You
+can write to the request object directly, but for now we're going to use the
+`response`, which works well for most situations.
+
+As you can see, the `response` is decoupled from the rest of the library. The
+advantages of using it over any other custom container are separate handling
+of the response body and headers, and a [funcref
+boost::cgi::common::response::send send()] function which wraps the whole
+response and writes it out to the client who instigated the request.
+
+Writing to a `response` is buffered. If an error occurs, you can `clear()` the
+response and send an error message instead. Buffered writing may not always
+suit your use-case (eg. returning large files), but when memory is not at a
+real premium, buffering the response is highly preferable.
+
+Not only does buffering help with network latency issues, but being able to
+cancel the response and send another at any time is almost essential when
+an error can crop up at any time. A `cgi::response` is not tied to a
+request, so the same response can be reused across multiple requests.[footnote
+Not with plain CGI though, of course.]
+
+When sending a response that is large relative to the amount of memory
+available to the system, you may need to write unbuffered.
+>*/
+
   if (req.form.count("expression"))
   {
     resp<< "<fieldset><legend>Result</legend><pre>";
@@ -195,24 +225,6 @@
   fcgi::acceptor acceptor(service); /*<
 An `Acceptor` handles accepting requests and little else.
>*/
- fcgi::response response; /*<
-The `response` class provides a streaming interface for writing replies. You
-can write to the request object directly, but for now we're going to just
-use the `response`, which works well for most situations.
-
-Writing to a `response` is buffered. If an error occurs, you can simply
-`clear()` the response and send an error message instead. Buffered writing
-may not always suit your use-case (eg. returning large files), but when memory
-is not at a real premium, buffering the response is highly preferable.
-
-Not only does buffering avoid network latency issues, but being able to cancel
-the response and send another is much cleaner than sending half a response,
-followed by "...Ooops". A `cgi::response` is not tied to a request, so the
-same response can be reused across multiple requests.
-
-When sending a response that is large relative to the amount of memory
-available to the program, you may want to write unbuffered.
->*/
   int status;
   
 /*<
@@ -228,20 +240,12 @@
 ie. A function that takes a reference to a `request` and returns an `int`.
 The returned `int` should be non-zero if the request was handled with
 an error.
-
-Since our handler has been defined to take references to a `request` and a
-`response`, we can use [@http://boost.org/libs/bind Boost.Bind] to wrap our
-function to give it the signature we need. See the documentation of Boost.Bind
-and [@http://boost.org/libs/function Boost.Function] for more information .
>*/
- status = acceptor.accept(boost::bind(&handle_request, _1, boost::ref(response)));
- if (status) {
+ status = acceptor.accept(&handle_request);
+ if (status)
         std::cerr
- << "Request handled with error. Exit code: " << status << std::endl
- << "Response body follows: " << std::endl
- << response.str() << std::endl;
- }
- response.clear();
+ << "Request handled with error. Exit code: "
+ << status << std::endl;
   } while (!status);
   return status;
 }

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/installation.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/installation.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,60 @@
+[/
+ / Copyright (c) 2007-2009 Darren Garvey
+ /
+ / 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)
+ /]
+
+[section Installation]
+
+Boost.CGI is a header-only library so there is no source to build. However, the library depends on a few Boost libraries (listed below), which for now should be built. Support for sessions also adds Boost.Serialization as a dependency.
+
+[h5 Dependencies]
+
+* Boost C++ Libraries. Tested with v1.39-v1.42. Session support requires Boost.Uuid, which was first included in v1.42[footnote The version of Boost.Uuid in Boost 1.42 reportedly does not create truly random Uuids, so you are recommended to use the version of Boost.Uuid distributed with Boost 1.43 or above.]
+* Google cTemplate - only required for using stencils (optional).
+
+[h5 Preparing]
+
+Boost-related elements can be downloaded from the [@http://sf.net/project/showfiles.php?group_id=7586 Boost download site] at sourceforge.
+
+[note
+"invoking `bjam`" implies calling "`bjam toolset=<your_toolset>`", where "`<your_toolset>`" is one of [@http://www.boost.org/doc/html/bbv2/reference.html#bbv2.reference.tools.compilers these]. More information can be found [@http://boost.org/more/getting_started/index.html here] (these are general instructions for building Boost [*and] configuring `bjam`. Following these instructions will also 'tick' the first two requirements below.
+]
+
+[table What you need
+ [[Element] [Optional?] [Instructions]]
+ [
+ [Boost.Jam - `bjam`]
+ [No]
+ [Download '__boost_jam__' (precompiled versions are highly recommended) and make it accessible to your system's PATH.]
+ ]
+ [
+ [Boost.System / Boost.Filesystem / Boost.Regex / Boost.Thread / Boost.Date_time]
+ [No]
+ [1. Download the latest Boost distro, 'boost'.
+
+ 2. Set the environment variable BOOST_ROOT on your system to the download location.
+
+ 3. Go to the directory BOOST_ROOT and invoke `bjam` (see above), passing it `--with-system --with-regex --with-date_time --with-filesystem --build-type=complete install` on the command line. his should finish without any failures.
+
+ For complete instructions, see the [@http://www.boost.org/doc/libs/release/more/getting_started/index.html Boost Getting Started guide].]
+ ]
+ [
+ [Documentation]
+ [Yes]
+ [These are built by going to the libs/cgi/doc directory and invoking `bjam` (see above). You can then read the docs by directing your browser to libs/cgi/index.html]
+ ]
+ [
+ [Unit tests]
+ [Yes]
+ [Tests can be run by going to the libs/cgi/test directory and invoking `bjam` (see above). Boost.CGI aims to be cross-platform, but not all platforms are available for testing. If any tests fail, problems can be reported to [link __reporting_problems__ here].]
+ ]
+ [
+ [Examples]
+ [Yes]
+ [There are some examples provided with the library in the `libs/cgi/example` directory. They are useful for learning the library or testing your server configuration, something that can be tricky. They can all be found in the lib/cgi/example directory. Invoking `bjam` in the example directory should build all examples whereas invoking `bjam` in each sub-directory will build only the example contained therein.]
+ ]
+]
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,12 @@
+
+
+[section:utilities Utilities]
+
+['[*TODO]: Document using Utilties]
+
+[include utilities/stencils.qbk]
+
+[include utilities/sessions.qbk]
+
+[endsect] [/ utilities]
+

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/sessions.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/sessions.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,3 @@
+
+
+[include sessions/sessions.qbk]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/sessions/sessions.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/sessions/sessions.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,20 @@
+[/
+ / Copyright (c) 2007-2009 Darren Garvey
+ /
+ / 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)
+ /]
+
+[section:sessions Sessions Quickstart]
+
+['[*TODO]: Sessions Quickstart]
+
+[h3 10 minute intro]
+
+The following example is generated from the linked [@../src/utilities/sessions/sessions_quickstart.cpp source file].
+
+[import sessions_quickstart.cpp]
+
+[sessions_quickstart]
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/sessions/sessions_quickstart.html
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/sessions/sessions_quickstart.html 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "DTD/xhtml1-strict.dtd">
+<html>
+<head>
+ <title>Basic Login Example</title>
+ <style type="text/css">
+ body {
+ width: 100%;
+ padding: 0;
+ margin: 0;
+ }
+ #body {
+ padding: 10px;
+ width: 400px;
+ }
+{{#LOGIN_FORM}}
+ #login-form {
+ background: #C8F0B7;
+ border:2px solid #98D087;
+ padding:10px;
+ }
+ #login-form label {
+ float: left;
+ text-align: right;
+ padding: 0px 10px;
+ width: 150px;
+ display: block;
+ }
+ #login-form input {
+ margin: 0 10px;
+ }
+{{/LOGIN_FORM}}
+{{#HAS_ERROR}}
+ div.error {
+ border: 2px solid #dd4444;
+ background: #ffaaaa;
+ padding: 5px 10px;
+ text-align: center;
+ -moz-border-radius: 10px;
+ }
+{{/HAS_ERROR}}
+ </style>
+</head>
+<body>
+
+<div id="body">
+
+{{#HAS_ERROR}}
+ <div class="error">{{error}}</div>
+{{/HAS_ERROR}}
+
+Last Accessed: {{last_accessed}} UTC
+
+{{#AUTHENTICATED_PAGE}}
+ {{! This is a comment. Note that the ":h" below is a modifier that HTML-encodes the email address.}}
+ <p>Hello, <a href="mailto:{{user_email:h}}">{{user_name:h}}</a> from {{user_location}}!</p>
+ <p>Log Out</p>
+{{/AUTHENTICATED_PAGE}}
+
+{{#DEFAULT_PAGE}}
+ <p>Hello, world.</p>
+{{/DEFAULT_PAGE}}
+
+{{#LOGIN_FORM}}
+ <p>Log in below.</p>
+
+ <form id="login-form" method="post">
+ <div>
+ <label for="name">Name:</label>
+ <input type="text" id="name" name="name" value="{{user_name}}">
+ </div>
+ <div>
+ <label for="pass">Password:</label>
+ <input type="password" id="pass" name="pass" value="">
+ </div>
+ <input type="hidden" name="login" value="1">
+ <input type="submit" name="submit" value="Submit">
+ </form>
+{{/LOGIN_FORM}}
+</div>
+
+</body>
+</html>
\ No newline at end of file

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/stencils.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/utilities/stencils.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,9 @@
+
+[section:stencils Stencils (HTML, XML, JSON, etc.)]
+
+['[*TODO]: Document using `common::stencil`]
+
+[note Requires cTemplate, from Google]
+
+
+[endsect] [/ stencils]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/authorizer/main.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/authorizer/main.cpp 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,107 @@
+// -- main.hpp --
+//
+// Copyright (c) Darren Garvey 2010.
+// 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)
+//
+////////////////////////////////////////////////////////////////
+//
+//[fcgi_authoriser
+
+#include <boost/cgi/fcgi.hpp>
+
+#include <fstream>
+using namespace std;
+namespace fcgi = boost::fcgi;
+
+template<typename Response, typename RequestData, typename String>
+void dump_map(Response& resp, RequestData& data, String title)
+{
+ if (!data.empty())
+ {
+ typedef typename RequestData::iterator iterator;
+ resp<< title << '\n';
+ for (iterator iter = data.begin(), end = data.end();
+ iter != end;
+ ++iter)
+ {
+ resp<< iter->first << " = " << iter->second << '\n';
+ }
+ }
+}
+
+int handle_request(fcgi::request& req)
+{
+ req.load(fcgi::parse_all);
+
+ fcgi::response resp;
+
+ if (req.role() == fcgi::authorizer)
+ {
+ ofstream ofs("../logs/authoriser.log", ios::out | ios::app);
+ ofs<< time(NULL) << "::Checked:: " << req.role() << endl;
+ dump_map(ofs, req.env, "Environment variables.");
+ dump_map(ofs, req.get, "Get variables.");
+ dump_map(ofs, req.post, "Post variables.");
+ dump_map(ofs, req.cookies, "Cookies.");
+ dump_map(ofs, req.uploads, "Uploads.");
+
+ // Note that this (and any other) HTTP header can go either before or after
+ // the response contents.
+ if (req.env.count("remote_user") && req.env.count("remote_passwd"))
+ {
+ if (req.env["remote_user"] == "test"
+ && req.env["remote_passwd"] == "test")
+ {
+ resp<< fcgi::header("Status", "200");
+ // Send the response to the client that made the request.
+ return fcgi::commit(req, resp);
+ }
+ }
+ }
+ else
+ {
+ ofstream ofs("../logs/authenticator.log", ios::out | ios::app);
+ ofs<< time(NULL) << "::Checked::" << req.role() << endl;
+ dump_map(ofs, req.env, "Environment variables.");
+ dump_map(ofs, req.get, "Get variables.");
+ dump_map(ofs, req.post, "Post variables.");
+ dump_map(ofs, req.cookies, "Cookies.");
+ dump_map(ofs, req.uploads, "Uploads.");
+
+ // Note that this (and any other) HTTP header can go either before or after
+ // the response contents.
+ if (req.env.count("remote_user"))
+ {
+ if (req.env["remote_user"] == "test")
+ {
+ resp<< fcgi::header("Status", "200");
+ // Send the response to the client that made the request.
+ return fcgi::commit(req, resp);
+ } else
+ resp<< "Wrong parameters.";
+ } else
+ resp<< "The FastCGI authenticator did not receive the necessary parameters.";
+ }
+ resp<< "Hello, world"
+ << fcgi::header("Status", "401")
+ << fcgi::http::unauthorized;
+
+ // Send the response to the client that made the request.
+ return fcgi::commit(req, resp);
+}
+
+int main()
+{
+ fcgi::service service;
+ fcgi::acceptor acceptor(service);
+
+ int status(0);
+ while (!status)
+ {
+ status = acceptor.accept(&handle_request);
+ }
+ return status;
+}
+//]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies/doc.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies/doc.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,19 @@
+
+[section Cookies]
+
+[import main.cpp]
+
+This file uses [@http://code.google.com/p/google-ctemplate/ Google cTemplate] to show the benefits of using an HTML template engine[footnote cTemplate isn't just an HTML templating engine. This library is in no way affiliated with cTemplate, etc, etc. :)].
+
+Using cTemplate to separate /displaying/ the response with figuring out /what to respond with/ allows for flexible applications. The 'templates' (aka. 'stencils') can be text files or strings built into your application so you can provide multiple formats of the same data by simply providing multiple template files.
+
+Of course, if you are familiar with any other languages or any web programming at all then none of this will be new to you: This is Model-View-Controller programming.
+
+[headers]
+
+[main]
+
+See the [@../../example/cgi/cookies/main.cpp full source listing].
+
+[endsect][/ cookies]
+

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies/main.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies/main.cpp 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -1,25 +1,23 @@
 // -- main.hpp --
 //
-// Copyright (c) Darren Garvey 2007-2009.
+// Copyright (c) Darren Garvey 2007-2010.
 // 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)
 //
 //////////////////////////////////////////////////////////////////
 //
-//[cgi_cookies
-//
 // Cookie Test With cTemplate
 // --------------------------
 //
 // This file uses Google cTemplate [1] to show the benefits of using an HTML
-// template engine. Using cTemplate to separate how you show the response and
-// how you figure out what to respond with, is keeping to the MVC paradigm.
-// Read up on that if you're not familiar; if you already are, you can
-// probably stop scowling at the last cookie_game example now.
+// template engine [2]. Using cTemplate to separate how you show the response and
+// how you figure out what to respond with, is keeping with the MVC paradigm.
 //
 // [1] - http://code.google.com/p/google-ctemplate/
+// [2] - cTemplate isn't just an HTML templating engine.
 //
+//[headers
 #include <boost/cgi/cgi.hpp>
 #include <ctemplate/template.h>
 #include <boost/throw_exception.hpp>
@@ -35,7 +33,7 @@
 
 //[main
 
-using namespace boost::cgi;
+namespace cgi = boost::cgi;
 namespace fs = boost::filesystem;
 
 // The types we use. Only here because this is an example.
@@ -45,25 +43,6 @@
 // You will usually load a template and then populate variables in it
 // using a TemplateDictionary.
 typedef ctemplate::TemplateDictionary dictionary_type;
-// The acgi and fcgi parts of the CGI library use a `service` class to
-// manage asynchronous dispatching (eg. async I/O). If you're not interested
-// in async I/O, you can just use the plain cgi stuff (which is the same as
-// acgi, but without the *a*sync bits).
-// If you're unsure, you can use acgi without having to really do anything with
-// the service - it's only used on two lines in this example. In one of them
-// it is constructed...
-typedef service service_type;
-// ... and on the other it's used to construct the `request`.
-typedef request request_type;
-// The `response` will make your life easier (and more efficient).
-typedef response response_type;
-
-// These are some of the functions / types / enums used in this example.
-using boost::cgi::cookie;
-using boost::cgi::header;
-using boost::cgi::redirect;
-using boost::cgi::parse_all;
-using boost::cgi::content_type;
 
 // This function just makes it easier to change the templating engine. It's
 // only here to keep the cTemplate code out of the core of this example...
@@ -99,29 +78,28 @@
 int main()
 {
   try {
- request_type req;
+ cgi::request req;
 
- response_type resp;
+ cgi::response resp;
 
     // Check if we are resetting the user.
     if (req.form.count("reset") && req.form["reset"] == "true")
     {
- resp<< cookie("name") // delete the 'name' cookie.
- << redirect(req, req.script_name()); // redirect them.
- resp.send(req.client());
- return 0;
+ resp<< cgi::cookie("name") // delete the 'name' cookie.
+ << cgi::redirect(req, req.script_name()); // redirect them.
+ return cgi::commit(req, resp);
     }
 
     if (req.form.count("name"))
     {
       // If requested by the user, delete the cookie.
       if (req.form.count("del"))
- resp<< cookie(req.form["name"]);
+ resp<< cgi::cookie(req.form["name"]);
       else // Set the cookie.
- resp<< cookie(req.form["name"], req.form["value"]);
- resp<< redirect(req, req.script_name());
+ resp<< cgi::cookie(req.form["name"], req.form["value"]);
+ resp<< cgi::redirect(req, req.script_name());
       // Exit here.
- return commit(req, resp, http::ok);
+ return cgi::commit(req, resp);
     }
 
     dictionary_type dict("cookie-game dict");
@@ -149,11 +127,11 @@
     stencil->Expand(&output, &dict);
 
     // Add the template to the response.
- resp<< content_type("text/html")
+ resp<< cgi::content_type("text/html")
         << output;
 
     // Send the response to the requestor and return control.
- return commit(req, resp, http::ok);
+ return cgi::commit(req, resp);
 
   }catch(boost::system::system_error& err){
     std::cerr<< "System Error: [" << err.code() << "] - " << err.what() << std::endl;

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/Jamfile.v2 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,64 @@
+# Copyright (c) 2007 Darren Garvey
+#
+# 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)
+
+project boost/cgi/example/acgi/cookie_game2 ;
+
+import os ;
+
+lib ctemplate ;
+#lib ctemplate : : <name>ctemplate <search>C:/Packages/ctemplate/lib ;
+
+exe acgi_cookie_game2
+ :
+ main.cpp
+ :
+ <library>ctemplate
+ :
+ <linkflags>-lctemplate
+ ;
+
+# Our install rule (builds binaries and copies them to <location>)
+install install-exe
+ :
+ acgi_cookie_game2
+ :
+ <location>$(cgi-bin)
+ ;
+
+install install-css
+ :
+ style.css
+ :
+ <location>$(htdocs)/css/
+ ;
+
+install install-js
+ :
+ main.js
+ :
+ <location>$(htdocs)/js/
+ ;
+
+install install-extra
+ :
+ index.html
+ :
+ <location>$(htdocs)/../templates/
+ ;
+
+explicit install-exe ;
+explicit install-extra ;
+
+install install
+ :
+ install-exe
+ install-css
+ install-js
+ install-extra
+ ;
+
+# Only install example if you use `bjam install' or equivalent
+explicit install ;

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/doc.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/doc.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,37 @@
+
+[section MVC Cookie Game]
+
+This example shows the user their cookies and allows them to set and delete them. It uses Google.cTemplate to move HTML out of the program and into HTML template files, which would be easily editable by anyone familiar with HTML.
+
+If you're not familiar with the term, [@http://wikipedia.org/wiki/Model-View-Controller read up on MVC]. The additional time you'll spend learning an HTML templating library, such as Google.cTemplate, will be saved many times over when compiling your CGI app starts taking more than a few seconds!
+
+[note
+ You need to download and install [@http://code.google.com/p/google-ctemplate Google's cTemplate library] and you may have to modify Jamfile.v2 to point to your compiled ctemplate library (see the `lib ctemplate ...` lines).
+]
+
+You can try a demo of the MVC Cookie Game example [@http://omnisplat.com/cgi/cgi_cookie_game2 here].
+
+[import main.cpp]
+
+[section Headers]
+
+[headers]
+
+[endsect][/ headers]
+
+[section Code]
+
+[main]
+
+[endsect][/ code]
+
+[table Files used for this example:
+ [[File] [Contents]]
+ [[[@../../example/cgi/cookie_game2/main.cpp main.cpp]] [The C++ source.]]
+ [[[@../../example/cgi/cookie_game2/style.css style.css]] [CSS styling for the response.]]
+ [[[@../../example/cgi/cookie_game2/main.js main.js]] [Javascript functions (for changing between GET and POST requests.]]
+ [[[@../../example/cgi/cookie_game2/index.html index.html]] [The HTML template itself.]]
+]
+
+[endsect][/ echo]
+

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/index.html
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/index.html 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,53 @@
+
+
+<html>
+<head>
+ <title>aCGI Cookie Game Example (using Google cTemplate)</title>
+ <link rel="stylesheet" type="text/css" href="/css/style.css" />
+ <script type="text/javascript" src="/js/main.js"></script>
+</head>
+<body>
+
+{{#HAS_NAME_IN_COOKIE_true}}
+ <h1>Hello again {{USER_NAME}}</h1>
+ <p></p>
+{{/HAS_NAME_IN_COOKIE_true}}
+{{#HAS_NAME_IN_COOKIE_false}}
+ <h1>Hello there.</h1>
+{{/HAS_NAME_IN_COOKIE_false}}
+
+<p>Here is list of the cookies you currently have for this site:</p>
+
+{{#DATA_MAP}}
+ {{#ERROR}}
+ EMPTY
+ {{/ERROR}}
+ <ul class="nvpair">
+ {{#ROW}}
+ <li class="name">{{NAME}}</li>
+ <li class="value">{{VALUE}}
+ Remove
+ </li>
+ {{/ROW}}
+ <div class="clear"></div>
+ </ul>
+{{/DATA_MAP}}
+
+<p>
+ You can add cookies using the form below.
+ If you add a cookie value for 'name', it will show up above.
+</p>
+
+ <form method="get" action="{{SCRIPT_NAME}}" id="getform">
+ <label for="name" class="name">Name:</label>
+ <input id="name" name="name" class="value" type="text" value=" {{COOKIE_NAME}}"></input>
+ <label for="value" class="name">Value:</label>
+ <input id="value" name="value" class="value" type="text" value=" {{COOKIE_VALUE}}"></input>
+ <label for="del" class="name">Delete this cookie?</label>
+ <input id="del" name="del" class="value" type="checkbox"></input>
+ <div class="clear"></div>
+ <input type="submit"></input>
+ </form>
+ <input type="submit" onclick="switch_method('getform'); switch_value(this); return false;" value="Switch to POST"></input>
+</body>
+</html>
\ No newline at end of file

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/main.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/main.cpp 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,170 @@
+// -- main.hpp --
+//
+// Copyright (c) Darren Garvey 2007-2009.
+// 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)
+//
+//////////////////////////////////////////////////////////////////
+//cgi_cookie_game2
+//
+// Cookie Test With cTemplate
+// --------------------------
+//
+// This file uses Google cTemplate [1] to show the benefits of using an HTML
+// template engine. Using cTemplate to separate how you show the response and
+// how you figure out what to respond with, is keeping to the MVC paradigm.
+// Read up on that if you're not familiar; if you already are, you can
+// probably stop scowling at the last cookie_game example now.
+//
+// [1] - http://code.google.com/p/google-ctemplate/
+//
+//[headers
+#include <boost/cgi/cgi.hpp>
+#include <ctemplate/template.h>
+#include <boost/throw_exception.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/filesystem.hpp>
+//
+
+/**
+ * The following example has a few stages.
+ * It is best understood by compiling and testing it, and then looking at
+ * the source code.
+ */
+
+//main
+
+using namespace boost::cgi;
+namespace fs = boost::filesystem;
+
+// The types we use. Only here because this is an example.
+
+// Uses cTemplate, from Google. It's simple and powerful.
+typedef ctemplate::Template stencil_type;
+// You will usually load a template and then populate variables in it
+// using a TemplateDictionary.
+typedef ctemplate::TemplateDictionary dictionary_type;
+// The acgi and fcgi parts of the CGI library use a `service` class to
+// manage asynchronous dispatching (eg. async I/O). If you're not interested
+// in async I/O, you can just use the plain cgi stuff (which is the same as
+// acgi, but without the *a*sync bits).
+// If you're unsure, you can use acgi without having to really do anything with
+// the service - it's only used on two lines in this example. In one of them
+// it is constructed...
+typedef service service_type;
+// ... and on the other it's used to construct the `request`.
+typedef request request_type;
+// The `response` will make your life easier (and more efficient).
+typedef response response_type;
+
+// These are some of the functions / types / enums used in this example.
+using boost::cgi::cookie;
+using boost::cgi::header;
+using boost::cgi::redirect;
+using boost::cgi::parse_all;
+using boost::cgi::content_type;
+
+// This function just makes it easier to change the templating engine. It's
+// only here to keep the cTemplate code out of the core of this example...
+stencil_type* get_stencil(std::string const& filename)
+{
+ if (!fs::exists(filename))
+ throw std::runtime_error(
+ std::string("Template file not found: '")
+ + fs::path(filename).string() + "'");
+ else
+ return ctemplate::Template::GetTemplate(
+ filename, ctemplate::STRIP_WHITESPACE);
+}
+
+// Show the data in the passed map, updating the passed dictionary.
+template<typename MapT, typename Dict>
+void print_formatted_data(MapT& data, Dict& dict)
+{
+ Dict* subd = dict.AddSectionDictionary("DATA_MAP");
+ if (data.empty())
+ subd->ShowSection("EMPTY");
+ else
+ for(typename MapT::const_iterator iter=data.begin(), end = data.end(); iter != end; ++iter)
+ {
+ Dict* row_dict = subd->AddSectionDictionary("ROW");
+ row_dict->SetValue("NAME", iter->first.c_str());
+ row_dict->SetValue("VALUE", iter->second.c_str());
+ row_dict->ShowSection("ROW");
+ }
+}
+
+
+int main()
+{
+ try {
+ request_type req;
+
+ // Load up the request data
+ req.load(parse_all);
+
+ response_type resp;
+
+ // Check if we are resetting the user.
+ if (req.form.count("reset") && req.form["reset"] == "true")
+ {
+ resp<< cookie("name") // delete the 'name' cookie.
+ << redirect(req, req.script_name()); // redirect them.
+ resp.send(req.client());
+ return 0;
+ }
+
+ if (req.form.count("name"))
+ {
+ // If requested by the user, delete the cookie.
+ if (req.form.count("del"))
+ resp<< cookie(req.form["name"]);
+ else // Set the cookie.
+ resp<< cookie(req.form["name"], req.form["value"]);
+ resp<< redirect(req, req.script_name());
+ // Exit here.
+ return commit(req, resp, http::ok);
+ }
+
+ dictionary_type dict("cookie-game dict");
+
+ // First, see if they have a cookie set
+ if (req.cookies.count("name"))
+ dict.SetValueAndShowSection("USER_NAME", req.cookies["name"].c_str(),
+ "HAS_NAME_IN_COOKIE_true");
+ else
+ dict.ShowSection("HAS_NAME_IN_COOKIE_false");
+
+ print_formatted_data(req.cookies, dict);
+
+ dict.SetValue("SCRIPT_NAME", req.script_name());
+ // pick() looks up the key in the map, returns a default value
+ // (ie. anonymous) if the key isn't found.
+ dict.SetValue("COOKIE_NAME", req.form.pick("name", "anonymous"));
+ dict.SetValue("COOKIE_VALUE", req.form["value"]);
+
+ // Load the HTML stencil now from the index.html file.
+ stencil_type* stencil = get_stencil("../stencils/index.html");
+
+ // Expand the stencil with the the given dictionary into `output`.
+ std::string output;
+ stencil->Expand(&output, &dict);
+
+ // Add the template to the response.
+ resp<< content_type("text/html")
+ << output;
+
+ // Send the response to the requestor and return control.
+ return commit(req, resp, http::ok);
+
+ }catch(boost::system::system_error& err){
+ std::cerr<< "System Error: [" << err.code() << "] - " << err.what() << std::endl;
+ }catch(std::exception const& e){
+ std::cerr<< "Exception: [" << typeid(e).name() << "] - " << e.what() << std::endl;
+ }catch(...){
+ std::cerr<< "boom<blink>!</blink>";
+ }
+}
+//]
+

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/main.js
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/main.js 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,30 @@
+function switch_method(ident) {
+ var f = document.getElementById(ident);
+ if (f.method == 'post') f.method = 'GET';
+ else f.method = 'POST';
+}
+function switch_value(elem) {
+ if (elem.value == 'Switch to POST') {
+ elem.value = 'Switch to GET';
+ }else{
+ elem.value = 'Switch to POST';
+ }
+}
+function switch_form(elem) {
+ var g = document.getElementById('getform');
+ var p = document.getElementById('postform');
+ if (elem.value == 'Switch to POST') {
+ p.style.visibility = 'visible';
+ p.style.display = 'block';
+ g.style.visibility = 'hidden';
+ g.style.display = 'none';
+ elem.value = 'Switch to GET';
+ } else {
+ g.style.visibility = 'visible';
+ g.style.display = 'block';
+ p.style.visibility = 'hidden';
+ p.style.display = 'none';
+ elem.value = 'Switch to POST';
+ }
+}
+

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/style.css
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/cookies2/style.css 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -0,0 +1,116 @@
+body { padding: 0; margin: 3%; border-color: #efe; }
+.var_map_title
+ { font-weight: bold; font-size: large; }
+.var_map
+ { border: 1px dotted; padding: 2px 3px 2px 3px; margin-bottom: 3%; }
+.pair
+ { border-top: 1px dotted; overflow: auto; padding: 0; margin: 0; }
+/*
+.name
+ { position: relative; float: left; width: 30%; font-weight: bold; }
+.value
+ { position: relative; float: left; width: 65%; left: 1%;
+ border-left: 1px solid; padding: 0 5px 0 5px;
+ overflow: auto; white-space: pre; }
+*/
+.info
+{
+ border-color: #ca3766;
+ border-width: 1px 0 1px 0;
+ border-style: solid;
+ padding: 2px 8px 2px 8px;
+ margin: 1em
+}
+#response
+{
+ text-align: center;
+ padding: 20px 30px 20px 30px;
+ margin: 1em;
+ border-width: 2px 0 2px 0;
+ border-style: solid;
+ border-color: #ca3766;
+}
+.var_map_title
+{
+ font-weight: bold;
+ font-size: large;
+}
+.var_map
+{
+ border: 1px dotted;
+ padding: 2px 3px 2px 3px;
+ margin: 15px 0 15px 0;
+}
+.var_pair
+{
+ border-top: 1px dotted;
+ overflow: auto;
+ padding: 0;
+ margin: 0;
+}
+.var_name
+{
+ position: relative;
+ float: left;
+ width: 30%;
+ font-weight: bold;
+}
+.var_value
+{
+ position: relative;
+ float: left;
+ width: 65%;
+ left: 1%;
+ border-left: 1px solid;
+ padding: 0 5px 0 5px;
+ overflow: auto;
+ white-space: pre;
+}
+.nvpair
+{
+ list-style-type: none;
+}
+.nvpair a
+{
+ float: right;
+}
+form
+{
+}
+input
+{
+border-width: 0 0 1px 0;
+border-style: solid;
+border-color: #444;
+padding: 2px 3px 2px 3px;
+margin-left: 1em;
+background: #FaFbFd;
+}
+input[type=submit]
+{
+ margin-left: 35%;
+}
+.name, .value
+{
+ display: inline;
+ width: 20%;
+ float: left;
+}
+.name
+{
+ text-align: right;
+ padding-right: 1em;
+ clear: left;
+}
+.value
+{
+ text-align: left;
+ padding-left: 1em;
+}
+.clear { clear: both; }
+.cookies { margin: 10px 0 25px 0; }
+#postform
+{
+ visibility: hidden;
+ display: none;
+}

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/doc.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/doc.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/doc.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -9,8 +9,6 @@
 
 [include cookies/doc.qbk]
 
-[include cookies2/doc.qbk]
-
 [include file_browser/doc.qbk]
 
 [include stencil/doc.qbk]

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/stencil/doc.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/stencil/doc.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/stencil/doc.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -3,7 +3,9 @@
 
 [import main.cpp]
 
-[cgi_stencil]
+[cgi_stencil_headers]
+
+[cgi_stencil_main]
 
 See the [@../../example/cgi/stencil/main.cpp full source listing].
 

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/stencil/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/stencil/main.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/stencil/main.cpp 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -7,22 +7,22 @@
 //
 ////////////////////////////////////////////////////////////////
 //
-// [cgi_stencil
-//
-
+//[cgi_stencil_headers
 #include <iostream>
 #include <boost/cgi/cgi.hpp>
 #include <boost/cgi/utility/stencil.hpp>
+//]
 
-using namespace boost::cgi;
+//[cgi_stencil_main
+namespace cgi = boost::cgi;
 
-int handle_request(request& req)
+int handle_request(cgi::request& req)
 {
- req.load(parse_all);
+ req.load(cgi::parse_all);
   
   // Construct a response that uses Google cTemplate. Also sets the root
   // directory where the stencils are found.
- stencil resp("../stencils/");
+ cgi::stencil resp("../stencils/");
 
   //// Test 1.
 
@@ -30,7 +30,7 @@
   // the response text.
   // The content of the response - which is everything streamed to it - is
   // added to a {{content}} field in the stencil.
- resp<< content_type("text/html")
+ resp<< cgi::content_type("text/html")
       << "Hello there, universe!";
       
   //// Test 2.
@@ -53,7 +53,7 @@
   // Show a section, conditionally.
   
   // Use the "show" GET variable, or default to the string "show" if not set.
- request::string_type show = req.get.pick("show", "show");
+ cgi::request::string_type show = req.get.pick("show", "show");
   resp.set("show", show == "show" ? "hide" : "show");
   if (show == "show")
     resp.show("some_section"); // Shows {{#some_section}}...{{/some_section}}.
@@ -64,7 +64,7 @@
   if (num < 0) num = 0;
   resp.set("show_less", num ? num - 1 : 0);
   resp.set("show_more", num + 1);
- stencil::section sec("section_with_variable");
+ cgi::section sec("section_with_variable");
   for (int i(0); i < num; ++i)
   {
     // We can show a section and set one field in it in one go.
@@ -73,7 +73,7 @@
   
   //// Test 5.
 
- dictionary test5 = resp.add("test5");
+ cgi::dictionary test5 = resp.add("test5");
   test5.add("input")
     .set("type", "text")
     .set("name", "text")
@@ -124,19 +124,19 @@
 
   //// Test 6.
 
- resp.add(stencil::section("embedded")).set("test", "passed");
+ resp.add(cgi::section("embedded")).set("test", "passed");
   
- dictionary dict = resp.add("embedded");
+ cgi::dictionary dict = resp.add("embedded");
   dict.add("subsection") // returns a new sub-dictionary.
       .set("test", "passed again")
       .set("other", "(another field)");
- dict.set("test", "passed yet again", stencil::section("subsection"));
+ dict.set("test", "passed yet again", cgi::section("subsection"));
 
   //// Test 7.
 
   // Include another stencil into this one at marker {{>include}}.
   resp.include(
- stencil::section(
+ cgi::section(
           "include",
           "cgi_stencil.include.html"
         )
@@ -145,7 +145,8 @@
   // Short-cut for stencil includes.
   resp.include("include", "cgi_stencil.include.html");
   
- resp<< cookie("name", "value");
+ // Set a session cookie, which expires when the user closes their browser.
+ resp<< cgi::cookie("name", "value");
 
   /// End Tests.
   
@@ -155,14 +156,14 @@
   resp.expand("cgi_stencil.html");
 
   // Send the response and close the request.
- return commit(req, resp);
+ return cgi::commit(req, resp);
 }
   
 int main()
 {
 try {
   
- request req;
+ cgi::request req;
   if (handle_request(req))
     std::cerr<< "Error returned from handling request." << std::endl;
   else

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/doc.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/doc.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/doc.qbk 2010-05-16 05:28:05 EDT (Sun, 16 May 2010)
@@ -1,19 +1,19 @@
 
 [section Examples]
 
-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:
+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 one of two ways:
 
 [h4 Command Line]
 
-``$ bjam install --cgi-bin=/usr/lib/cgi-bin``
+``shell> bjam install --cgi-bin=/usr/lib/cgi-bin``
 
 Installs the CGI program (or set of programs) into `/usr/lib/cgi-bin`. If you want to install FastCGI examples from the `/libs/cgi/example/fcgi/` directory, for instance, type the above but replace `--cgi-bin=...` with `--fcgi-bin=...`.
 
 [h4 Environment Variables]
 
-Set the environment variable(s) `BOOST_CGI_BIN_PATH` (or `BOOST_FCGI_BIN_PATH`/`BOOST_SCGI_BIN_PATH`), then type:
+Set the environment variable(s) `BOOST_CGI_BIN_PATH` or `BOOST_FCGI_BIN_PATH`, then type:
 
-``$ bjam install``
+``shell> bjam install``
 
 The example(s) will be installed into the relevant directory.
 


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