Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r59939 - in sandbox/SOC/2007/cgi/trunk: . boost/cgi boost/cgi/cgi boost/cgi/common boost/cgi/detail boost/cgi/fcgi boost/cgi/fwd boost/cgi/impl boost/cgi/utility libs/cgi/build/msvc/9.0/Boost.CGI libs/cgi/build/msvc/9.0/Boost.CGI/cgi_quickstart libs/cgi/build/msvc/9.0/Boost.CGI/cgi_sessions libs/cgi/build/msvc/9.0/Boost.CGI/cgi_stencil libs/cgi/build/msvc/9.0/Boost.CGI/fastcgi_quickstart libs/cgi/doc libs/cgi/doc/src libs/cgi/doc/src/overview libs/cgi/doc/src/overview/requests libs/cgi/doc/src/tutorial libs/cgi/example/cgi/sessions libs/cgi/example/cgi/stencil libs/cgi/example/fcgi/amortization libs/cgi/example/fcgi/charts libs/cgi/test/run
From: lists.drrngrvy_at_[hidden]
Date: 2010-02-25 23:43:23


Author: drrngrvy
Date: 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
New Revision: 59939
URL: http://svn.boost.org/trac/boost/changeset/59939

Log:
* Making protocol_traits a public class template.
* Cleaned up basic_client<> to take the connection from protocol_traits rather than as a template argument.
* Initial session support (disabled by default).
* Added sessions example.
* Added some new docs - partial commit.
* Altered data_map_proxy<>.
* Ignore "decorated name length exceeded" warning from MSVC.
* Housekeeping.
* Removed scgi stuff (not currently supported).

Added:
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/protocol_traits.hpp
      - copied, changed from r59402, /sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/protocol_traits.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/sessions.hpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_quickstart/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_quickstart/cgi_quickstart.vcproj (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_sessions/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_sessions/cgi_sessions.vcproj (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/fastcgi_quickstart/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/fastcgi_quickstart/fastcgi_quickstart.vcproj (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/cgi.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/acceptors.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/clients.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/requests/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/requests.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/requests/loading.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/responses.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/services.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/0-old-fastcgi_quickstart.cpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/Copy of fastcgi_quickstart.cpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/cgi.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/cgi_quickstart.cpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/cookies.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi_quickstart.cpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/hello_world.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/quickstart.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/requests.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/running.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/scaling.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/tutorial.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/variables.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/sessions/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/sessions/main.cpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/charts/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/charts/charts.html
      - copied unchanged from r59404, /sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/fcgi_stencil/templates/stencil.html
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/charts/charts.include.html
      - copied unchanged from r59404, /sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/fcgi_stencil/templates/stencil.include.html
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/charts/main.cpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/cgi_test.cpp (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/data_map_proxy.cpp (contents, props changed)
Removed:
   sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/utility.hpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/responses.qbk
Text files modified:
   sandbox/SOC/2007/cgi/trunk/README.txt | 11 +++-
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_client.hpp | 25 +++-----
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request.hpp | 91 ++++++++++++++++++++-------------
   sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi.hpp | 1
   sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request.hpp | 1
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/basic_protocol_service.hpp | 47 ++++++++++++----
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/commit.hpp | 5 +
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/cookie.hpp | 7 +-
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/data_map_proxy.hpp | 45 +++++++++++++---
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/form_part.hpp | 14 +++++
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/map.hpp | 5 -
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/protocol_traits.hpp | 77 ++++++++++------------------
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_base.hpp | 21 +++----
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_service.hpp | 56 +--------------------
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/response.hpp | 6 +-
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/basic_io_object.hpp | 4
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/common_headers.hpp | 4 +
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/push_options.hpp | 5 +
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi.hpp | 1
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/client.hpp | 29 ++++------
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/specification.hpp | 7 ++
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fwd/basic_client_fwd.hpp | 2
   sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/response.ipp | 1
   sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/redirect.hpp | 24 ++++----
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.sln | 59 +++++++++-------------
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_stencil/cgi_stencil.vcproj | 4 -
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/Jamfile.v2 | 105 ++++++++++++++++++++-------------------
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/cgi.qbk | 16 ++++-
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/stencil/main.cpp | 6 +-
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/main.cpp | 2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/Jamfile.v2 | 13 ++--
   31 files changed, 351 insertions(+), 343 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-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -5,6 +5,10 @@
 
 ------------------------------------------------------------
 
+Websites for more information on this library are:
+ http://cgi.sf.net
+ http://omnisplat.com
+
 Check the library works ok by first running the tests + compiling the examples.
 
 These are all in the
@@ -13,15 +17,16 @@
 
 directory (see Jamfile.v2 for build instructions).
 
-Note that some of the 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 cTemplate, so they will fail to compile unless you have that installed.
 
 The tests aren't exhaustive - this library is still under development.
 
 Currently tested on
 
 Ubuntu 8.04 desktop 32bit
+Ubuntu 9.10 desktop 32bit
 Ubuntu 8.04 server 64bit
-MSVC 2008
+MSVC 2008 Windows XP
 
-FastCGI stuff only works on linux at the moment. If you're a Windows network programmer, can you help?
+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.
 

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_client.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_client.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_client.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -12,11 +12,11 @@
 #include <boost/shared_ptr.hpp>
 ///////////////////////////////////////////////////////////
 #include "boost/cgi/common/map.hpp"
+#include "boost/cgi/common/protocol_traits.hpp"
 #include "boost/cgi/common/role_type.hpp"
 #include "boost/cgi/common/request_status.hpp"
 #include "boost/cgi/connections/tcp_socket.hpp"
 #include "boost/cgi/detail/throw_error.hpp"
-#include "boost/cgi/detail/protocol_traits.hpp"
 #include "boost/cgi/error.hpp"
 #include "boost/cgi/http/status_code.hpp"
 
@@ -53,23 +53,18 @@
    * clients aware of how busy the connection is and size its output packets
    * accordingly... But I'm not doing that.
    */
- template<typename Connection, typename Protocol>
+ template<typename Protocol>
   class basic_client
   {
   public:
- //typedef BOOST_CGI_NAMESPACE::map map_type;
- typedef ::BOOST_CGI_NAMESPACE::common::io_service io_service_type;
- typedef ::BOOST_CGI_NAMESPACE::common::map map_type;
- typedef Connection connection_type;
- typedef Protocol protocol_type;
- typedef typename connection_type::pointer connection_ptr;
- typedef boost::array<unsigned char, 8> header_buffer_type;
- typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
- typedef typename
- detail::protocol_traits<
- Protocol
- >::role_type role_type;
-
+ typedef Protocol protocol_type;
+ typedef common::map map_type;
+ typedef protocol_traits<Protocol> traits;
+ typedef typename traits::connection_type connection_type;
+ typedef typename traits::mutable_buffers_type mutable_buffers_type;
+ typedef typename traits::header_buffer_type header_buffer_type;
+ typedef typename connection_type::pointer connection_ptr;
+ typedef typename traits::role_type role_type;
 
     basic_client()
     {

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -16,32 +16,29 @@
 
 #include "boost/cgi/detail/push_options.hpp"
 
-#include <boost/mpl/if.hpp>
-#include <boost/assert.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/noncopyable.hpp>
-#include <boost/optional.hpp>
 #include <boost/functional/hash.hpp>
-#include <boost/asio/io_service.hpp>
 #include <boost/system/error_code.hpp>
-#include <boost/utility/enable_if.hpp>
 ///////////////////////////////////////////////////////////
 #include "boost/cgi/common/data_map_proxy.hpp"
 #include "boost/cgi/common/form_part.hpp"
-#include "boost/cgi/common/has_hidden_io_service.hpp"
 #include "boost/cgi/common/map.hpp"
 #include "boost/cgi/common/parse_options.hpp"
 #include "boost/cgi/common/path_info.hpp"
+#include "boost/cgi/common/protocol_traits.hpp"
 #include "boost/cgi/common/request_service.hpp"
 #include "boost/cgi/common/request_status.hpp"
 #include "boost/cgi/common/role_type.hpp"
 #include "boost/cgi/common/source_enums.hpp"
 #include "boost/cgi/detail/basic_io_object.hpp"
 #include "boost/cgi/detail/throw_error.hpp"
-#include "boost/cgi/detail/protocol_traits.hpp"
 #include "boost/cgi/fwd/basic_request_fwd.hpp"
 #include "boost/cgi/fwd/basic_protocol_service_fwd.hpp"
 #include "boost/cgi/http/status_code.hpp"
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+# include "boost/cgi/utility/sessions.hpp"
+#endif // BOOST_CGI_ENABLE_SESSIONS
 
 #ifndef BOOST_CGI_POST_MAX
     /// Restrict POST data to less than 7MB per request.
@@ -83,13 +80,13 @@
   template<typename Protocol>
   class basic_request
     : public detail::basic_io_object<
- typename detail::protocol_traits<Protocol>::service_type
+ typename protocol_traits<Protocol>::service_type
>
   {
   public:
     typedef basic_request<Protocol> self_type;
     typedef Protocol protocol_type;
- typedef detail::protocol_traits<protocol_type> traits;
+ typedef protocol_traits<protocol_type> traits;
     typedef typename traits::protocol_service_type protocol_service_type;
     typedef typename traits::service_type service_type;
     typedef typename traits::pointer pointer;
@@ -98,6 +95,13 @@
     typedef typename traits::string_type string_type;
     typedef typename traits::client_type client_type;
     typedef typename traits::buffer_type buffer_type;
+ typedef typename traits::session_type session_type;
+
+ string_type session_id_;
+
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+ session_type session;
+#endif // BOOST_CGI_ENABLE_SESSIONS
     
     common::data_map_proxy<env_map> env;
     common::data_map_proxy<post_map> post;
@@ -178,6 +182,23 @@
     {
       //if (is_open())
       // close(http::internal_server_error, 0);
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+ try {
+ if (!session_id_.empty())
+ {
+ if (session.id().empty())
+ session.id(session_id_);
+ this->implementation.service_->save(session);
+ }
+ } catch(...) {
+ // pass
+ }
+#endif // BOOST_CGI_ENABLE_SESSIONS
+ }
+
+ protocol_service_type& get_protocol_service()
+ {
+ return *(this->implementation.service_);
     }
     
     static pointer create(protocol_service_type& ps)
@@ -259,8 +280,12 @@
           post.set(post_vars(this->implementation.vars_));
         if (parse_opts & parse_get_only || parse_opts & parse_get_only)
           uploads.set(upload_vars(this->implementation.vars_));
- if (parse_opts & parse_cookies)
+ if (parse_opts & parse_cookies) {
           cookies.set(cookie_vars(this->implementation.vars_));
+ if (cookies.count("$ssid")) {
+ session_id_ = cookies["$ssid"];
+ }
+ }
         if (parse_opts & parse_form_only)
         {
           common::name rm(request_method().c_str());
@@ -269,6 +294,13 @@
                 rm == "POST" ? post : env
           );
         }
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+ if (!session_id_.empty())
+ {
+ session.id(session_id_);
+ this->implementation.service_->load(session);
+ }
+#endif // BOOST_CGI_ENABLE_SESSIONS
       }
       return ec;
     }
@@ -406,19 +438,6 @@
       return this->service.read_some(this->implementation, buf, ec);
     }
 
- /// Set the output for the request
- /**
- * Not Implemented Yet ******************
- *
- * Set the output sink as `stdout_`, `stderr_`, or `stdout_ | stderr_`
- */
- /*
- void set_output(BOOST_CGI_NAMESPACE::sink dest, boost::system::error_code& ec)
- {
- this->service(this->implementation, dest, ec);
- }
- */
-
     /////////////////////////////////////////////////////////
     // Helper-functions for the basic CGI 1.1 meta-variables.
     /////////////////////////////////////////////////////////
@@ -620,29 +639,29 @@
       return this->service.status(this->implementation);
     }
     
+ /// Set the status of a request.
     void status(common::request_status const& status)
     {
       this->service.status(this->implementation, status);
     }
-
- common::http::status_code status(common::http::status_code const& status) const
- {
- return this->service.status(this->implementation);
- }
-
- void status(common::http::status_code const& status)
- {
- this->service.status(this->implementation, status);
- }
    };
 
+ /// Support for Boost.Hash
+ /**
+ * `basic_request<>` supports Boost.Hash. A request will have the same hash
+ * value if all of the following are the same:
+ *
+ * * PATH_INFO
+ * * QUERY_STRING
+ * * REQUEST_METHOD
+ * * REQUEST_URI
+ */
    template<typename P>
    std::size_t hash_value(basic_request<P> const& req)
    {
      boost::hash<typename basic_request<P>::string_type> hasher;
- return hasher(req.env["REMOTE_ADDR"] + ":"
- + req.env["REMOTE_PORT"] + ":"
- + req.env["HTTP_USER_AGENT"] + ":"
+ return hasher(req.env["PATH_INFO"] + ":"
+ + req.env["QUERY_STRING"] + ":"
                  + req.env["REQUEST_METHOD"] + ":"
                  + req.env["REQUEST_URI"]);
    }

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -22,7 +22,6 @@
 
   typedef cgi_request request;
   using namespace common;
- //typedef BOOST_CGI_NAMESPACE::cgi_service service; // to be added
   
 BOOST_CGI_NAMESPACE_END
 

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -11,7 +11,6 @@
 
 #include "boost/cgi/detail/push_options.hpp"
 
-#include "boost/cgi/detail/protocol_traits.hpp"
 #include "boost/cgi/common/tags.hpp"
 #include "boost/cgi/cgi/service.hpp"
 #include "boost/cgi/cgi/request_service.hpp"

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/basic_protocol_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/basic_protocol_service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/basic_protocol_service.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -16,12 +16,15 @@
 #include <boost/asio/strand.hpp>
 #include <boost/detail/workaround.hpp>
 ///////////////////////////////////////////////////////////
-#include "boost/cgi/import/io_service.hpp"
-#include "boost/cgi/fwd/basic_request_fwd.hpp"
-#include "boost/cgi/detail/protocol_traits.hpp"
+#include "boost/cgi/config.hpp"
+#include "boost/cgi/common/protocol_traits.hpp"
 #include "boost/cgi/common/io_service_provider.hpp"
+#include "boost/cgi/fwd/basic_request_fwd.hpp"
 #include "boost/cgi/fwd/basic_protocol_service_fwd.hpp"
-#include "boost/cgi/config.hpp"
+#include "boost/cgi/import/io_service.hpp"
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+# include "boost/cgi/utility/sessions.hpp"
+#endif // BOOST_CGI_ENABLE_SESSIONS
 
 BOOST_CGI_NAMESPACE_BEGIN
  namespace common {
@@ -33,16 +36,18 @@
    */
   template<typename Protocol, typename IoServiceProvider>
   class basic_protocol_service
- //: public protocol_traits<Protocol> // do this!
   {
   public:
- typedef Protocol protocol_type;
- typedef IoServiceProvider ios_provider_type;
- typedef typename detail::protocol_traits<Protocol>::type traits;
- typedef typename traits::request_type request_type;
- typedef typename boost::shared_ptr<request_type> request_ptr;
- typedef std::set<request_ptr> set_type;
- typedef std::queue<request_ptr> queue_type;
+ typedef Protocol protocol_type;
+ typedef IoServiceProvider ios_provider_type;
+ typedef typename protocol_traits<Protocol>::type traits;
+ typedef typename traits::request_type request_type;
+ typedef typename request_type::pointer request_ptr;
+ typedef std::set<request_ptr> set_type;
+ typedef std::queue<request_ptr> queue_type;
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+ typedef typename traits::session_manager_type session_manager_type;
+#endif // BOOST_CGI_ENABLE_SESSIONS
 
     basic_protocol_service(int pool_size_hint = 1)
       : ios_provider_(pool_size_hint)
@@ -121,6 +126,22 @@
       ios_provider_.get_io_service().dispatch(handler);
     }
 
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+ template<typename T>
+ void save(basic_session<T>& sesh) {
+ session_mgr_.save(sesh);
+ }
+
+ template<typename T>
+ void load(basic_session<T>& sesh) {
+ session_mgr_.load(sesh);
+ }
+
+ private:
+ session_manager_type session_mgr_;
+
+#endif // BOOST_CGI_ENABLE_SESSIONS
+
   private:
     ios_provider_type ios_provider_;
 
@@ -128,7 +149,7 @@
     set_type request_set_;
     /// A std::queue of the waiting (ie. not-being-handled) requests.
     queue_type request_queue_;
-
+
 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400))
     friend typename traits::request_type;//typename request_type;
 #else

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/commit.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/commit.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/commit.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -28,6 +28,11 @@
     int commit(Request& req, Response& resp, int program_status
               , boost::system::error_code& ec)
     {
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+ if (!req.session_id_.empty()) {
+ resp<< cookie("$ssid", req.session_id_);
+ }
+#endif // BOOST_CGI_ENABLE_SESSIONS
       resp.send(req.client(), ec);
       return ec ? -1 : req.close(resp.status(), program_status, ec);
     }

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/cookie.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/cookie.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/cookie.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -121,6 +121,8 @@
     template<typename T>
     operator std::basic_string<T> () { return value; }
     
+ bool operator==(string_type const& other) { return value == other; }
+
     template<typename T>
     friend std::ostream& operator<<(std::ostream& os, basic_cookie<T> const& ck);
   };
@@ -129,9 +131,8 @@
   std::pair<common::name, common::cookie>
     make_pair (const char* n, common::cookie& ck)
   {
- ck.value.swap(ck.name);
- ck.name = n;
- return std::make_pair(n, ck);
+ common::cookie new_cookie(n, ck.name);
+ return std::make_pair(n, new_cookie);
   }
 
   template<typename CharT>

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/data_map_proxy.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/data_map_proxy.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/data_map_proxy.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -55,7 +55,7 @@
     typedef typename map_type::const_reverse_iterator const_reverse_iterator;
     typedef typename map_type::allocator_type allocator_type;
     
- self_type()
+ data_map_proxy()
       : impl(NULL)
     {
     }
@@ -79,7 +79,22 @@
     const_reverse_iterator rend() const {
        BOOST_CGI_MAP_ASSERT(impl); return impl->rend(); }
 
-
+ iterator insert( iterator pos, const value_type& pair ) {
+ BOOST_CGI_MAP_ASSERT(impl);
+ return impl->insert(pos, pair);
+ }
+
+ template<typename InputIterator>
+ void insert(InputIterator start, InputIterator end) {
+ BOOST_CGI_MAP_ASSERT(impl);
+ return impl->insert(start, end);
+ }
+
+ std::pair<iterator,bool> insert(const value_type& pair) {
+ BOOST_CGI_MAP_ASSERT(impl);
+ return impl->insert(pair);
+ }
+
     void set(map_type& data) { impl = &data; }
 
     bool empty() { BOOST_CGI_MAP_ASSERT(impl); return impl->empty(); }
@@ -93,7 +108,7 @@
        return impl->count(key);
     }
 
- /// Get a value for the key, with fallback.
+ /// Get a value for the key, with a fallback when not found.
     mapped_type const&
       pick(key_type const& key, mapped_type const& default_value) const
     {
@@ -102,23 +117,35 @@
       return iter == impl->end() ? default_value : iter->second;
     }
 
+ /// Get a value for the key as a specified type.
+ /**
+ * @param key The name of CGI parameter to look for.
+ *
+ * If the key is found, attempts to convert the value into the type
+ * T. This throws a boost::bad_lexical_cast when it fails.
+ */
+ template<typename T>
+ T as(key_type const& key) const
+ {
+ BOOST_CGI_MAP_ASSERT(impl);
+ return boost::lexical_cast<T>((*impl)[key]);
+ }
+
     /// Get a value for the key as a specified type, with fallback.
     /**
      * @param key The name of CGI parameter to look for.
      * @param default_value
      * The default return value. If no data exists in the map
      * for the specified key, or the data cannot be converted
- * into the type of the default_ value, then this value is
- * returned.
+ * into the type T, then this value is returned.
      *
      * If the key cannot be found, returns a default-constructed object
      * of type T.
      *
- * If the key is found, attempts to convert the value into the type
- * T. This throws a boost::bad_lexical_cast when it fails.
+ * If the key is found, attempts to convert the value into the type T.
      */
     template<typename T>
- T as(key_type const& key, T const& default_value = T()) const
+ T pick(key_type const& key, T const& default_value = T()) const
     {
       BOOST_CGI_MAP_ASSERT(impl);
       const_iterator iter = impl->find(key);
@@ -161,7 +188,7 @@
   private:
     map_type* impl;
   };
-
+
  } // namespace common
 BOOST_CGI_NAMESPACE_END
 

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/form_part.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/form_part.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/form_part.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -29,6 +29,10 @@
        string_type, pair_t
> meta_data_map_type;
      
+ form_part() {}
+ form_part(string_type const& val) : value(val) {}
+ form_part(const char_type* val) : value(val) {}
+
      ~form_part()
      {
      /*
@@ -87,6 +91,16 @@
     return std::make_pair(n, part);
   }
 
+ inline
+ std::pair<common::name, common::form_part>
+ make_pair (const char* n, const char* v)
+ {
+ common::form_part part;
+ part.name = n;
+ part.value = v;
+ return std::make_pair(n, part);
+ }
+
   inline std::ostream& operator<< (std::ostream& os, BOOST_CGI_NAMESPACE::common::form_part const& part)
   {
     os<< part.value;

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/map.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/map.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/map.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -29,10 +29,7 @@
   typedef map get_map;
   typedef map post_map;
   typedef map form_map;
- typedef std::map<
- ::BOOST_CGI_NAMESPACE::common::name,
- ::BOOST_CGI_NAMESPACE::common::cookie
- > cookie_map;
+ typedef map cookie_map;
   typedef std::map<
       ::BOOST_CGI_NAMESPACE::common::name,
       ::BOOST_CGI_NAMESPACE::common::form_part

Copied: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/protocol_traits.hpp (from r59402, /sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/protocol_traits.hpp)
==============================================================================
--- /sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/protocol_traits.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/protocol_traits.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -1,20 +1,13 @@
 // -- protocol_traits.hpp --
 //
-// Copyright (c) Darren Garvey 2007.
+// 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)
 //
 ////////////////////////////////////////////////////////////////
-//
-// Wow this is messy. It's not expected to last though; it's
-// merely here to make things more separated than they need to
-// be, so everything can be meshed together slowly.
-// (or something like that)
-//
-/////////////////////////////////////////////////////////////////
-#ifndef CGI_REQUEST_TRAITS_HPP_INCLUDED__
-#define CGI_REQUEST_TRAITS_HPP_INCLUDED__
+#ifndef BOOST_CGI_PROTOCOL_TRAITS_HPP_INCLUDED_
+#define BOOST_CGI_PROTOCOL_TRAITS_HPP_INCLUDED_
 
 #include <boost/asio/ip/tcp.hpp>
 #include <boost/none.hpp>
@@ -29,9 +22,14 @@
 #include "boost/cgi/fwd/basic_protocol_service_fwd.hpp"
 #include "boost/cgi/fwd/basic_request_fwd.hpp"
 #include "boost/cgi/fwd/form_parser_fwd.hpp"
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+# include "boost/cgi/utility/sessions.hpp"
+#endif // BOOST_CGI_ENABLE_SESSIONS
 
 BOOST_CGI_NAMESPACE_BEGIN
 
+ struct empty;
+
   namespace cgi {}
   namespace fcgi
   {
@@ -56,15 +54,14 @@
   class cgi_request_service;
   class fcgi_request_service;
 
- namespace detail {
+ namespace common {
 
- namespace tags = ::BOOST_CGI_NAMESPACE::common::tags;
-
    template<typename Protocol>
     struct protocol_traits
     {
     };
 
+ /// Common Traits for CGI.
     template<>
     struct protocol_traits<tags::cgi>
     {
@@ -82,7 +79,6 @@
                   tags::async_stdio
> connection_type;
       typedef common::basic_client<
- connection_type,
                   tags::cgi
> client_type;
       typedef common::form_parser form_parser_type;
@@ -90,14 +86,21 @@
       typedef char char_type;
       typedef std::basic_string<char_type> string_type;
       typedef string_type buffer_type;
+ typedef boost::array<unsigned char, 8> header_buffer_type;
       typedef boost::asio::const_buffers_1 const_buffers_type;
       typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
       typedef common::role_type role_type;
       typedef boost::shared_ptr<request_type> pointer;
-
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+ typedef basic_session<
+ std::map<string_type, string_type>
+ > session_type;
+ typedef session_manager session_manager_type;
+#endif // BOOST_CGI_ENABLE_SESSIONS
       static const common::parse_options parse_opts = common::parse_all;
     };
 
+ /// Common Traits for FastCGI.
     template<>
     struct protocol_traits<tags::fcgi>
     {
@@ -125,10 +128,7 @@
       typedef acceptor_service_type::native_type native_type;
       typedef unsigned short port_number_type;
       typedef boost::asio::ip::tcp::endpoint endpoint_type;
- typedef common::basic_client<
- connection_type,
- tags::fcgi
- > client_type;
+ typedef common::basic_client<tags::fcgi> client_type;
       typedef common::form_parser form_parser_type;
       typedef fcgi::spec::header header_type;
       typedef fcgi::spec_detail::role_types role_type;
@@ -136,42 +136,21 @@
       typedef char char_type;
       typedef std::basic_string<char_type> string_type;
       typedef string_type buffer_type;
+ typedef boost::array<unsigned char, 8> header_buffer_type;
       typedef boost::asio::const_buffers_1 const_buffers_type;
       typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
       typedef boost::shared_ptr<request_type> pointer;
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+ typedef basic_session<
+ std::map<string_type, string_type>
+ > session_type;
+ typedef session_manager session_manager_type;
+#endif // BOOST_CGI_ENABLE_SESSIONS
 
       static const common::parse_options parse_opts = common::parse_none;
     };
 
- template<>
- struct protocol_traits<tags::scgi>
- {
- typedef protocol_traits<tags::scgi> type;
- typedef scgi::scgi_request_service request_service_impl;
- typedef scgi::scgi_request_service service_type;
- typedef common::basic_protocol_service<tags::scgi> protocol_service_type;
- typedef common::basic_request<
- tags::scgi
- > request_type;
- typedef scgi::scgi_service_impl service_impl_type;
- typedef scgi::scgi_acceptor_service acceptor_service_impl;
- typedef common::basic_connection<tags::tcp_socket> connection_type;
- typedef common::basic_client<
- connection_type,
- tags::scgi
- > client_type;
- typedef common::form_parser form_parser_type;
- typedef char char_type;
- typedef std::basic_string<char_type> string_type;
- typedef string_type buffer_type;
- typedef boost::asio::const_buffers_1 const_buffers_type;
- typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
- typedef boost::shared_ptr<request_type> pointer;
-
- static const common::parse_options parse_opts = common::parse_none;
- };
-
- } // namespace detail
+ } // namespace common
 BOOST_CGI_NAMESPACE_END
 
-#endif // CGI_REQUEST_TRAITS_HPP_INCLUDED__
+#endif // BOOST_CGI_PROTOCOL_TRAITS_HPP_INCLUDED_

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_base.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_base.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_base.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -23,9 +23,9 @@
 #include "boost/cgi/common/map.hpp"
 #include "boost/cgi/common/form_part.hpp"
 #include "boost/cgi/common/parse_options.hpp"
+#include "boost/cgi/common/protocol_traits.hpp"
 #include "boost/cgi/common/request_status.hpp"
 #include "boost/cgi/detail/extract_params.hpp"
-#include "boost/cgi/detail/protocol_traits.hpp"
 #include "boost/cgi/detail/save_environment.hpp"
 #include "boost/cgi/config.hpp"
 
@@ -50,21 +50,18 @@
     {
       typedef impl_base base_type;
       typedef Protocol protocol_type;
- typedef detail::protocol_traits<Protocol> traits;
-
- typedef typename traits::char_type char_type;
- typedef typename traits::string_type string_type;
+ typedef protocol_traits<Protocol> traits;
       typedef typename traits::buffer_type buffer_type;
- typedef typename traits::const_buffers_type const_buffers_type;
- typedef typename traits::mutable_buffers_type mutable_buffers_type;
-
- typedef typename traits::form_parser_type form_parser_type;
-
+ typedef typename traits::char_type char_type;
       typedef typename traits::client_type client_type;
       typedef typename traits::connection_type connection_type;
- typedef typename connection_type::pointer conn_ptr;
- typedef typename traits::request_type request_type;
+ typedef typename traits::const_buffers_type const_buffers_type;
+ typedef typename traits::form_parser_type form_parser_type;
+ typedef typename traits::mutable_buffers_type mutable_buffers_type;
       typedef typename traits::protocol_service_type protocol_service_type;
+ typedef typename traits::request_type request_type;
+ typedef typename traits::string_type string_type;
+ typedef typename connection_type::pointer conn_ptr;
       
       /**
        * If you want to add a new data type to a request you need to:

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_service.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -10,14 +10,10 @@
 #define CGI_REQUEST_SERVICE_HPP_INCLUDED
 
 #include "boost/cgi/detail/push_options.hpp"
-
-#include <boost/utility/enable_if.hpp>
-///////////////////////////////////////////////////////////
-#include "boost/cgi/import/io_service.hpp"
+#include "boost/cgi/common/protocol_traits.hpp"
 #include "boost/cgi/detail/service_base.hpp"
-#include "boost/cgi/detail/protocol_traits.hpp"
 #include "boost/cgi/fwd/basic_protocol_service_fwd.hpp"
-#include "boost/cgi/config.hpp"
+#include "boost/cgi/import/io_service.hpp"
 
 BOOST_CGI_NAMESPACE_BEGIN
  namespace common {
@@ -35,7 +31,7 @@
     : public detail::service_base<request_service<Protocol> >
   {
     // The platform-specific implementation (only one for now)
- typedef typename detail::protocol_traits<Protocol>::request_service_impl
+ typedef typename protocol_traits<Protocol>::request_service_impl
       service_impl_type;
 
   public:
@@ -103,52 +99,6 @@
     {
       return service_impl_.set_header(impl, name, value, ec);
     }
-
-/*
- template<typename ConstBufferSequence>
- std::size_t write_some(impl_type& impl, const ConstBufferSequence& buf
- , boost::system::error_code& ec)
- {
- return service_impl_.write_some(impl, buf, ec);
- }
-
- template<typename MutableBufferSequence>
- std::size_t read_some(impl_type& impl, MutableBufferSequence buf
- , boost::system::error_code& ec)
- {
- return service_impl_.read_some(impl, buf, ec);
- }
- std::string
- GET(impl_type& impl, const std::string& name
- , boost::system::error_code& ec)
- {
- return service_impl_.GET(impl, name, ec);
- }
-
- std::string
- POST(impl_type& impl, const std::string& name
- , boost::system::error_code& ec)
- {
- return service_impl_.POST(impl, name, ec);
- }
-
- std::string
- cookie(impl_type& impl, const std::string& name
- , boost::system::error_code& ec)
- {
- return service_impl_.cookie(impl, name, ec);
- }
-
-*/
- /*
- std::string
- header(impl_type& impl, const std::string& name
- , boost::system::error_code& ec)
- {
- return "";
- }
-*/
-
   private:
     service_impl_type& service_impl_;
   };

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/response.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/response.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/response.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -154,7 +154,7 @@
 
     basic_response<char_type>&
       set_header(const string_type& value);
-
+
     /// Format and add a header given name and value, appending CRLF.
     basic_response<char_type>&
       set_header(string_type const& name, string_type const& value);
@@ -236,9 +236,9 @@
     }
  
   protected:
- // Vector of all the headers, each followed by a CRLF
+ // Vector of all the headers, each followed by a CRLF
     std::vector<string_type> headers_;
-
+
     // The buffer is a shared_ptr, so you can keep it cached elsewhere.
     boost::shared_ptr<common::streambuf> buffer_;
 

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/basic_io_object.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/basic_io_object.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/basic_io_object.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -65,7 +65,7 @@
           common::is_async<typename Service::protocol_type>,
           boost::mpl::not_<
             boost::is_same<
- typename Service::protocol_type, tags::cgi
+ typename Service::protocol_type, common::tags::cgi
>
>
>
@@ -117,7 +117,7 @@
       Service,
       typename boost::enable_if<
         boost::is_same<
- typename Service::protocol_type, tags::cgi
+ typename Service::protocol_type, common::tags::cgi
>
>::type
>

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/common_headers.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/common_headers.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/common_headers.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -27,6 +27,10 @@
 #include "boost/cgi/import/read.hpp"
 #include "boost/cgi/import/streambuf.hpp"
 #include "boost/cgi/import/write.hpp"
+#include "boost/cgi/utility/redirect.hpp"
+#ifdef BOOST_CGI_ENABLE_SESSIONS
+# include "boost/cgi/utility/sessions.hpp"
+#endif // BOOST_CGI_ENABLE_SESSIONS
 
 #endif // CGI_DETAIL_COMMON_HEADERS_HPP_INCLUDED__
 

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/push_options.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/push_options.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/push_options.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -9,12 +9,15 @@
 
 //#ifdef _MSC_VER
 
+#include "boost/cgi/config.hpp"
+
 // You may want to remove these.
 #if defined (BOOST_WINDOWS)
 # define _CRT_SECURE_NO_DEPRECATE 1
 # define _SCL_SECURE_NO_WARNINGS 1
 # define _CRT_SECURE_NO_WARNINGS 1
 # define NOMINMAX
+# pragma warning( disable : 4503 ) // warning: decorated name length exceeded
 #endif // defined (BOOST_WINDOWS)
 
 #if !defined(BOOST_CGI_INLINE)
@@ -39,5 +42,3 @@
  * currently on by default).
  */
 #define BOOST_CGI_KEEP_EMPTY_VARS
-
-#include "boost/cgi/config.hpp"

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -26,6 +26,7 @@
 /// Dump fcgi stuff into the boost namespace
 namespace boost {
  namespace fcgi {
+ using ::BOOST_CGI_NAMESPACE::detail::protocol_traits;
    using namespace ::BOOST_CGI_NAMESPACE::fcgi;
    using namespace ::BOOST_CGI_NAMESPACE::common; // import common elements.
  } // namespace fcgi

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/client.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/client.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/client.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -32,9 +32,9 @@
 #undef max
 #include <algorithm>
 
-#ifndef NDEBUG
+#if !defined(BOOST_CGI_NO_LOGGING) && !defined(NDEBUG)
 # include <iostream>
-#endif
+#endif
 
 BOOST_CGI_NAMESPACE_BEGIN
  namespace common {
@@ -43,8 +43,7 @@
   /// Construct
   template<>
   basic_client<
- connections::shareable_tcp
- , ::BOOST_CGI_NAMESPACE::common::tags::fcgi
+ ::BOOST_CGI_NAMESPACE::common::tags::fcgi
>::basic_client()
     : request_id_(-1)
     , status_(none_)
@@ -59,9 +58,8 @@
   /// Construct
   template<>
   basic_client<
- connections::shareable_tcp
- , ::BOOST_CGI_NAMESPACE::common::tags::fcgi
- >::basic_client(io_service_type& ios)
+ ::BOOST_CGI_NAMESPACE::common::tags::fcgi
+ >::basic_client(common::io_service& ios)
     : request_id_(-1)
     , status_(none_)
     , total_sent_bytes_(0)
@@ -85,8 +83,7 @@
   template<>
   boost::system::error_code
   basic_client<
- connections::shareable_tcp
- , ::BOOST_CGI_NAMESPACE::common::tags::fcgi
+ ::BOOST_CGI_NAMESPACE::common::tags::fcgi
>::close(boost::uint64_t app_status, boost::system::error_code& ec)
   {
     // Note that the request may already be closed if the client aborts
@@ -121,8 +118,7 @@
   template<typename ConstBufferSequence>
   void
   basic_client<
- connections::shareable_tcp
- , ::BOOST_CGI_NAMESPACE::common::tags::fcgi
+ ::BOOST_CGI_NAMESPACE::common::tags::fcgi
>::prepare_buffer(const ConstBufferSequence& buf)
   {
     typename ConstBufferSequence::const_iterator iter = buf.begin();
@@ -169,8 +165,7 @@
   template<>
   void
   basic_client<
- connections::shareable_tcp
- , ::BOOST_CGI_NAMESPACE::common::tags::fcgi
+ ::BOOST_CGI_NAMESPACE::common::tags::fcgi
>::handle_write(std::size_t bytes_transferred, boost::system::error_code& ec)
   {
     total_sent_bytes_ += bytes_transferred;
@@ -204,8 +199,7 @@
   template<typename ConstBufferSequence>
   std::size_t
   basic_client<
- connections::shareable_tcp
- , ::BOOST_CGI_NAMESPACE::common::tags::fcgi
+ ::BOOST_CGI_NAMESPACE::common::tags::fcgi
>::write_some(
       const ConstBufferSequence& buf
     , boost::system::error_code& ec
@@ -228,8 +222,7 @@
   template<typename ConstBufferSequence, typename Handler>
   void
   basic_client<
- connections::shareable_tcp
- , ::BOOST_CGI_NAMESPACE::common::tags::fcgi
+ ::BOOST_CGI_NAMESPACE::common::tags::fcgi
>::async_write_some(
       const ConstBufferSequence& buf
     , Handler handler
@@ -249,7 +242,7 @@
 namespace fcgi {
     typedef
       common::basic_client<
- connections::shareable_tcp, ::BOOST_CGI_NAMESPACE::common::tags::fcgi
+ ::BOOST_CGI_NAMESPACE::common::tags::fcgi
>
     client;
 } // namespace fcgi

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/specification.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/specification.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/specification.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -11,6 +11,7 @@
 
 #include <boost/cstdint.hpp>
 #include <boost/asio/buffer.hpp>
+#include "boost/cgi/config.hpp"
 
 // NOTE: CamelCase style mimicks the FastCGI specification
 // SEE: http://www.fastcgi.com/devkit/doc/fcgi-spec.html#S8
@@ -586,4 +587,10 @@
  } // namespace fcgi
 BOOST_CGI_NAMESPACE_END
 
+namespace boost {
+ namespace fcgi {
+ using namespace ::BOOST_CGI_NAMESPACE::fcgi;
+ }
+}
+
 #endif // CGI_FCGI_SPECIFICATION_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/fwd/basic_client_fwd.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/fwd/basic_client_fwd.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/fwd/basic_client_fwd.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -12,7 +12,7 @@
 BOOST_CGI_NAMESPACE_BEGIN
  namespace common {
 
- template<typename Connection, typename Protocol>
+ template<typename Protocol>
   class basic_client;
 
  } // namespace common

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/response.ipp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/response.ipp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/response.ipp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -20,7 +20,6 @@
 #include <boost/foreach.hpp>
 ///////////////////////////////////////////////////////////
 #include "boost/cgi/config.hpp"
-
 #include "boost/cgi/common/cookie.hpp"
 #include "boost/cgi/common/header.hpp"
 #include "boost/cgi/common/name.hpp"

Deleted: sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
+++ (empty file)
@@ -1,39 +0,0 @@
-// -- scgi.hpp --
-//
-// Copyright (c) Darren Garvey 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-////////////////////////////////////////////////////////////////
-#ifndef CGI_SCGI_HPP_INCLUDED__
-#define CGI_SCGI_HPP_INCLUDED__
-
-// #include headers for SCGI use.
-#include "boost/cgi/scgi/service.hpp"
-#include "boost/cgi/scgi/acceptor.hpp"
-#include "boost/cgi/scgi/request_service.hpp"
-#include "boost/cgi/scgi/request_acceptor_service.hpp"
-#include "boost/cgi/detail/common_headers.hpp"
-
-/*
-namespace cgi {
-
- typedef basic_request_acceptor<scgi_request_acceptor_service> scgi_acceptor;
-
-# ifndef CGI_NO_IMPLICIT_TYPEDEFS
- typedef scgi_acceptor acceptor;
-# endif
-
-} // namespace cgi
-*/
-
-/// Dump acgi stuff into the boost namespace
-BOOST_CGI_NAMESPACE_BEGIN
- namespace acgi {
- using namespace ::cgi::scgi;
- using namespace ::cgi::common;
- } // namespace acgi
-BOOST_CGI_NAMESPACE_END
-
-#endif // CGI_SCGI_HPP_INCLUDED__

Deleted: sandbox/SOC/2007/cgi/trunk/boost/cgi/utility.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/utility.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
+++ (empty file)
@@ -1,16 +0,0 @@
-// -- utility.hpp --
-//
-// Copyright (c) Darren Garvey 2007.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-////////////////////////////////////////////////////////////////
-#ifndef CGI_UTILITY_HPP_INCLUDED__
-#define CGI_UTILITY_HPP_INCLUDED__
-
-// #include all utility headers.
-#include "boost/cgi/utility/redirect.hpp"
-#include "boost/cgi/utility/stencil.hpp"
-
-#endif // CGI_UTILITY_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/redirect.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/redirect.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/redirect.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -18,23 +18,25 @@
    /// Redirect a request to another place.
    /**
     * Note that without also outputting a content-type header, this will be a
- * 'soft' redirect and the location won't be updated. If you want to do a
- * 'hard' redirect, pass a 'Content-type: text/plain' header along with
- * two CRLFs to complete the headers.
+ * 'soft' (internal) redirect. If you want to do a 'hard' redirect, pass a
+ * 'Content-type: text/plain' header along with two CRLFs to complete the
+ * headers.
     */
    template <typename RequestT>
    basic_header<typename RequestT::char_type>
    redirect(RequestT& req, typename RequestT::string_type const& dest
            , bool secure, boost::system::error_code& ec)
    {
- std::string url(secure ? "https" : "http");
- url += "://" + req.server_name();
- if (dest[0] == '/')
- url += dest;
- else
- url += "/" + dest;
- basic_header<typename RequestT::char_type> hdr("Location", url);
- return hdr;
+ typename RequestT::string_type url(dest);
+ if (url.find("://") == typename RequestT::string_type::npos) {
+ url = secure ? "https" : "http";
+ url += "://" + req.server_name();
+ if (dest[0] == '/')
+ url += dest;
+ else
+ url += "/" + dest;
+ }
+ return basic_header<typename RequestT::char_type>("Location", url);
    }
 
    template <typename RequestT>

Added: sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/sessions.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/sessions.hpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,92 @@
+
+#ifndef BOOST_CGI_SESSIONS_HPP_INCLUDED_
+#define BOOST_CGI_SESSIONS_HPP_INCLUDED_
+
+#include "boost/cgi/detail/push_options.hpp"
+
+#include <string>
+#include <fstream>
+#include <iostream>
+///////////////////////////////////////////////////////////
+#include <boost/system/error_code.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/serialization/utility.hpp>
+#include <boost/serialization/map.hpp>
+#include <boost/noncopyable.hpp>
+///////////////////////////////////////////////////////////
+#include "boost/cgi/import/write.hpp"
+#include "boost/cgi/common/header.hpp"
+#include "boost/cgi/detail/throw_error.hpp"
+///////////////////////////////////////////////////////////
+
+BOOST_CGI_NAMESPACE_BEGIN
+ namespace common {
+
+using namespace std;
+//using namespace boost::serialization;
+
+///////////////////////////////////////////////////////////
+
+template<typename T>
+class basic_session : public T, private boost::noncopyable
+{
+public:
+ typedef T value_type;
+
+ basic_session(string const& id = "")
+ : id_(id)
+ {}
+
+ basic_session(T& t, string const& id = "")
+ : T(t)
+ , id_(id)
+ {}
+
+ basic_session(T const& t, string const& id = "")
+ : T(t)
+ , id_(id)
+ {}
+
+ string const& id () const { return id_; }
+ void id (string const& new_id) { id_ = new_id; }
+
+ operator T() { return static_cast<T&>(*this); }
+ operator T() const { return static_cast<T const&>(*this); }
+
+private:
+ string id_;
+};
+
+class session_manager
+{
+public:
+ session_manager()
+ {}
+
+ template<typename T>
+ void save(basic_session<T>& sesh)
+ {
+ ofstream ofs((sesh.id() + ".arc").c_str());
+ if (ofs) {
+ boost::archive::text_oarchive archive(ofs);
+ archive<< static_cast<basic_session<T>::value_type&>(sesh);
+ }
+ }
+
+ template<typename T>
+ void load(basic_session<T>& sesh)
+ {
+ ifstream ifs((sesh.id() + ".arc").c_str());
+ if (ifs) {
+ boost::archive::text_iarchive archive(ifs);
+ archive>> static_cast<basic_session<T>::value_type&>(sesh);
+ }
+ }
+};
+
+ } // namespace common
+BOOST_CGI_NAMESPACE_END
+
+#endif // BOOST_CGI_SESSIONS_HPP_INCLUDED_
+

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.sln
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.sln (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.sln 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -3,8 +3,6 @@
 # Visual Studio 2008
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_ctemplate_debug_server", "cgi_ctemplate_debug_server\cgi_ctemplate_debug_server.vcproj", "{CED278B4-18C9-41F5-9026-1DB8CD0AC5D4}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xcgi_accept", "xcgi_accept\xcgi_accept.vcproj", "{D24DD1E5-B8E3-4686-AB93-D17D44A73730}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_hello_world", "cgi_hello_world\cgi_hello_world.vcproj", "{CDC4D356-7606-4100-BD78-AFAE949C5748}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_echo", "cgi_echo\cgi_echo.vcproj", "{12AA5F5E-EA1E-4602-98E4-9244872739C1}"
@@ -19,34 +17,32 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcgi_echo_threaded", "fcgi_echo_threaded\fcgi_echo_threaded.vcproj", "{519DFDA7-DC31-410E-BD9A-F17AADA41354}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcgi_echo_debug", "fcgi_echo_debug\fcgi_echo_debug.vcproj", "{A79970AC-68D3-4BE1-9F79-ECF075045F87}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcgi_file_browser", "fcgi_file_browser\fcgi_file_browser.vcproj", "{54333641-E5E5-4B30-A9D4-1054BFA95511}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_file_browser", "cgi_file_browser_debug\cgi_file_browser_debug.vcproj", "{E266C18C-F482-459C-9805-EBAF5C68E50A}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcgi_speed_check", "fcgi_speed_check\fcgi_speed_check.vcproj", "{8F7D1DD8-FE44-419B-BE93-6A78C708ACDA}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_ctemplate_cookie_game", "cgi_ctemplate_cookie_game\cgi_ctemplate_cookie_game.vcproj", "{C18D47EA-742B-4256-8D9B-A3D2A1EB6E1C}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_stencil", "cgi_stencil\cgi_stencil.vcproj", "{B08A2E6D-9973-42F3-9621-90F3BD4A1721}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcgi_run_all", "fcgi_run_all\fcgi_run_all.vcproj", "{2BE173AB-B577-4413-9CD0-1CEA022F0DEE}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_upload", "cgi_upload\cgi_upload.vcproj", "{DF63E5DB-97C8-465D-98FB-5FA64CEDBA62}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcgi_upload", "fcgi_upload\fcgi_upload.vcproj", "{234A7010-1CA1-4E76-8B2C-55167902DB7F}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_wiki", "cgi_wiki\cgi_wiki.vcproj", "{FFF275FA-323A-4699-9D04-A5C9BDD6048B}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcgi_async_echo", "fcgi_async_echo\fcgi_async_echo.vcproj", "{C34170B1-6404-463E-8081-7582B140A8C3}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcgi_stencil", "fcgi_stencil\fcgi_stencil.vcproj", "{6B94FB20-A187-4225-938E-A005352FDD12}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_images", "cgi_images\cgi_images.vcproj", "{B59C59FA-E4A0-498D-A8CF-9FAD68B4315C}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_cookies", "cgi_cookies\cgi_cookies.vcproj", "{C51C82EE-A1BB-4EA7-AD66-20929A7A6E24}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_quickstart", "cgi_quickstart\cgi_quickstart.vcproj", "{0C48C143-DD3F-4DD4-AA5B-34A1F44F7D96}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fastcgi_quickstart", "fastcgi_quickstart\fastcgi_quickstart.vcproj", "{4B0D354E-19EE-4D85-8370-B284A59C4AE1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcgi_charts", "fcgi_charts\fcgi_charts.vcproj", "{557CE468-710F-4C6D-A7EC-286B6A7F746A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cgi_sessions", "cgi_sessions\cgi_sessions.vcproj", "{5C01290A-DD11-4DD9-971A-9C25CCA7FB96}"
+EndProject
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -57,9 +53,6 @@
                 {CED278B4-18C9-41F5-9026-1DB8CD0AC5D4}.Debug|Win32.Build.0 = Debug|Win32
                 {CED278B4-18C9-41F5-9026-1DB8CD0AC5D4}.Release|Win32.ActiveCfg = Release|Win32
                 {CED278B4-18C9-41F5-9026-1DB8CD0AC5D4}.Release|Win32.Build.0 = Release|Win32
- {D24DD1E5-B8E3-4686-AB93-D17D44A73730}.Debug|Win32.ActiveCfg = Debug|Win32
- {D24DD1E5-B8E3-4686-AB93-D17D44A73730}.Release|Win32.ActiveCfg = Release|Win32
- {D24DD1E5-B8E3-4686-AB93-D17D44A73730}.Release|Win32.Build.0 = Release|Win32
                 {CDC4D356-7606-4100-BD78-AFAE949C5748}.Debug|Win32.ActiveCfg = Debug|Win32
                 {CDC4D356-7606-4100-BD78-AFAE949C5748}.Debug|Win32.Build.0 = Debug|Win32
                 {CDC4D356-7606-4100-BD78-AFAE949C5748}.Release|Win32.ActiveCfg = Release|Win32
@@ -88,10 +81,6 @@
                 {519DFDA7-DC31-410E-BD9A-F17AADA41354}.Debug|Win32.Build.0 = Debug|Win32
                 {519DFDA7-DC31-410E-BD9A-F17AADA41354}.Release|Win32.ActiveCfg = Release|Win32
                 {519DFDA7-DC31-410E-BD9A-F17AADA41354}.Release|Win32.Build.0 = Release|Win32
- {A79970AC-68D3-4BE1-9F79-ECF075045F87}.Debug|Win32.ActiveCfg = Debug|Win32
- {A79970AC-68D3-4BE1-9F79-ECF075045F87}.Debug|Win32.Build.0 = Debug|Win32
- {A79970AC-68D3-4BE1-9F79-ECF075045F87}.Release|Win32.ActiveCfg = Release|Win32
- {A79970AC-68D3-4BE1-9F79-ECF075045F87}.Release|Win32.Build.0 = Release|Win32
                 {54333641-E5E5-4B30-A9D4-1054BFA95511}.Debug|Win32.ActiveCfg = Debug|Win32
                 {54333641-E5E5-4B30-A9D4-1054BFA95511}.Debug|Win32.Build.0 = Debug|Win32
                 {54333641-E5E5-4B30-A9D4-1054BFA95511}.Release|Win32.ActiveCfg = Release|Win32
@@ -100,10 +89,6 @@
                 {E266C18C-F482-459C-9805-EBAF5C68E50A}.Debug|Win32.Build.0 = Debug|Win32
                 {E266C18C-F482-459C-9805-EBAF5C68E50A}.Release|Win32.ActiveCfg = Release|Win32
                 {E266C18C-F482-459C-9805-EBAF5C68E50A}.Release|Win32.Build.0 = Release|Win32
- {8F7D1DD8-FE44-419B-BE93-6A78C708ACDA}.Debug|Win32.ActiveCfg = Debug|Win32
- {8F7D1DD8-FE44-419B-BE93-6A78C708ACDA}.Debug|Win32.Build.0 = Debug|Win32
- {8F7D1DD8-FE44-419B-BE93-6A78C708ACDA}.Release|Win32.ActiveCfg = Release|Win32
- {8F7D1DD8-FE44-419B-BE93-6A78C708ACDA}.Release|Win32.Build.0 = Release|Win32
                 {C18D47EA-742B-4256-8D9B-A3D2A1EB6E1C}.Debug|Win32.ActiveCfg = Debug|Win32
                 {C18D47EA-742B-4256-8D9B-A3D2A1EB6E1C}.Debug|Win32.Build.0 = Debug|Win32
                 {C18D47EA-742B-4256-8D9B-A3D2A1EB6E1C}.Release|Win32.ActiveCfg = Release|Win32
@@ -112,10 +97,6 @@
                 {B08A2E6D-9973-42F3-9621-90F3BD4A1721}.Debug|Win32.Build.0 = Debug|Win32
                 {B08A2E6D-9973-42F3-9621-90F3BD4A1721}.Release|Win32.ActiveCfg = Release|Win32
                 {B08A2E6D-9973-42F3-9621-90F3BD4A1721}.Release|Win32.Build.0 = Release|Win32
- {2BE173AB-B577-4413-9CD0-1CEA022F0DEE}.Debug|Win32.ActiveCfg = Debug|Win32
- {2BE173AB-B577-4413-9CD0-1CEA022F0DEE}.Debug|Win32.Build.0 = Debug|Win32
- {2BE173AB-B577-4413-9CD0-1CEA022F0DEE}.Release|Win32.ActiveCfg = Release|Win32
- {2BE173AB-B577-4413-9CD0-1CEA022F0DEE}.Release|Win32.Build.0 = Release|Win32
                 {DF63E5DB-97C8-465D-98FB-5FA64CEDBA62}.Debug|Win32.ActiveCfg = Debug|Win32
                 {DF63E5DB-97C8-465D-98FB-5FA64CEDBA62}.Debug|Win32.Build.0 = Debug|Win32
                 {DF63E5DB-97C8-465D-98FB-5FA64CEDBA62}.Release|Win32.ActiveCfg = Release|Win32
@@ -124,10 +105,6 @@
                 {234A7010-1CA1-4E76-8B2C-55167902DB7F}.Debug|Win32.Build.0 = Debug|Win32
                 {234A7010-1CA1-4E76-8B2C-55167902DB7F}.Release|Win32.ActiveCfg = Release|Win32
                 {234A7010-1CA1-4E76-8B2C-55167902DB7F}.Release|Win32.Build.0 = Release|Win32
- {FFF275FA-323A-4699-9D04-A5C9BDD6048B}.Debug|Win32.ActiveCfg = Debug|Win32
- {FFF275FA-323A-4699-9D04-A5C9BDD6048B}.Debug|Win32.Build.0 = Debug|Win32
- {FFF275FA-323A-4699-9D04-A5C9BDD6048B}.Release|Win32.ActiveCfg = Release|Win32
- {FFF275FA-323A-4699-9D04-A5C9BDD6048B}.Release|Win32.Build.0 = Release|Win32
                 {C34170B1-6404-463E-8081-7582B140A8C3}.Debug|Win32.ActiveCfg = Debug|Win32
                 {C34170B1-6404-463E-8081-7582B140A8C3}.Debug|Win32.Build.0 = Debug|Win32
                 {C34170B1-6404-463E-8081-7582B140A8C3}.Release|Win32.ActiveCfg = Release|Win32
@@ -136,14 +113,26 @@
                 {6B94FB20-A187-4225-938E-A005352FDD12}.Debug|Win32.Build.0 = Debug|Win32
                 {6B94FB20-A187-4225-938E-A005352FDD12}.Release|Win32.ActiveCfg = Release|Win32
                 {6B94FB20-A187-4225-938E-A005352FDD12}.Release|Win32.Build.0 = Release|Win32
- {B59C59FA-E4A0-498D-A8CF-9FAD68B4315C}.Debug|Win32.ActiveCfg = Debug|Win32
- {B59C59FA-E4A0-498D-A8CF-9FAD68B4315C}.Debug|Win32.Build.0 = Debug|Win32
- {B59C59FA-E4A0-498D-A8CF-9FAD68B4315C}.Release|Win32.ActiveCfg = Release|Win32
- {B59C59FA-E4A0-498D-A8CF-9FAD68B4315C}.Release|Win32.Build.0 = Release|Win32
                 {C51C82EE-A1BB-4EA7-AD66-20929A7A6E24}.Debug|Win32.ActiveCfg = Debug|Win32
                 {C51C82EE-A1BB-4EA7-AD66-20929A7A6E24}.Debug|Win32.Build.0 = Debug|Win32
                 {C51C82EE-A1BB-4EA7-AD66-20929A7A6E24}.Release|Win32.ActiveCfg = Release|Win32
                 {C51C82EE-A1BB-4EA7-AD66-20929A7A6E24}.Release|Win32.Build.0 = Release|Win32
+ {0C48C143-DD3F-4DD4-AA5B-34A1F44F7D96}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0C48C143-DD3F-4DD4-AA5B-34A1F44F7D96}.Debug|Win32.Build.0 = Debug|Win32
+ {0C48C143-DD3F-4DD4-AA5B-34A1F44F7D96}.Release|Win32.ActiveCfg = Release|Win32
+ {0C48C143-DD3F-4DD4-AA5B-34A1F44F7D96}.Release|Win32.Build.0 = Release|Win32
+ {4B0D354E-19EE-4D85-8370-B284A59C4AE1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4B0D354E-19EE-4D85-8370-B284A59C4AE1}.Debug|Win32.Build.0 = Debug|Win32
+ {4B0D354E-19EE-4D85-8370-B284A59C4AE1}.Release|Win32.ActiveCfg = Release|Win32
+ {4B0D354E-19EE-4D85-8370-B284A59C4AE1}.Release|Win32.Build.0 = Release|Win32
+ {557CE468-710F-4C6D-A7EC-286B6A7F746A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {557CE468-710F-4C6D-A7EC-286B6A7F746A}.Debug|Win32.Build.0 = Debug|Win32
+ {557CE468-710F-4C6D-A7EC-286B6A7F746A}.Release|Win32.ActiveCfg = Release|Win32
+ {557CE468-710F-4C6D-A7EC-286B6A7F746A}.Release|Win32.Build.0 = Release|Win32
+ {5C01290A-DD11-4DD9-971A-9C25CCA7FB96}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5C01290A-DD11-4DD9-971A-9C25CCA7FB96}.Debug|Win32.Build.0 = Debug|Win32
+ {5C01290A-DD11-4DD9-971A-9C25CCA7FB96}.Release|Win32.ActiveCfg = Release|Win32
+ {5C01290A-DD11-4DD9-971A-9C25CCA7FB96}.Release|Win32.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_quickstart/cgi_quickstart.vcproj
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_quickstart/cgi_quickstart.vcproj 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="cgi_quickstart"
+ ProjectGUID="{0C48C143-DD3F-4DD4-AA5B-34A1F44F7D96}"
+ RootNamespace="cgi_quickstart"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE; _SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;c:\code\c++\boost.cgi\cgi-bin\$(TargetName)&quot;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;c:\code\c++\boost.cgi\cgi-bin\$(TargetName)&quot;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\..\..\doc\src\tutorial\cgi_quickstart.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_sessions/cgi_sessions.vcproj
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_sessions/cgi_sessions.vcproj 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="cgi_sessions"
+ ProjectGUID="{5C01290A-DD11-4DD9-971A-9C25CCA7FB96}"
+ RootNamespace="cgi_sessions"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_SCL_SECURE_NO_WARNINGS; BOOST_CGI_ENABLE_SESSIONS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;c:\code\c++\boost.cgi\cgi-bin\$(TargetName)&quot;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;BOOST_CGI_ENABLE_SESSIONS"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;c:\code\c++\boost.cgi\cgi-bin\$(TargetName)&quot;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\..\..\example\cgi\sessions\main.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\..\..\..\example\cgi\sessions\sessions.hpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_stencil/cgi_stencil.vcproj
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_stencil/cgi_stencil.vcproj (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/cgi_stencil/cgi_stencil.vcproj 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -188,10 +188,6 @@
                         Filter="h;hpp;hxx;hm;inl;inc;xsd"
                         UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
- <File
- RelativePath="..\..\..\..\..\example\cgi\stencil\stencil.hpp"
- >
- </File>
                 </Filter>
                 <Filter
                         Name="Resource Files"

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/fastcgi_quickstart/fastcgi_quickstart.vcproj
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/build/msvc/9.0/Boost.CGI/fastcgi_quickstart/fastcgi_quickstart.vcproj 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="fastcgi_quickstart"
+ ProjectGUID="{4B0D354E-19EE-4D85-8370-B284A59C4AE1}"
+ RootNamespace="fastcgi_quickstart"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ Profile="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="false"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\..\..\doc\src\tutorial\fastcgi_quickstart.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>

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-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -30,73 +30,73 @@
 #import auto-index ;
 
 # compile the doxygen sources here
-doxygen autodoc
- :
+#doxygen autodoc
+# :
 # [ glob-tree ../../../boost/cgi/*.hpp : .svn ]
 # [ glob-tree ../../../boost/libs/cgi/src/*.cpp : .svn ]
-
- [ glob $(top)/boost/cgi/*.hpp ]
- [ glob $(top)/boost/cgi/common/*.hpp ]
- [ glob $(top)/boost/cgi/util/*.hpp ]
- [ glob $(top)/boost/cgi/connections/*.hpp ]
- [ glob $(top)/boost/cgi/cgi/*.hpp ]
- [ glob $(top)/boost/cgi/fcgi/*.hpp ]
- $(top)/boost/cgi/fcgi/client.hpp
- $(top)/boost/cgi/fcgi/service.hpp
- $(top)/boost/cgi/fcgi/acceptor.hpp
- $(top)/boost/cgi/fcgi/request.hpp
- $(top)/boost/cgi/cgi/service.hpp
- $(top)/boost/cgi/cgi/request.hpp
- $(top)/boost/cgi/http/status_code.hpp
- :
- <doxygen:param>TAB_SIZE=2
- # <doxygen:param>EXTRACT_ALL=YES
- <doxygen:param>HIDE_UNDOC_MEMBERS=NO
- # Show all inherited members of a class in the documentation of that class
- # as if those members were ordinary class members.
- <doxygen:param>INLINE_INHERITED_MEMB=YES
- <doxygen:param>SORT_MEMBER_DOCS=YES
- #<doxygen:param>EXTRACT_PRIVATE=YES
- <doxygen:param>EXTRACT_STATIC=YES
- # If the EXTRACT_PRIVATE tag is set to YES all private members of a class
- # will be included in the documentation
- <doxygen:param>EXTRACT_PRIVATE=NO
- <doxygen:param>EXTRACT_LOCAL_CLASSES=YES
- <doxygen:param>EXTRACT_LOCAL_METHODS=YES
- # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
- # locally in source files will be included in the documentation.
- <doxygen:param>EXTRACT_LOCAL_CLASSES=YES
- <doxygen:param>ENABLE_PREPROCESSING=YES
- <doxygen:param>MACRO_EXPANSION=YES
- <doxygen:param>EXPAND_ONLY_PREDEF=YES
- <doxygen:param>SEARCH_INCLUDES=YES
+#
+# [ glob $(top)/boost/cgi/*.hpp ]
+# [ glob $(top)/boost/cgi/common/*.hpp ]
+# [ glob $(top)/boost/cgi/util/*.hpp ]
+# [ glob $(top)/boost/cgi/connections/*.hpp ]
+# [ glob $(top)/boost/cgi/cgi/*.hpp ]
+# [ glob $(top)/boost/cgi/fcgi/*.hpp ]
+# $(top)/boost/cgi/fcgi/client.hpp
+# $(top)/boost/cgi/fcgi/service.hpp
+# $(top)/boost/cgi/fcgi/acceptor.hpp
+# $(top)/boost/cgi/fcgi/request.hpp
+# $(top)/boost/cgi/cgi/service.hpp
+# $(top)/boost/cgi/cgi/request.hpp
+# $(top)/boost/cgi/http/status_code.hpp
+# :
+# <doxygen:param>TAB_SIZE=2
+# # <doxygen:param>EXTRACT_ALL=YES
+# <doxygen:param>HIDE_UNDOC_MEMBERS=NO
+# # Show all inherited members of a class in the documentation of that class
+# # as if those members were ordinary class members.
+# <doxygen:param>INLINE_INHERITED_MEMB=YES
+# <doxygen:param>SORT_MEMBER_DOCS=YES
+# #<doxygen:param>EXTRACT_PRIVATE=YES
+# <doxygen:param>EXTRACT_STATIC=YES
+# # If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# # will be included in the documentation
+# <doxygen:param>EXTRACT_PRIVATE=NO
+# <doxygen:param>EXTRACT_LOCAL_CLASSES=YES
+# <doxygen:param>EXTRACT_LOCAL_METHODS=YES
+# # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# # locally in source files will be included in the documentation.
+# <doxygen:param>EXTRACT_LOCAL_CLASSES=YES
+# <doxygen:param>ENABLE_PREPROCESSING=YES
+# <doxygen:param>MACRO_EXPANSION=YES
+# <doxygen:param>EXPAND_ONLY_PREDEF=YES
+# <doxygen:param>SEARCH_INCLUDES=YES
     # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] is
     # inserted in the documentation for inline members.
- <doxygen:param>INLINE_INFO=YES
+# <doxygen:param>INLINE_INFO=YES
     # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
     # descriptions of file, namespace and class members alphabetically by member
     # name.
- <doxygen:param>SORT_BRIEF_DOCS=YES
+# <doxygen:param>SORT_BRIEF_DOCS=YES
     # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen will
     # sort the (detailed) documentation of file and class members alphabetically
     # by member name.
- <doxygen:param>SORT_MEMBER_DOCS=YES
+# <doxygen:param>SORT_MEMBER_DOCS=YES
     # List of the files that are included by a file in the documentation of that
     # file.
- <doxygen:param>SHOW_INCLUDE_FILES=NO
+# <doxygen:param>SHOW_INCLUDE_FILES=NO
     # Prepend the brief description of a member or function before the detailed
     # description
- <doxygen:param>REPEAT_BRIEF=YES
+# <doxygen:param>REPEAT_BRIEF=YES
     # Include brief member descriptions after the members that are listed in the
     # file and class
- <doxygen:param>BRIEF_MEMBER_DESC=YES
+# <doxygen:param>BRIEF_MEMBER_DESC=YES
     # Treat a multi-line C++ special comment block (i.e. a block of //! or
     # /// comments) as a brief description.
- <doxygen:param>MULTILINE_CPP_IS_BRIEF=YES
+# <doxygen:param>MULTILINE_CPP_IS_BRIEF=YES
     # May be best to always use \brief and \details to avoid ambiguity?
- <doxygen:param>INCLUDE_PATH=$(boost-root)
- <doxygen:param>WARN_LOGFILE=$(top)/libs/cgi/doc/doxywarnings.log
- ;
+# <doxygen:param>INCLUDE_PATH=$(boost-root)
+# <doxygen:param>WARN_LOGFILE=$(top)/libs/cgi/doc/doxywarnings.log
+# ;
 
 xml cgi_xml : src/cgi.qbk ;
 
@@ -123,20 +123,21 @@
     # Use graphics not text for navigation:
     <xsl:param>navig.graphics=1
     # How far down we chunk nested sections, basically all of them:
- <xsl:param>chunk.section.depth=10
+ <xsl:param>chunk.section.depth=2
     # Don't put the first section on the same page as the TOC:
     <xsl:param>chunk.first.sections=1
     # How far down sections get TOC's
     <xsl:param>toc.section.depth=10
     # Max depth in each TOC:
- <xsl:param>toc.max.depth=4
+ <xsl:param>toc.max.depth=2
     # How far down we go with TOC's
     <xsl:param>generate.section.toc.level=1
     #<xsl:param>generate.toc="chapter nop section nop"
 
     #<xsl:param>root.filename="svg_plot"
     #<xsl:param>root.filename=cgi
- <xsl:param>boost.image.src="../../../../boost/boostified/release/doc/html/images"
+ <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>annotation.support=1
@@ -168,7 +169,7 @@
     <format>pdf:<xsl:param>admon.graphics.path=$(images_location)/images/
     <format>pdf:<xsl:param>draft.mode="no"
 
- <dependency>autodoc
+# <dependency>autodoc
          ;
 
 install html

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/cgi.qbk
==============================================================================

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-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -1,15 +1,15 @@
 [/
- / Copyright (c) 2007 Darren Garvey
+ / 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)
  /]
 
 [library CGI
- [quickbook 1.4]
- [version 0.01]
+ [quickbook 1.5]
+ [version 0.02]
     [dirname the_document_dir]
- [copyright 2007 2008 Darren Garvey]
+ [copyright 2007-2009 Darren Garvey]
     [purpose Documentation for CGI / FastCGI Library]
     [authors [Garvey, Darren]]
     [license
@@ -92,6 +92,12 @@
 
 [/include quickstart.qbk]
 
+[include tutorial.qbk]
+
+[include overview.qbk]
+
+[include utilities.qbk]
+
 [/include user_guide.qbk]
 
 [/include:tutorial user_guide/tutorial.qbk]
@@ -120,4 +126,4 @@
 
 [/xinclude quickref.xml]
 
-[include reference.qbk]
+[/include reference.qbk]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/acceptors.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/acceptors.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,78 @@
+[/
+ / 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:acceptors Acceptors]
+
+['[*TODO]: Document using Acceptors]
+
+[section:accepting Accepting Requests]
+
+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
+``
+
+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):
+
+[table
+ [[Function signature] [Purpose]]
+ [
+ [`void accept(xcgi::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)`]
+ [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)`]
+ [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.]
+ ]
+ [
+ [`void cancel()`]
+ [Cancel all outstanding asynchronous accepts that are running]
+ ]
+] [/table]
+
+[h5 Example]
+
+``
+#include <boost/cgi/fcgi.hpp>
+
+int main()
+{
+ using namespace cgi::fcgi; // for example
+
+ // create a ProtocolService
+ service service;
+
+ // create an acceptor
+ acceptor acceptor(service);
+
+ // make an empty request
+ request req(service);
+
+ boost::system::error_code ec;
+ // accept a request
+ acceptor.accept(req, ec);
+
+ if (!ec)
+ {
+ // a request was accepted ok
+ }
+
+ return 0;
+}
+``
+
+[endsect] [/ accepting]
+
+[endsect] [/ acceptors]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/clients.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/clients.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,7 @@
+
+[section:clients Clients]
+
+['[*TODO]: Document using Clients]
+
+[endsect] [/ clients]
+

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/requests.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/requests.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,8 @@
+
+[section:request Requests]
+
+['[*TODO]: Document using Requests]
+
+[include:loading requests/loading.qbk]
+
+[endsect] [/ requests]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/requests/loading.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/requests/loading.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,97 @@
+[/
+ / 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:loading Loading Requests]
+
+After a request has been accepted, it should also be 'loaded'. Before being loaded the request is in an undefined state and it is unsafe to access any data associated with the request - although you may still read/write with the request. For CGI, the request's constructor calls load implicitly (this is optional behaviour), in most other situations, one of the following functions are used:
+
+[table
+ [[Method Name] [Function signature] [Purpose]]
+ [
+ [`load`]
+ [`void (parse_options& )`]
+ [Loads the request meta-data according to the passed `parse_options`. If an error occurs, a `boost::system::system_error` is thrown.]
+ ]
+ [
+ [`load`]
+ [`boost::system::error_code& (parse_options&, boost::system::error_code&)`]
+ [Loads the request meta-data according to the passed `parse_options`. If an error occurs, an `error_code` is returned with detail about the error.]
+ ]
+ [
+ [`async_load`]
+ [`template<typename Handler> void (parse_options&, Handler)`]
+ [Asynchronously loads the request meta-data according to the passed `parse_options`. `handler` must be a model of __Handler__ and will be invoked when the loading has completed. The function always returns immediately.]
+ ]
+] [/table]
+
+What the call does is acquire the request environment data as necessary and parse the CGI `GET` and `HTTP_COOKIE` variables. Also reads and parses form data (ie. `POST` data). If the form data include file uploads, these are saved to disk and information about the file is stored in the request (see `basic_request<>::uploads`).
+
+[h5 CGI example]
+
+``
+#include <boost/cgi/cgi.hpp>
+
+namespace cgi = boost::cgi;
+
+int main()
+{
+
+ // Delay loading the request data
+ cgi::request request(cgi::parse_none);
+ cgi::response response;
+
+ // ...
+
+ // Load the request now (including parsing stdin)
+ boost::system::error_code& ec;
+ request.load(cgi::parse_all, ec);
+
+ if (ec)
+ {
+ response<< "Failed to load response.";
+ return cgi::commit(request, response, cgi::http::internal_server_error);
+ }
+
+ response<< "Loaded response OK.";
+ return cgi::commit(request, response);
+}
+``
+
+[h5 Synchronous FastCGI example]
+
+``
+#include <boost/cgi/fcgi.hpp>
+
+namespace fcgi = boost::fcgi;
+
+int handler(fcgi::request& request)
+{
+ request.load(fcgi::parse_env); // minimal parsing.
+
+ fcgi::response response;
+ response<< "Hello, world.";
+ return fcgi::commit(request, response);
+}
+
+int main()
+{
+ // Create a ProtocolService
+ fcgi::service service;
+
+ // Create an acceptor
+ fcgi::acceptor acceptor(service);
+
+ int status(0);
+ while (!status) {
+ status = acceptor.accept(&handler);
+ }
+
+ return status;
+}
+``
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/responses.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/responses.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,51 @@
+
+[section:responses Responses]
+
+['[*TODO]: Document using Responses]
+
+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 when an exception is going to be throw), so being able to rewrite your response at any time is a requirement.
+
+The library provides the [classref cgi::response] class to make buffering your response simpler. Here is an example of using it:
+
+[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/services.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/overview/services.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,8 @@
+
+[section:services Services]
+
+['[*TODO]: Document using Services]
+
+
+
+[endsect] [/ services]

Deleted: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/responses.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/responses.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
+++ (empty file)
@@ -1,57 +0,0 @@
-
-[section:responses Writing Responses]
-
-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 when an exception is going to be throw), so being able to rewrite your response at any time is a requirement.
-
-The library provides the [classref cgi::response] class to make buffering your response simpler. Here is an example of using it:
-
-[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]
-
-[variablelist Interface
-
-[
-
-]
-
-]
-
-[endsect] [/ api]
-
-[endsect] [/ responses]
-

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/0-old-fastcgi_quickstart.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/0-old-fastcgi_quickstart.cpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,119 @@
+
+//[fastcgi_main
+
+/*<
+We start off with the following:
+>*/
+#include <boost/cgi/fcgi.hpp>
+namespace fcgi = boost::fcgi;
+
+/*<
+Now the body of the FastCGI handler:
+>*/
+int main(int,char**)
+{
+ fcgi::request req;
+
+/*<
+At this point, the environment variables are accessible. This includes cookie
+and form variables too, which by default are all parsed (this is optional).
+
+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 - whereas writing to the request directly
+isn't - so if an error occurs, you can simply `clear()` the response and send
+an error message, which is much cleaner than sending half a response to the
+client, followed by "... Sorry, I just broke!".
+>*/
+
+ fcgi::response resp;
+
+/*<
+Let's assume you now want to check if the user has a cookie, "user_name",
+set. We get at it like this:
+>*/
+
+ std::string user_name( req.cookies["user_name"] );
+
+/*<
+If it's set, we'll be polite and say hello. If you are used to CGI
+programming, you'll notice the lack of any HTTP headers. If you don't want to
+bother with headers, a default header `'Content-type: text/plain'` is sent,
+followed by the usual HTTP end-of-line `'\r\n'` and a blank line which
+indicates the end of the headers and the start of content.
+>*/
+
+ if (!user_name.empty())
+ {
+ resp<< "Hello there, " << req.cookies["user_name"] << ". How are you?";
+
+/*<
+That's all we want to say for now, so just send this back and quit.
+>*/
+ return fcgi::commit(req, resp);
+ }
+
+/*<
+If the cookie isn't set, we will check if the user has posted a __GET__/
+__POST__ form with their name.
+>*/
+ user_name = req.form["user_name"];
+
+ if (!user_name.empty())
+ {
+/*<
+If they have told us their name, we should set a cookie so we remember it next
+time. Then we can say hello and exit. There are two ways to set a cookie:
+either directly using `req.set_cookie("user_name", user_name)` or the method
+below. You can also send an expiry date and a path for the cookie.[footnote
+See [@http://tools.ietf.org/html/rfc822 RFC822] for more
+]
+
+Note that if you set a cookie with no value, the cookie will be deleted.
+
+Again, the request object isn't buffered, so we are going to keep using the
+`response` in case something breaks and we end up not wanting to set the
+cookie. The cookie we set below will expire when the client closes their
+browser.
+
+This time, we shall send a Date header. If we do this (ie. send a header
+ourselves), we must also set the Content-type header and terminate the
+headers, like below.
+>*/
+
+ resp<< fcgi::cookie("user_name", user_name)
+ << header("Date", "Tue, 15 Nov 1994 08:12:31 GMT")
+ << header("Content-type", "text/plain")
+ << "Hello there, " << user_name << ". You're new around here.";
+
+ return fcgi::commit(req, resp);
+ }
+
+/*<
+Now, if we have no idea who they are, we'll send a form asking them for their
+name. As the default `"Content-type"` header is `"text/plain"`, we'll change
+this to `"text/html"` so the user's browser will display the HTML form. You
+can do this using
+``
+set_header(req, "Content-type", "text/html")
+``
+or
+``
+resp<< header("Content-type", "text/html")
+``
+Since writing with raw strings is error-prone, the shortcut below is the recommended way
+to set the content-type:
+>*/
+
+ resp<< fcgi::content_type("text/html")
+ << "Hello there. What's your name?" "<p />"
+ "<form method='POST'>"
+ "<input type='text' name='user_name' />"
+ "<input type='submit' />";
+
+ /*< This is all we want to do for now, so we can send the response and exit. >*/
+ return fcgi::commit(req, resp);
+}
+//]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/Copy of fastcgi_quickstart.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/Copy of fastcgi_quickstart.cpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,254 @@
+// -- fastcgi_quickstart.cpp --
+//
+// Copyright (c) Darren Garvey 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)
+//
+////////////////////////////////////////////////////////////////
+
+//[fastcgi_quickstart
+
+#include <iostream> // for std::cerr
+
+/*<
+A catch-all header is available which includes all of the headers you should
+need for CGI.
+
+For the sake of clarity we alias the `boost::fcgi` namespace rather than
+dumping all of the library names with a `using namespace`. This way, you can
+see what comes from the library.
+>*/
+#include <boost/cgi/fcgi.hpp>
+namespace cgi = boost::fcgi;
+
+/*<
+The first thing to do is write a handler function which takes a request and a
+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)
+{
+/*<
+In our request handler, we will assume that the request has been fully-parsed
+and we can access all of the request data. The request data is available using
+`std::map<>`-like public members of a `fcgi::request`.[footnote
+The data is stored internally in a single `fusion::vector<>`]
+
+A FastCGI request has several types of variables available. These are listed
+in the table below, assuming that `req` is an instance of `fcgi::request`:
+
+[table
+ [[Source] [Variable] [Description]]
+ [
+ [Environment] [`req.env`] [The environment of a FastCGI request contains
+ most of the information you will need to handle a request. There is a basic
+ set of common environment variables that you can expect to be set by most
+ HTTP servers around. A list of them is available on the __TODO__ (link)
+ variables page.]
+ ]
+ [
+ [GET] [`req.get`] [The variables passed in the query string of an HTTP GET
+ request.]
+ ]
+ [
+ [POST] [`req.post`] [The HTTP POST data that is sent in an HTTP request's
+ body. File uploads are not stored in this map.]
+ ]
+ [
+ [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.]
+ ]
+ [
+ [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.]
+ ]
+ [
+ [Form] [`req.form`] [The form variables are either the GET variables or
+ the POST variables, depending on the request method of the request.]
+ ]
+]
+
+Let's assume you now want to check if the user has a cookie, "user_name",
+set. We can check if a user has a cookie set like this:
+>*/
+ if (req.cookies.count("user_name"))
+ {
+/*<
+First, we need to be able to clear the cookie we are setting. We will reset
+the cookie if the user navigates to `"/path/to/script?reset=1"`.
+
+The `reset` variable in the query string is a GET variable. The request data
+is accessed through a proxy class which works just like a `std::map<>` with
+some extra features.
+
+One of them is `pick`, which looks up a key in the map and returns the value
+if it is found. Otherwise it returns a default value, which is the second
+argument.
+
+The default value can be any type that supports
+[@http://boost.org/libs/lexical_cast Boost.Lexical_cast]. If the key isn't
+found in the map, or the value cannot be cast to the type of the default
+value, the default is returned.
+>*/
+ if (req.get.pick<std::string>("reset", "") == "1")
+ {
+ resp<< cgi::cookie("user_name") /*<
+Set a cookie with no value to delete it.
+>*/
+ << cgi::redirect(req, req.script_name()) /*<
+The `cgi::redirect` free function returns a `"Location"` header that will
+redirect the user to the specified URL. This URL can be a relative or absolute
+but an absolute URL is always returned. To perform an internal redirect, use
+`cgi::location` instead.
+>*/
+ << cgi::content_type("text/plain");
+ }
+ else
+ {
+ std::string user_name( req.cookies["user_name"] );
+/*<
+Looking up a request cookie in `req.cookies` really returns a `cgi::cookie`.
+The line above works though because a `cgi::cookie` is implicitly convertible
+to a `std::string`.
+
+The lookup is case-insensitive, so "USER_NAME" and "User_Name" would be
+equivalent lookup keys.
+
+If the cookie is set, we'll be polite and say hello.
+>*/
+ if (!user_name.empty())
+ {
+ resp<< cgi::content_type("text/html")
+ << "<p>Hello there, " << req.cookies["user_name"]
+ << ". How are you?</p>"
+ << "<a href=\"" << req.script_name() << "?reset=1\">Reset</a>";
+ }
+ }
+ } else
+ if (req.form.count("user_name"))
+ {
+/*<
+If the cookie isn't set, we will check if the user has posted a __GET__/
+__POST__ form with their name.
+>*/
+ std::string user_name (req.form["user_name"]);
+/*<
+If they have told us their name, we should set a cookie so we remember it next
+time. Then we can say hello and exit.
+
+There are two ways to set a cookie: either directly using
+`req.set_cookie("user_name", user_name)` or the method shown. You can also
+send an expiry date and a path for the cookie.[footnote
+See [@http://tools.ietf.org/html/rfc822 RFC822] for more.
+]
+Note that if you set a cookie with no value, the cookie will be deleted.
+
+Again, the request object isn't buffered, so we are going to keep using the
+`response` in case something breaks and we end up not wanting to set the
+cookie. The cookie we set below will expire when the client closes their
+browser.
+
+This time, we shall send a Date header. If we do this (ie. send a header
+ourselves), we must also set the Content-type header, like below.
+>*/
+ resp<< cgi::cookie("user_name", user_name)
+ << cgi::header("Date", "Tue, 15 Nov 1994 08:12:31 GMT")
+ << cgi::content_type("text/html")
+ << "Hello there, " << user_name << ". You're new around here."
+ << "user_name.length() = " << user_name.length() ;
+ }
+ else
+ {
+/*<
+Now, if we have no idea who they are, we'll send a form asking them for their
+name. As the default `"Content-type"` header is `"text/plain"`, we'll change
+this to `"text/html"` so the user's browser will display the HTML form. You
+can do this using
+ `set_header(req, "Content-type", "text/html")`
+or
+ `resp<< header("Content-type", "text/html")`.
+Since writing with raw strings is error-prone, the shortcut below is available.
+>*/
+ resp<< cgi::content_type("text/html")
+ << "Hello there. What's your name?" "<p />"
+ "<form method='POST'>"
+ "<input type='text' name='user_name' />"
+ "<input type='submit' />";
+
+ }
+/*<
+Finally, send the response back and close the request.
+>*/
+ return cgi::commit(req, resp);
+}
+
+/*<
+We now have a request handler in all of it's contrived glory.
+
+The program's `main` function needs to parse the request, call the request
+handler defined above, and finally send the response.
+>*/
+int main(int, char**)
+{
+ cgi::service service;
+/*<
+An `Acceptor` handles accepting requests and little else.
+>*/
+ cgi::acceptor acceptor(service, 8010);
+/*<
+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.
+>*/
+ cgi::response response;
+ int status;
+
+/*<
+Keep accepting requests until the handler returns an error.
+>*/
+ do {
+/*<
+The function `boost::fcgi::acceptor::accept` has a few overloads. The one used
+here takes a function or function object with the signature:
+``
+boost::function<int (boost::fcgi::request&)>
+``
+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) {
+ std::cerr
+ << "Request handled with error. Exit code: " << status << std::endl
+ << "Response body follows: " << std::endl
+ << response << std::endl;
+ }
+ response.clear();
+ } while (!status);
+ return status;
+}
+
+//]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/cgi.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/cgi.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,26 @@
+[/
+ / 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:cgi CGI Quickstart]
+
+[tip
+ If you are familiar with the CGI protocol, you can skip straight to the 10 Minute Intro.
+]
+
+CGI is a simple protocol for writing dynamic web-enabled applications. The protocol's simplicity is key to its success, but the simplicity brings with it some limitations.
+
+By far the most significant limitation is that a CGI program handles one request before exiting. If handling a request involves resources that are expensive to initialise (eg. opening a database), then CGI may not scale as well as you would like. For true scalability, you may want [link cgi.tutorial.fastcgi FastCGI].
+
+[h3 10 Minute Intro]
+
+The following example is generated from the linked [@../src/tutorial/cgi_quickstart.cpp source file].
+
+[import cgi_quickstart.cpp]
+
+[cgi_quickstart]
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/cgi_quickstart.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/cgi_quickstart.cpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,243 @@
+// -- cgi_quickstart.cpp --
+//
+// Copyright (c) Darren Garvey 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_quickstart
+
+/*<
+A catch-all header is available which includes all of the headers you should
+need for CGI.
+
+For the sake of clarity we alias the `boost::cgi` namespace rather than
+dumping all of the library names with a `using namespace`. This way, you can
+see what comes from the library.
+>*/
+#include <boost/cgi/cgi.hpp>
+namespace cgi = boost::cgi;
+
+/*<
+The first thing to do is write a handler function which takes a request and a
+response and does all request-specific work. Later, we will look at writing
+the code that calls this function.
+>*/
+int handle_request(cgi::request& req, cgi::response& resp)
+{
+/*<
+In our request handler, we will assume that the request has been fully-parsed
+and we can access all of the request data. The request data is available using
+`std::map<>`-like public members of a `cgi::request`.[footnote
+The data is stored internally in a single `fusion::vector<>`]
+
+A CGI request has several types of variables available. These are listed in
+the table below, assuming that `req` is an instance of `cgi::request`:
+
+[table
+ [[Source] [Variable] [Description]]
+ [
+ [Environment] [`req.env`] [The environment of a CGI request contains most
+ of the information you will need to handle a request. There is a basic set of
+ common environment variables that you can expect to be set by most HTTP
+ servers around. A list of them is available on the __TODO__ (link) variables
+ page.]
+ ]
+ [
+ [GET] [`req.get`] [The variables passed in the query string of an HTTP GET
+ request.]
+ ]
+ [
+ [POST] [`req.post`] [The HTTP POST data that is sent in an HTTP request's
+ body. File uploads are not stored in this map.]
+ ]
+ [
+ [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.]
+ ]
+ [
+ [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.]
+ ]
+ [
+ [Form] [`req.form`] [The form variables are either the GET variables or
+ the POST variables, depending on the request method of the request.]
+ ]
+]
+
+Let's assume you now want to check if the user has a cookie, "user_name",
+set. We can check if a user has a cookie set like this:
+>*/
+ if (req.cookies.count("user_name"))
+ {
+/*<
+First, we need to be able to clear the cookie we are setting. We will reset
+the cookie if the user navigates to `"/path/to/script?reset=1"`.
+
+The `reset` variable in the query string is a GET variable. The request data
+is accessed through a proxy class which works just like a `std::map<>` with
+some extra features.
+
+One of them is `pick`, which looks up a key in the map and returns the value
+if it is found. Otherwise it returns a default value, which is the second
+argument.
+
+The default value can be any type that supports
+[@http://boost.org/libs/lexical_cast Boost.Lexical_cast]. If the key isn't
+found in the map, or the value cannot be cast to the type of the default
+value, the default is returned.
+>*/
+ if (req.get.pick<std::string>("reset", "") == "1")
+ {
+ resp<< cgi::cookie("user_name") /*<
+Set a cookie with no value to delete it.
+>*/
+ << cgi::redirect(req, req.script_name()) /*<
+The `cgi::redirect` free function returns a `"Location"` header that will
+redirect the user to the specified URL. This URL can be a relative or absolute
+but an absolute URL is always returned. To perform an internal redirect, use
+`cgi::location` instead.
+>*/
+ << cgi::content_type("text/plain");
+ }
+ else
+ {
+ std::string user_name( req.cookies["user_name"] );
+/*<
+Looking up a request cookie in `req.cookies` really returns a `cgi::cookie`.
+The line above works though because a `cgi::cookie` is implicitly convertible
+to a `std::string`.
+
+The lookup is case-insensitive, so "USER_NAME" and "User_Name" would be
+equivalent lookup keys.
+
+If the cookie is set, we'll be polite and say hello before quitting.
+>*/
+ if (!user_name.empty())
+ {
+ resp<< cgi::content_type("text/html")
+ << "<p>Hello there, " << req.cookies["user_name"]
+ << ". How are you?</p>"
+ << "<a href=\"" << req.script_name() << "?reset=1\">Reset</a>";
+ }
+ }
+/*<
+That's all we want to say for now, so we can return.
+
+If you are familiar with CGI programming, you will notice the lack of any
+HTTP headers in the response. A `cgi::response` handles headers separately
+to the body. You can set headers at any point and when you send the response
+the headers will all be sent first.
+
+If you don't explicitly set any response headers, a default header
+`"Content-type: text/plain"` is sent, followed by the usual HTTP end-of-line
+`"\r\n"` and a blank line which indicates the end of the headers and the
+start of response body.
+>*/
+ } else
+/*<
+If the cookie isn't set, we will check if the user has posted a __GET__/
+__POST__ form with their name.
+>*/
+ if (req.form.count("user_name"))
+ {
+ std::string user_name (req.form["user_name"]);
+/*<
+If they have told us their name, we should set a cookie so we remember it next
+time. Then we can say hello and exit.
+
+There are two ways to set a cookie: either directly using
+`req.set_cookie("user_name", user_name)` or the method shown. You can also
+send an expiry date and a path for the cookie.[footnote
+See [@http://tools.ietf.org/html/rfc822 RFC822] for more.
+]
+Note that if you set a cookie with no value, the cookie will be deleted.
+
+Again, the request object isn't buffered, so we are going to keep using the
+`response` in case something breaks and we end up not wanting to set the
+cookie. The cookie we set below will expire when the client closes their
+browser.
+
+This time, we shall send a Date header. If we do this (ie. send a header
+ourselves), we must also set the Content-type header, like below.
+>*/
+ resp<< cgi::cookie("user_name", user_name)
+ << cgi::header("Date", "Tue, 15 Nov 1994 08:12:31 GMT")
+ << cgi::content_type("text/html")
+ << "Hello there, " << user_name << ". You're new around here."
+ << "user_name.length() = " << user_name.length() ;
+ }
+ else
+ {
+/*<
+Now, if we have no idea who they are, we'll send a form asking them for their
+name. As the default `"Content-type"` header is `"text/plain"`, we'll change
+this to `"text/html"` so the user's browser will display the HTML form. You
+can do this using
+ `set_header(req, "Content-type", "text/html")`
+or
+ `resp<< header("Content-type", "text/html")`.
+Since writing with raw strings is error-prone, the shortcut below is available.
+>*/
+ resp<< cgi::content_type("text/html")
+ << "Hello there. What's your name?" "<p />"
+ "<form method='POST'>"
+ "<input type='text' name='user_name' />"
+ "<input type='submit' />";
+ }
+/*<
+A CGI program will handle one request each time it is invoked. Returning a
+non-zero status to the OS indicates an error handling the request. I don't
+know that HTTP servers treat non-zero exit codes specially.[footnote I may well
+may well be wrong about this.]
+
+To send the response back to the request, use `cgi::commit`. The third
+`status` argument is optional and defaults to zero. The return value of
+`cgi::commit` is `status`.
+>*/
+ return cgi::commit(req, resp);
+}
+
+/*<
+We now have a request handler in all of it's contrived glory.
+
+The program's `main` function needs to parse the request, call the request
+handler defined above, and finally send the response.
+>*/
+
+int main(int, char**)
+{
+ cgi::request req;
+/*<
+At this point, the environment variables are accessible. This includes cookie
+and form variables too, which are all parsed by default-constructing a
+`cgi::request` (this is optional).
+>*/
+ cgi::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 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.
+>*/
+ return handle_request(req, resp);
+}
+
+//]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/cookies.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/cookies.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,12 @@
+[/
+ / 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)
+ /]
+
+[section Cookies]
+
+
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,26 @@
+[/
+ / 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:fastcgi FastCGI Quickstart]
+
+['[*TODO]: FastCGI Quickstart]
+
+FastCGI is a protocol that was designed with efficiency in mind. One of the key features of FastCGI is that it allows a CGI-like program to serve multiple requests and outlive the lifetime of any one request. The application communicates with the server using TCP sockets[footnote This library currently only supports TCP sockets. The FastCGI protocol allows for "any reliable transport" and adding support for named pipes on Windows and UNIX sockets on linux is on the TODO list.] and the data is binary-encoded, which can be parsed quickly.
+
+For a full introduction on FastCGI, see the [@http://www.fastcgi.com/drupal/node/6?q=node/15 FastCGI White Paper].
+
+This library supports FastCGI on both linux and Windows. Windows support is currently limited to external FastCGI handlers only.
+
+[h3 10 minute intro]
+
+The following example is generated from the linked [@../src/tutorial/fastcgi_quickstart.cpp source file].
+
+[import fastcgi_quickstart.cpp]
+
+[fastcgi_quickstart]
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi_quickstart.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/fastcgi_quickstart.cpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,250 @@
+// -- fastcgi_quickstart.cpp --
+//
+// Copyright (c) Darren Garvey 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)
+//
+////////////////////////////////////////////////////////////////
+
+//[fastcgi_quickstart
+
+#include <iostream> // for std::cerr
+#include <string>
+#include <boost/config/warning_disable.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+/*<
+A catch-all header is available which includes all of the headers you should
+need for FastCGI.
+
+For the sake of clarity we alias the `boost::fcgi` namespace rather than
+dumping all of the library names with a `using namespace`. This way, you can
+see what comes from the library.
+>*/
+#include <boost/cgi/fcgi.hpp>
+namespace fcgi = boost::fcgi;
+
+/*<
+The following code is taken straight from the calc3 example in
+[@http://boost.org/libs/spirit Boost.Spirit]. The only difference is to
+use `float`s rather than `int`s.
+>*/
+namespace client
+{
+ namespace qi = boost::spirit::qi;
+ namespace ascii = boost::spirit::ascii;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our calculator grammar
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator>
+ struct calculator : qi::grammar<Iterator, float(), ascii::space_type>
+ {
+ calculator() : calculator::base_type(expression)
+ {
+ using qi::_val;
+ using qi::_1;
+ using qi::float_;
+
+ expression =
+ term [_val = _1]
+ >> *( ('+' >> term [_val += _1])
+ | ('-' >> term [_val -= _1])
+ )
+ ;
+
+ term =
+ factor [_val = _1]
+ >> *( ('*' >> factor [_val *= _1])
+ | ('/' >> factor [_val /= _1])
+ )
+ ;
+
+ factor =
+ float_ [_val = _1]
+ | '(' >> expression [_val = _1] >> ')'
+ | ('-' >> factor [_val = -_1])
+ | ('+' >> factor [_val = _1])
+ ;
+ }
+
+ qi::rule<Iterator, float(), ascii::space_type> expression, term, factor;
+ };
+} // namespace client
+
+/*<
+The first thing to do is write a handler function which takes a request and a
+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)
+{
+/*<
+A FastCGI request is not loaded or parsed by default.
+>*/
+ req.load(fcgi::parse_all);
+/*<
+Now that the request has been loaded, we can access all of the request data.
+The request data is available using `std::map<>`-like public members of a
+`fcgi::request`.[footnote
+The data is stored internally in a single `fusion::vector<>`
+]
+
+A FastCGI request has several types of variables available. These are listed
+in the table below, assuming that `req` is an instance of `fcgi::request`:
+
+[table
+ [[Source] [Variable] [Description]]
+ [
+ [Environment] [`req.env`] [The environment of a FastCGI request contains
+ most of the information you will need to handle a request. There is a basic
+ set of common environment variables that you can expect to be set by most
+ HTTP servers around. A list of them is available on the __TODO__ (link)
+ variables page.]
+ ]
+ [
+ [GET] [`req.get`] [The variables passed in the query string of an HTTP GET
+ request.]
+ ]
+ [
+ [POST] [`req.post`] [The HTTP POST data that is sent in an HTTP request's
+ body. File uploads are not stored in this map.]
+ ]
+ [
+ [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.]
+ ]
+ [
+ [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.]
+ ]
+ [
+ [Form] [`req.form`] [The form variables are either the GET variables or
+ the POST variables, depending on the request method of the request.]
+ ]
+]
+>*/
+ if (req.form.count("expression"))
+ {
+ resp<< "<fieldset><legend>Result</legend><pre>";
+
+ using boost::spirit::ascii::space;
+ typedef std::string::const_iterator iterator_type;
+ typedef client::calculator<iterator_type> calculator;
+
+ calculator calc; // Our grammar
+
+ std::string str ( req.form["expression"] );
+ float result;
+ if (!str.empty())
+ {
+ std::string::const_iterator iter = str.begin();
+ std::string::const_iterator end = str.end();
+ bool r = phrase_parse(iter, end, calc, space, result);
+
+ if (r && iter == end)
+ {
+ resp << "-------------------------\n";
+ resp << "Parsing succeeded\n";
+ resp << "result = " << result << '\n';
+ resp << "-------------------------\n";
+ }
+ else
+ {
+ std::string rest(iter, end);
+ resp << "-------------------------\n";
+ resp << "Parsing failed\n";
+ resp << "stopped at: \": " << rest << "\"\n";
+ resp << "-------------------------\n";
+ }
+ }
+ else
+ {
+ resp<< "No expression found.";
+ }
+ resp<< "</pre></fieldset>";
+ }
+ resp<< "<form method='post' id=''>"
+ << " Expression: <input type='text' name='expression' value='"
+ << req.form["expression"] << "'><br />"
+ << " <input type='submit' value='Calculate!'>"
+ << "</form>"
+ << fcgi::content_type("text/html");
+/*<
+Finally, send the response back and close the request.
+>*/
+ return fcgi::commit(req, resp);
+}
+
+/*<
+We now have a request handler in all of it's contrived glory.
+
+The program's `main` function needs to parse the request, call the request
+handler defined above, and finally send the response.
+>*/
+int main(int, char**)
+{
+ fcgi::service service; /*<
+A Service handles asynchronous operations and some of the protocol-specific
+bits.
+>*/
+ fcgi::acceptor acceptor(service, 8008); /*<
+An `Acceptor` handles accepting requests and little else. The `8008` argument
+is the port on the localhost to listen on.
+>*/
+ 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;
+
+/*<
+Keep accepting requests until the handler returns an error.
+>*/
+ do {
+/*<
+The function `boost::fcgi::acceptor::accept` has a few overloads. The one used
+here takes a function or function object with the signature:
+``
+boost::function<int (boost::fcgi::request&)>
+``
+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) {
+ std::cerr
+ << "Request handled with error. Exit code: " << status << std::endl
+ << "Response body follows: " << std::endl
+ << response.str() << std::endl;
+ }
+ response.clear();
+ } while (!status);
+ return status;
+}
+
+//]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/hello_world.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/hello_world.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,101 @@
+
+[section "Hello, World."]
+
+Let's start at the beginning, with the eponymous "Hello world" example:
+
+``
+#include <boost/cgi.hpp>
+using namespace boost::cgi;
+
+int main()
+{
+ request req;
+ response resp;
+
+ resp<< "Hello, world.";
+
+ return_(resp, req, 0); // note the underscore.
+}
+``
+
+This is as simple as it gets. Don't worry though, the library isn't about having the shortest examples; it just so happens that hello world is easy to do. It is probably self-explanatory, but here is what is happening:
+
+``
+#include <boost/cgi.hpp>
+using namespace boost::cgi;
+``
+
+The `boost/cgi.hpp` header includes the headers for CGI, aCGI (CGI with asynchronous I/O support) SCGI and FastCGI. If you only want the CGI stuff you can `#include <boost/cgi/cgi.hpp>`, or similarly for the other protocols (eg. `<boost/cgi/fcgi.hpp>` for FastCGI bits).
+
+``
+request req;
+response resp;
+``
+
+A CGI script is quite simple in principle: the server accepts a request, spawns your CGI program to handle it and sends the response back to the client. These three concepts map directly to the library, with the request, response and client classes.
+
+The request class (be it a `boost::cgi::request` or a `boost::fcgi::request`) is the heart of the library. The response class is a helper class that you can use similarly to `std::cout`, but with some important differences (more on this later). You aren't forced to use the response class with this library, but it's use is highly recommended. .
+
+While a `boost::cgi::request` isn't directly compatible with a `boost::fcgi::request`, a response is independent of protocol and any request you choose to use it with - that makes it easy to reuse for different requests.
+
+
+[tip The `response` class resides in the `boost::cgi::common` namespace and is aliased in the `cgi`/`fcgi`/etc. namespaces when including a protocol-specific header.
+
+eg.
+``
+#include <boost/cgi/fcgi.hpp>
+
+
+int main()
+{
+ boost::cgi::response resp1;
+ boost::cgi::response resp2;
+
+ assert(typeid(resp1) == typeid(resp2));
+ return 0;
+}
+``]
+
+Default constructing a `boost::cgi::request` automatically parses everything you need (this is optional), so you can instantly write a response:
+
+``
+resp<< "Hello, world.";
+``
+
+You can stream data to a response just like you can with std::cout. In addition, you can stream things like `content_type("text/html")` and `cookie("whatever", "value")` or even `redirect("http://google.com")`. More on this later.
+
+`content_type()` is one of the ['`header` factories] provided by the library. In other words it is a function which returns a `header` object, so the following type lines do the same thing:
+
+``
+response resp;
+resp<< content_type("text/plain")
+ << header("Content-type", "text/plain");
+``
+
+Both are equivalent, but the former is more concise and (partly) checked at compile time making it less error prone. Note that the actual content type (ie. `"text/plain"`) isn't checked at all - doing this seems unnecessary.
+
+The `response` class understands `header`s and keeps them separate from the rest of the response. This allows you to add headers at any point, so long as you haven't flushed/sent the response already. For instance, you could add a custom header "Running-time" just before you send the response, which stated the time it took to handle the request.
+
+As mentioned in the _preface_, all CGI scripts require at least a "Content-type" header. However, if you don't stream any headers to a response, a default "Content-type: text/plain" header is added. You can customise this using the macro `BOOST_CGI_DEFAULT_CONTENT_TYPE`.
+
+``
+#define BOOST_CGI_DEFAULT_CONTENT_TYPE "text/html" // Default output is HTML.
+``
+
+Since the response class buffers your data, so you must send it at some point. This doesn't happen automatically. It is sent to the ['Client] associated with a request - ie. `req.client()`. A Client might actually be a connection to your HTTP server, but you should view it as a handle on a connection to the machine that made the request in the first place. You don't really need to know anything else about the Client concept for now. The library provides a convenient macro return_ to keep things clean:
+
+``
+return_(resp, req, 0);
+``
+
+This macro is equivalent to doing:
+
+``
+resp.send(req.client());
+req.close(resp.status(), 0);
+return 0; // Returns 0 to the OS
+``
+
+[tip A CGI request is effectively closed when the application exits, so you don't need to call `close()` on it. Since FastCGI and SCGI can handle multiple requests before the process exits you must explicitly close each one.]
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/quickstart.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/quickstart.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,27 @@
+[/
+ / 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)
+ /]
+
+[section:quickstart Quickstart]
+
+CGI is a simple protocol: you read __POST__ data from `stdin`, other data from environment variables (ie. via [@http://tinyurl.com/3cqrd5 `::getenv()`]) and write your output to `stdout`. This section introduces the '__CGI__' interface, which offers a subset of the library's functionality. This is not essential reading, but it is recommended that you at least scan through it as the techniques still apply to the rest of the library. Afterwards, if you wish to scale your program to __FastCGI__ or __SCGI__, or just provide a custom logging layer or asynchronous read/writes (with vanilla CGI) then the rest of the tutorial will show you how to.
+
+[h3 10 minute intro]
+
+The following example can be found [@../../src/user_guide/tutorial/10_min_intro.cpp here].
+
+[import 10_min_intro.cpp]
+
+[main]
+
+[section:building Building]
+
+Now to compile and run the example. It's probably beyond the scope of these docs to go into too
+much detail here but
+
+[endsect]
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/requests.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/requests.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,22 @@
+[/
+ / 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)
+ /]
+
+[section Requests]
+
+The template class [classref cgi::basic_request `cgi::basic_request<>`] is the main entry point to the library.
+
+The following `typedef`s are provided for typical usage:
+``
+cgi::request // CGI
+fcgi::request // FastCGI
+``
+
+[include:data variables.qbk]
+
+[/link ]
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/running.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/running.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,12 @@
+[/
+ / 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:running Building & Running]
+
+['[*TODO]: How to compile and run the example.]
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/scaling.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/scaling.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,124 @@
+
+[section:scaling Turning a CGI program into a FastCGI daemon]
+
+So you want more flexibility and power than CGI can provide? This section shows you how to turn the CGI "Hello world" program into a FastCGI daemon that can handle more than one request at a time. We'll start off simple by handling one requests after another, before moving on to handling multiple requests simultaneously.
+
+[note
+ The examples in this section assume you have prepended:
+ ``
+ #include <boost/cgi/fcgi.hpp>
+ using namespace boost::fcgi;
+ ``
+]
+
+[section:sync_fcgi Synchronous FastCGI]
+
+``
+int main()
+{
+ try
+ {
+ service s;
+ acceptor a(s);
+
+ for(;;)
+ {
+ request req(s);
+ a.accept(req);
+
+ req.load();
+
+ response resp;
+
+ resp<< "Hello, world.";
+
+ resp.send(req.client());
+ req.close(http::ok, 0);
+ }
+
+ return 0;
+
+ }catch(boost::system::system_error& err){
+ return 1;
+ }
+}
+``
+
+Hopefully you can guess what's going on above. Let's go through the differences to the original CGI example.
+
+``
+acceptor a(s);
+``
+
+This is what you use to accept requests.
+
+``
+for(;;)
+{
+ // ...
+}
+``
+
+This is a simple example, so the program handles an arbitrary number of requests. You may choose to limit the number of requests you handle.
+
+``
+a.accept(req);
+
+req.load(); // equivalent to req.load(parse_env) - the least-expensive useful state for a request.
+``
+
+This accepts one request. An accepted request is in a protocol-dependent state and generally isn't very useful. You must either `load()` or `async_load()` the request to put in a useful state. The arguments to these functions determine what is parsed. You can do things like:
+
+``
+req.load(parse_env|parse_post|parse_cookies); // parse everything but GET variables
+req.load(parse_all); // parse everthing
+req.load(parse_env); // parse just environment variables
+req.load(parse_get); // parse environment and GET variables
+req.load(parse_form); // parse environment and then either GET or POST variables, dependent on the REQUEST_METHOD
+``
+
+Beyond the accept/load sequence the request is basically the same as a CGI request as far as a library user is concerned. As mentioned earlier, you must explicitly close the request when you're finished with it:
+
+``
+req.close(http::ok, 0);
+``
+
+The first argument should be a valid [@http://wikipedia.org/wiki/List_of_HTTP_status_codes HTTP status code], normalised to lower case and underscores except for '100 Continue', which is normalised to `http::continue_` (because `continue` is a keyword). The second argument is the program status and should be what you would have put in the `return 0;` line at the end of your `main()` function. Zero is the default if the argument is omitted, while non-zero means an error which may cause the HTTP server to kill the process. An alternative way to pass the status is like so:
+
+``
+resp<< http::moved_permanently // Handled specially by the `response`.
+ << "This page is no longer valid."
+ << location("somewhere_else") // The location of the new page
+ << content_type("text/plain"); // The location header has been output, so a content-type
+ // header is needed now.
+resp.send(req.client());
+return req.close(resp.status()); // use return_() instead!
+``
+
+One final thing to note is the type of error thrown by this library, which comes from [@http://boost.org/libs/system Boost.System]:
+
+``
+try {
+ // ...
+}catch(boost::system::system_error& err){
+ // err.message() <- string representing the error
+ // err.id() <- the error code (a number)
+ // if(err) {} <- only true when err represents an error
+}
+``
+
+[tip
+ There are non-`throw`ing alternatives to most of the `throw`ing functions in the library that take an additional `boost::cgi::error_code` argument. Due to the nature of FastCGI, exceptions may be undesireable - you won't usually want all the requests a process is handling to abort just because of a problem with one of them. In this case you can use the non-throwing versions of functions and gracefully close individual requests when something goes wrong.
+]
+
+The next example is very similar to the above but shows you how you might want to organise your program. As a demonstration it also uses the non-throwing alternatives to some functions.
+
+[endsect] [/ sync_fcgi]
+
+[section:async_fcgi Asynchronous FastCGI]
+
+[endsect] [/ async_fcgi]
+
+
+[endsect] [/ scaling]
+

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/tutorial.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/tutorial.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,33 @@
+
+[section Tutorial]
+
+**FIXME** - If this doesn't get fixed, please remind me!
+
+[/include hello_world.qbk]
+
+[section:what_next The next step]
+
+Now we have a "Hello world" example compiling and working with our server we can choose to do two things:
+
+* Make a CGI program that handles user-supplied data to provide dynamic content, or
+
+* Turn the CGI "Hello world" into a FastCGI "Hello world", allowing better scalability.
+
+The first option is of course what CGI is all about: you take form data or a query string or a user's cookies and serve a custom response. The second option isn't mutually exclusive to the first, it is essentially an 'extra step' that you should be able to do at any point in the life-cycle of your application - although the sooner you do it the easier it might be!
+
+[important
+ Once you have set up an `fcgi::request`, you use it in almost exactly the same way as a `cgi::request`.
+]
+
+[link __branching__ branching?]
+
+[endsect] [/ what_next]
+
+[include scaling.qbk]
+
+[/include step_two.qbk]
+
+[/include step_three.qbk]
+
+[endsect] [/ tutorial]
+

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/variables.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/tutorial/variables.qbk 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,173 @@
+[/
+ / 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)
+ /]
+
+[def __xss_footnote__ It is generally accepted that a CGI program should pay attention to where meta-data has come from (eg. [@http://www.google.com/search?q=XSS XSS]). In other words, since `basic_request<>::form` removes such distinctions, its use should be limited to places where the source of the variable doesn't matter. For example, a language toggle (like `"hl=en"`, as Google uses) could come from anywhere and doing so is not an issue.]
+
+[section:variables Using Request Variables]
+
+[warning
+A request [*must] be [link __loading__ loaded] before the request data can be accessed.
+]
+
+[table Request variable accessor functions
+ [[Function signature] [Purpose]]
+ [
+ [`common::env_map& env`]
+ [Return a complete map of the environment meta-data for the request.]
+ ]
+ [
+ [`common::get_map& get`]
+ [Return a complete map of the GET variables for the request.]
+ ]
+ [
+ [`common::post_map& post`]
+ [Return a complete map of the POST variables associated for the request. File uploads are not stored in this map.]
+ ]
+ [
+ [`common::form_map& form`]
+ [Return a complete map of the form variables associated with the request. This is equivalent to either `get` or `post`, depending on the `request_method()` of the request.]
+ ]
+ [
+ [`common::cookie_map& cookies`]
+ [Return a complete map of the cookies for a request.]
+ ]
+ [
+ [`common::upload_map& uploads`]
+ [A map of all of the file uploads for a request. An `upload_map` is equivalent to a `std::map<common::key, common::form_part&>`.]
+ ]
+]
+
+[h3 Example usage]
+
+``
+{
+// ...
+ cgi::request request(cgi::parse_all);
+ cgi::response response;
+
+ if (request.get.count("user_id")) {
+ std::string user_id ( request.get["user_id"] );
+ }
+
+ int convert_to_int = request.get.as<int>("number");
+// ...
+}
+``
+
+The CGI specification defines a set of basic environment variables that you can expect to be set, which describe the context of the request.
+
+All of these are loaded into `basic_request<>::env` and are accessible the same as any other bit of request data:
+
+``
+cgi::request request;
+string request_method = request.env["request_method"];
+``
+
+Since looking up variables using raw strings can be error-prone, there is a safer way to reference the standard CGI environment variables. Not only are these short-cuts less error-prone, some of them convert the value into a suitable type. For instance, `content_length()` returns a `long`.
+
+The table below lists them, and briefly explains their function.[footnote Reference information largely drafted from [@http://hoohoo.ncsa.uiuc.edu/cgi/env.html] and [@http://www.ietf.org/rfc/rfc3875 RFC3875].]
+
+[table Standard CGI Meta-variables
+ [[CGI Variable] [Function signature] [Purpose]]
+ [
+ [`AUTH_TYPE`]
+ [`string_type& auth_type()`]
+ [If the server supports user authentication, and the script is protected, this is the protocol-specific authentication method used to validate the user.]
+ ]
+ [
+ [`CONTENT_LENGTH`]
+ [`long content_length()`]
+ [The size of the message-body attached to the request.]
+ ]
+ [
+ [`CONTENT_TYPE`]
+ [`string_type& content_type()`]
+ [The content type of data attached to the query, if any (ev. POST, PUT)]
+ ]
+ [
+ [`GATEWAY_INTERFACE`]
+ [`string_type& gateway_interface()`]
+ [The revision of the CGI specification to which this server complies. Format: CGI/revision, eg. `"CGI/1.1"`]
+ ]
+ [
+ [`PATH_INFO`]
+ [`common::path_info& path_info()`]
+ [The extra path information, as given by the client. In other words, scripts can be accessed by their virtual pathname, followed by extra information at the end of this path. The extra information is sent as PATH_INFO.]
+ ]
+ [
+ [`PATH_TRANSLATED`]
+ [`common::path_info& path_translated()`]
+ [The server provides a translated version of PATH_INFO, which takes the path and does any virtual-to-physical mapping to it.]
+ ]
+ [
+ [`QUERY_STRING`]
+ [`string_type& query_string()`]
+ [The information following the '?' in the URL. This is where the GET data is extracted from. Format: `"name1=value1&name2=value2..."` Any reserved characters are URL-encoded.]
+ ]
+ [
+ [`REMOTE_ADDR`]
+ [`string_type& remote_addr()`]
+ [The IP address of the remote host making the request. You should [*never] rely on the accuracy of this value, as it is easily forged.]
+ ]
+ [
+ [`REMOTE_HOST`]
+ [`string_type& remote_host()`]
+ [The hostname making the request.]
+ ]
+ [
+ [`REMOTE_IDENT`]
+ [`string_type& remote_ident()`]
+ [If the HTTP server supports [rfc 931] identification, then this variable will be set to the remote user name retrieved from the server. Usage of this variable should be limited to logging only.]
+ ]
+ [
+ [`REMOTE_USER`]
+ [`string_type& remote_user()`]
+ [If the server supports user authentication, and the script is protected, this is the username they have authenticated as.]
+ ]
+ [
+ [`REQUEST_METHOD`]
+ [`common::request_method& request_method()`]
+ [The method with which the request was made. For HTTP, this is "GET", "HEAD", "POST", etc.]
+ ]
+ [
+ [`SCRIPT_NAME`]
+ [`string_type& script_name()`]
+ [A virtual path to the script being executed, used for self-referencing URLs.]
+ ]
+ [
+ [`SCRIPT_URL`]
+ [`string_type& script_url()`]
+ [A virtual path to the script being executed, used for self-referencing URLs.]
+ ]
+ [
+ [`SCRIPT_URI`]
+ [`string_type& script_uri()`]
+ [A virtual path to the script being executed, used for self-referencing URLs.]
+ ]
+ [
+ [`SERVER_NAME`]
+ [`string_type& server_name()`]
+ [The server's hostname, DNS alias, or IP address as it would appear in self-referencing URLs.]
+ ]
+ [
+ [`SERVER_PORT`]
+ [`short server_port()`]
+ [The port number to which the request was sent.]
+ ]
+ [
+ [`SERVER_PROTOCOL`]
+ [`string_type& server_protocol()`]
+ [The name and revision of the information protcol this request came in with. Format: protocol/revision.]
+ ]
+ [
+ [`SERVER_SOFTWARE`]
+ [`string_type& server_software()`]
+ [The name and version of the information server software answering the request (and running the gateway). Format: name/version.]
+ ]
+]
+
+[endsect]

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/sessions/main.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/sessions/main.cpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,73 @@
+
+#include <boost/cgi/cgi.hpp>
+#include <iostream>
+
+using namespace std;
+
+class context
+{
+public:
+
+ context() {}
+
+ map<string,int> data;
+
+ template<typename Archive>
+ void serialize(Archive& ar, const unsigned int version)
+ {
+ ar & data;
+ }
+
+};
+
+struct session_enabled_cgi {};
+
+namespace boost { namespace cgi {
+
+template<>
+struct protocol_traits<session_enabled_cgi>
+ : protocol_traits<boost::cgi::tags::cgi>
+{
+ typedef basic_session<context> session_type;
+};
+
+} } // namespace boost::cgi
+
+using namespace boost::cgi;
+
+typedef basic_request<session_enabled_cgi> my_request;
+
+int main(int, char**)
+{
+ try
+ {
+ my_request req;
+ response resp;
+
+ resp<< "one = " << req.session.data["one"]
+ << ", two = " << req.session.data["two"]
+ << ", ten = " << req.session.data["ten"];
+
+ // Modify the request session.
+ req.session.data["one"] = 1;
+ req.session.data["two"] = 2;
+ req.session.data["ten"] = 10;
+
+ // Set the session id, so the data is saved.
+ req.session_id_ = "1";
+
+ resp<< content_type("text/plain") << "\nBlah\n";
+
+ commit(req, resp);
+
+ cout<< "Press enter to continue...";
+ //cin.get();
+ return 0;
+
+ } catch (std::exception& e) {
+ cerr<< "Error: " << e.what() << endl;
+ }
+
+ cout<< "Press enter to continue...";
+ cin.get();
+}
\ No newline at end of file

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-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -42,9 +42,9 @@
   resp.set("short_bits", 8 * sizeof(short)); // Populates {{short_bits}}.
   if (req.get.count("short"))
   {
- // Almost any type is supported by as<>
+ // Almost any type is supported by pick<>
     // (ie. any type supported by Boost.Lexical_cast.).
- short some_short = req.get.as<short>("short", -1);
+ short some_short = req.get.pick<short>("short", -1);
     resp.set("some_short", some_short);
   }
   
@@ -60,7 +60,7 @@
   
   //// Test 4.
   
- int num = req.get.as("count", 0);
+ int num = req.get.pick("count", 0);
   if (num < 0) num = 0;
   resp.set("show_less", num ? num - 1 : 0);
   resp.set("show_more", num + 1);

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/main.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/main.cpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -60,7 +60,7 @@
       string_from_currency(req.post["LoanAmt"]));
     double i = req.post.as<double>("YearlyIntRate", 1) / 1200;
     double n = req.post.as<double>("TermYrs", 1) * 12;
- double monthly_payments = (P*i) / (1 - std::pow((1+i), -n));
+ double monthly_payments = (P*i) / (1 - std::pow((1+i), -n));+
     
     ctemplate::TemplateDictionary* sub_dict
       = dict.AddSectionDictionary("RegPmtSummary");

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/charts/main.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/charts/main.cpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,158 @@
+// -- 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)
+//
+////////////////////////////////////////////////////////////////
+//
+// [fcgi_charts
+//
+
+#include <iostream>
+#include <boost/cgi/fcgi.hpp>
+#include <boost/cgi/utility/stencil.hpp>
+#include <chartdir.h>
+
+using namespace boost::fcgi;
+
+/*
+int handle_request(request& req)
+{
+ req.load(parse_all);
+
+ // Construct a response that uses Google cTemplate. Also sets the root
+ // directory where the stencils are found.
+ stencil resp("templates/");
+
+ //// Test 1.
+
+ // This is a minimal response. The content_type(...) may go before or after
+ // 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")
+ << "Hello there, universe!";
+
+ //// Test 2.
+
+ // Set some fields.
+ resp.set("script_name", req.script_name()); // Populates {{script_name}}.
+ resp.set("some_string", req.get["string"]); // Populates {{some_string}}.
+ // set() supports any type that Boost.Lexical_cast does.
+ resp.set("short_bits", 8 * sizeof(short)); // Populates {{short_bits}}.
+ if (req.get.count("short"))
+ {
+ // Almost any type is supported by as<>
+ // (ie. any type supported by Boost.Lexical_cast.).
+ short some_short = req.get.as<short>("short", -1);
+ resp.set("some_short", some_short);
+ }
+
+ //// Test 3.
+
+ // 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");
+ resp.set("show", show == "show" ? "hide" : "show");
+ if (show == "show")
+ resp.show("some_section"); // Shows {{#some_section}}...{{/some_section}}.
+
+ //// Test 4.
+
+ int num = req.get.as("count", 0);
+ 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");
+ for (int i(0); i < num; ++i)
+ {
+ // We can show a section and set one field in it in one go.
+ resp.set("some_section_variable", i + 1, sec);
+ }
+
+ //// Test 5.
+
+ resp.add(stencil::section("embedded")).set("test", "passed");
+
+ stencil::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"));
+
+ //// Test 6.
+
+ // Include another stencil into this one at marker {{>include}}.
+ resp.include(
+ stencil::section(
+ "include",
+ "stencil.include.html"
+ )
+ );
+
+ // Short-cut for stencil includes.
+ resp.include("include", "stencil.include.html");
+
+ resp<< cookie("name", "value");
+
+ /// End Tests.
+
+ // Expand the response using the specified template.
+ // cTemplate has a cache internally, which we can choose to
+ // ignore.
+ resp.expand("stencil.html", stencil::reload);
+
+ // Send the response and close the request.
+ return commit(req, resp);
+}
+*/
+
+using namespace std;
+
+int main()
+{
+try {
+
+ cout<< "Hello, world" << endl;
+
+ // The data for the bar chart
+ double data[] = {85, 156, 179.5, 211, 123};
+
+ // The labels for the bar chart
+ const char *labels[] = {"Mon", "Tue", "Wed", "Thu", "Fri"};
+
+ // Create a XYChart object of size 250 x 250 pixels
+ boost::scoped_ptr<XYChart> c (new XYChart(250, 250));
+
+ // Set the plotarea at (30, 20) and of size 200 x 200 pixels
+ c->setPlotArea(30, 20, 200, 200);
+
+ // Add a bar chart layer using the given data
+ c->addBarLayer(DoubleArray(data, sizeof(data)/sizeof(data[0])));
+
+ // Set the labels on the x axis.
+ c->xAxis()->setLabels(StringArray(labels, sizeof(labels)/sizeof(labels[0])));
+
+ // Output the chart
+ c->makeChart("simplebar.png");
+
+ cerr<< "Press enter to close console window..." << endl;
+ cin.get();
+ return 0;
+
+} catch(std::exception& e) {
+ cerr<< "Error: " << e.what() << endl;
+} catch(...) {
+ using namespace std;
+ cerr<< "Unexpected exception." << endl;
+}
+ // Control only reaches here if an exception has been caught.
+ using namespace std;
+ cerr<< "Press enter to close console window..." << endl;
+ cin.get();
+ return 1;
+}
+//]

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/Jamfile.v2 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -23,12 +23,13 @@
   :
     #[ run [ glob *.cpp ] ]
     
- [ run cookie.cpp ]
- [ run response.cpp ]
- [ run cgi_simple_request.cpp ]
- [ run name_test.cpp ]
- [ run map_test.cpp ]
- [ run parse_options.cpp ]
+ #[ run cookie.cpp ]
+ #[ run response.cpp ]
+ #[ run cgi_simple_request.cpp ]
+ #[ run name_test.cpp ]
+ #[ run map_test.cpp ]
+ #[ run parse_options.cpp ]
+ [ run data_map_proxy.cpp ]
     #[ run has_key.cpp ]
   ;
 

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/cgi_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/cgi_test.cpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,30 @@
+
+#define BOOST_TEST_MAIN blah
+#include <boost/test/unit_test.hpp>
+//#include <boost/test/included/prg_exec_monitor.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/lexical_cast.hpp>
+#include <iostream>
+
+using namespace std;
+
+int foo() { throw std::logic_error("You can't use foo()."); }
+
+int bar() { BOOST_THROW_EXCEPTION( std::logic_error("You can't use bar().") ); }
+
+template<typename T>
+T as(string val, T const& t = T()) {
+ return boost::lexical_cast<T>(val);
+}
+
+//int cpp_main(int argc, char** argv)
+BOOST_AUTO_TEST_CASE( asoduh )
+{
+ cout<< "Hello, test." << endl;
+ cout<< as<float>("3.1415962") << endl;
+ BOOST_CHECK_EQUAL( as<float>("3.1415962"), 3.1415962 );
+ BOOST_CHECK_EQUAL( boost::lexical_cast<float>("3.1415962"), 3.1415962 );
+ //bar();
+ //foo();
+ cin.get();
+}
\ No newline at end of file

Added: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/data_map_proxy.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/data_map_proxy.cpp 2010-02-25 23:43:10 EST (Thu, 25 Feb 2010)
@@ -0,0 +1,80 @@
+
+#include "boost/cgi/common/data_map_proxy.hpp"
+#include "boost/cgi/common/source_enums.hpp"
+#include <iostream>
+
+#define BOOST_TEST_MODULE data_map_proxy_test_suite
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::cgi::common;
+using std::make_pair;
+
+template<typename Map>
+void test_map(Map& data)
+{
+ /// First check that upper case compares with lower case.
+ data.insert(make_pair("foo", "bar"));
+ data.insert(make_pair("pi", "3.1415962"));
+
+ BOOST_CHECK_EQUAL( data["foo"], "bar" );
+ BOOST_CHECK_EQUAL( data["FOO"], "bar" );
+ BOOST_CHECK_EQUAL( data.count("foo"), 1 );
+
+ // Now check data_map_proxy<>.
+
+ data_map_proxy<Map> proxy;
+ proxy.set(data);
+
+ BOOST_CHECK_EQUAL( proxy["foo"], "bar" );
+ BOOST_CHECK_EQUAL( proxy["FOO"], "bar" );
+ BOOST_CHECK_EQUAL( proxy.count("foo"), 1 );
+
+ /// Then check that lower case compares with upper case.
+ BOOST_CHECK_EQUAL( proxy.as<double>("pi"), 3.1415962 );
+ BOOST_CHECK_EQUAL( proxy.as<float>("PI"), 3.1415962 );
+
+ // Sanity check.
+ BOOST_CHECK_NE( proxy["nonfoo"], "dfpij" );
+
+ // Get either the value of a variable, or a default value.
+ BOOST_CHECK_EQUAL( proxy.pick("not_in_map", "some_value"), "some_value" );
+
+ // Get either the value of a variable, converted to the specified type, or a default value.
+ BOOST_CHECK_EQUAL( proxy.as<int>("foo", 1234), 1234 );
+ // Get a default-constructed int when "foo" can't be found in the map,
+ // or it's value can't be lexically casted to an int
+ // (works on any type supported by Boost.Lexical_cast).
+ BOOST_CHECK_EQUAL( proxy.as<int>("foo"), int() );
+ // The type of the return value can be automatically deduced.
+ BOOST_CHECK_EQUAL( proxy.as("foo", 1234.56), 1234.56 );
+}
+
+BOOST_AUTO_TEST_CASE( env_map_test )
+{
+ env_map m;
+ test_map(m);
+}
+
+BOOST_AUTO_TEST_CASE( get_map_test )
+{
+ get_map m;
+ test_map(m);
+}
+
+BOOST_AUTO_TEST_CASE( post_map_test )
+{
+ post_map m;
+ test_map(m);
+}
+
+BOOST_AUTO_TEST_CASE( cookie_map_test )
+{
+ cookie_map m;
+ test_map(m);
+}
+
+BOOST_AUTO_TEST_CASE( upload_map_test )
+{
+ upload_map m;
+ test_map(m);
+}


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