$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: lists.drrngrvy_at_[hidden]
Date: 2008-08-04 17:17:03
Author: drrngrvy
Date: 2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
New Revision: 47978
URL: http://svn.boost.org/trac/boost/changeset/47978
Log:
Adding several fixes from a while ago (ike);
Plus, some fixes from Christian Leutloff (see http://tinyurl.com/5cz67a)
Added:
   sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/basic_request.ipp   (contents, props changed)
   sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/redirect.hpp   (contents, props changed)
Properties modified: 
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/   (props changed)
Text files modified: 
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/parse_options.hpp                    |    10 +++---                                  
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_base.hpp                     |    42 +++++++++++++++++++++++++++++++         
   sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/shareable_tcp_socket.hpp        |     6 ++--                                    
   sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/stdio.hpp                       |     1                                         
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/cgi_service_impl_base.hpp            |     4 +-                                      
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/save_environment.hpp                 |    10 ++++++-                                 
   sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/fcgi_request_service.ipp               |     8 +++---                                  
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/Jamfile.v2                             |    53 ++++++++++++++++++++++++++++++++++++++- 
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/Jamfile.v2                               |    20 +++++++-------                          
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/cgi.qbk                              |     2                                         
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/user_guide/tutorial/10_min_intro.cpp |    12 +++-----                                
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/echo/main.cpp                   |    23 +++++++++-------                        
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/Jamfile.v2           |     7 ++++                                    
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/echo/main.cpp                   |     3 -                                       
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/Jamfile.v2                              |     2                                         
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/request_test_template.hpp           |    42 ++++++++++++++++---------------         
   sandbox/SOC/2007/cgi/trunk/project-root.jam                                      |     1                                         
   17 files changed, 176 insertions(+), 70 deletions(-)
Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/common/parse_options.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/common/parse_options.hpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/common/parse_options.hpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -7,12 +7,12 @@
 
    enum parse_options
    {
-       parse_none      = 0  // you should *always* parse the environment!
+       parse_none      = 0  // you should *always* parse the environment.
      , parse_env       = 1
-     , parse_get       = 2
-     , parse_post      = 4
-     , parse_form      = parse_get | parse_post
-     , parse_cookie    = 8
+     , parse_get       = 2 | parse_env
+     , parse_post      = 4 | parse_env
+     , parse_form      = parse_env | parse_get | parse_post
+     , parse_cookie    = 8 | parse_env
      , parse_all       = parse_env | parse_form | parse_cookie
    };
 
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	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -19,6 +19,7 @@
 #include <boost/system/error_code.hpp>
 ////////////////////////////////////////////////////////////////
 #include "boost/cgi/common/map.hpp"
+#include "boost/cgi/common/parse_options.hpp"
 #include "boost/cgi/detail/extract_params.hpp"
 
 namespace cgi {
@@ -84,6 +85,47 @@
       return impl.client_.read_some(buf,ec);
     }
 
+    /// Synchronously read/parse the request meta-data
+    template<typename ImplType>
+    boost::system::error_code
+    load(ImplType& impl, common::parse_options parse_opts
+        , boost::system::error_code& ec)
+    {
+      if (parse_opts & common::parse_env)
+      {
+        if (!read_env_vars(impl, ec)) // returns an error_code
+          return ec;
+      }
+
+      std::string const& cl = env_vars(impl.vars_)["CONTENT_LENGTH"];
+      impl.characters_left_ = cl.empty() ? 0 : boost::lexical_cast<std::size_t>(cl);
+      impl.client_.bytes_left() = impl.characters_left_;
+
+      std::string const& request_method = env_vars(impl.vars_)["REQUEST_METHOD"];
+
+      if (request_method == "GET" && parse_opts & common::parse_get)
+      {
+        parse_get_vars(impl, ec);
+      }
+      else
+      if (request_method == "POST" && parse_opts & common::parse_post)
+      {
+        parse_post_vars(impl, ec);
+      }
+
+      if (ec) return ec;
+
+      if (parse_opts & common::parse_cookie)
+      {
+        if (!parse_cookie_vars(impl, ec)) // returns an error_code
+          return ec;
+      }
+
+      set_status(impl, common::loaded);
+
+      return ec;
+    }
+
     /// Read and parse the cgi GET meta variables
     template<typename ImplType>
     boost::system::error_code
Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/shareable_tcp_socket.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/shareable_tcp_socket.hpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/shareable_tcp_socket.hpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -50,7 +50,7 @@
     typedef boost::mutex                              mutex_type;
     struct condition_type : public boost::condition_variable
         { typedef boost::shared_ptr<boost::condition_variable> pointer; };
-    typedef boost::unique_lock<mutex_type>            scoped_lock_type;
+	typedef boost::mutex::scoped_lock                 scoped_lock_type;
     typedef boost::asio::ip::tcp::socket              next_layer_type;
 
     /** FastCGI specific stuff **/
@@ -93,13 +93,13 @@
 
     void lock()
     {
-      scoped_lock_type(mutex_);
+      scoped_lock_type lock(mutex_);
       locked_ = true;
     }
 
     void unlock()
     {
-      scoped_lock_type(mutex_);
+      scoped_lock_type lock(mutex_);
       locked_ = false;
       condition_.notify_one();
     }
Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/stdio.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/stdio.hpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/stdio.hpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -17,6 +17,7 @@
 ///////////////////////////////////////////////////////////
 #include "boost/cgi/error.hpp"
 #include "boost/cgi/common/tags.hpp"
+#include "boost/cgi/basic_connection.hpp"
 #include "boost/cgi/common/connection_base.hpp"
 #include "boost/cgi/fwd/basic_connection_fwd.hpp"
 
Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/cgi_service_impl_base.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/cgi_service_impl_base.hpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/cgi_service_impl_base.hpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -124,7 +124,7 @@
       impl.http_status() = http_s;
       return status;
     }
-
+/*
     /// Synchronously read/parse the request meta-data
     boost::system::error_code&
     load(implementation_type& impl, common::parse_options parse_opts
@@ -164,7 +164,7 @@
 
       return ec;
     }
-
+*/
     /// Synchronously read/parse the request meta-data
     /**
      * @param parse_stdin if true then STDIN data is also read/parsed
Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/save_environment.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/save_environment.hpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/save_environment.hpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -17,7 +17,7 @@
 // The process' environment
 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
   // MSVC warns of 'inconsistent dll linkage' here...
-  _CRTIMP extern char** environ;
+  _CRTIMP extern char** _environ;
 #else
   extern char** environ;
 #endif
@@ -32,7 +32,13 @@
     *            environment.
     */
    template<typename MapT>
-   void save_environment(MapT& env_map, char** env = environ)
+   void save_environment(MapT& env_map, char** env = 
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+	_environ
+#else
+	 environ
+#endif
+	   )
    {
      std::string sa;
      std::string sb;
Added: sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/basic_request.ipp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/basic_request.ipp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -0,0 +1,505 @@
+//                -- basic_request.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)
+//
+////////////////////////////////////////////////////////////////
+//
+// Defines the basic_request<> class; the main entry-point to the
+// library.
+//
+////////////////////////////////////////////////////////////////
+#ifndef CGI_BASIC_REQUEST_HPP_INCLUDED__
+#define CGI_BASIC_REQUEST_HPP_INCLUDED__
+
+#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/asio/io_service.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/asio/basic_io_object.hpp>
+///////////////////////////////////////////////////////////
+// **FIXME** Half of these are probably useless
+#include "boost/cgi/detail/protocol_traits.hpp"
+#include "boost/cgi/common/map.hpp"
+#include "boost/cgi/common/is_async.hpp"
+#include "boost/cgi/common/role_type.hpp"
+#include "boost/cgi/http/status_code.hpp"
+#include "boost/cgi/detail/throw_error.hpp"
+#include "boost/cgi/common/status_type.hpp"
+#include "boost/cgi/common/source_enums.hpp"
+#include "boost/cgi/fwd/basic_request_fwd.hpp"
+#include "boost/cgi/common/request_service.hpp"
+#include "boost/cgi/import/basic_io_object.hpp"
+#include "boost/cgi/detail/basic_sync_io_object.hpp"
+#include "boost/cgi/fwd/basic_protocol_service_fwd.hpp"
+
+namespace cgi {
+ namespace common {
+
+  /// The basic_request class, primary entry point to the library
+  /**
+   * Note: By default, synchronous protocols (ie. cgi) auto-load AND parse
+   * STDIN,whereas async protocols don't.
+   *
+   * Note: The alternative functions which take a boost::system::error_code are
+   * the non-throwing versions. Instead of a boost::system::system_error being
+   * thrown in case of an error, the passed error_code will be set to the value
+   * of the error, s.t. if (error) evaluates to true.`
+   * 
+   * Note: This class isn't thread safe: carrying around a mutex-per-request
+   * seems prohibitively expensive. There could be functions which take a mutex
+   * as an arguement and lock it. (Async calls could get messy if you need a
+   * protected request object).
+  **/
+
+    // Throws
+  template<typename RS, typename PS, typename A>
+  basic_request<RS,PS,A>::basic_request
+  (
+      bool load_now = true, bool parse_post = true
+  )
+      : detail::basic_sync_io_object<service_type>()
+  {
+    if (load_now) load(parse_post);
+  }
+
+		// Won't throw
+  template<typename RS, typename PS, typename A>
+  basic_request<RS,PS,A>::basic_request
+  (
+      boost::system::error_code& ec
+    , const bool load_now = true
+    , const bool parse_post = true
+  )
+      : detail::basic_sync_io_object<service_type>()
+  {
+    if (load_now) load(ec, parse_post);
+  }
+
+		// Throws
+  template<typename RS, typename PS, typename A>
+  basic_request<RS,PS,A>::basic_request
+  (
+      protocol_service_type& s, const bool load_now = false
+    , const bool parse_post = false
+  )
+      : basic_io_object<service_type>(s.io_service())
+  {
+    set_protocol_service(s);
+    if (load_now) load(parse_post);
+  }
+
+		// Won't throw
+  template<typename RS, typename PS, typename A>
+  basic_request<RS,PS,A>::basic_request
+  (
+      protocol_service_type& s
+    , boost::system::error_code& ec
+    , const bool load_now = false, const bool parse_post = false
+  )
+      : basic_io_object<service_type>(s.io_service())
+  {
+    set_protocol_service(s);
+    if(load_now) load(ec, parse_post);//this->service.load(this->implementation, false, ec);
+  }
+
+    /// Make a new mutiplexed request from an existing connection.
+    // Throws.
+  template<typename RS, typename PS, typename A>
+  basic_request<RS,PS,A>::    basic_request(implementation_type& impl)
+      : basic_io_object<service_type>(impl.service_->io_service())
+    {
+      set_protocol_service(*impl.service_);
+      boost::system::error_code ec;
+      this->service.begin_request_helper(this->implementation
+                                        , impl.header_buf_, ec);
+      detail::throw_error(ec);
+    }
+
+    /// Make a new mutiplexed request from an existing connection.
+    // Won't throw.
+  template<typename RS, typename PS, typename A>
+  basic_request<RS,PS,A>::    basic_request(implementation_type& impl, boost::system::error_code& ec)
+      : basic_io_object<service_type>(impl.service_->io_service())
+    {
+      set_protocol_service(*impl.service_);
+      this->service.begin_request_helper(this->implementation
+                                        , impl.header_buf_, ec);
+    }
+      
+    ~basic_request()
+    {
+      //if (is_open())
+      //  close(http::internal_server_error, 0);
+    }
+
+  template<typename RS, typename PS, typename A>
+  basic_request<RS,PS,A>::    static pointer create(protocol_service_type& ps)
+    {
+      return pointer(new type(ps));
+    }
+
+  template<typename RS, typename PS, typename A>
+  basic_request<RS,PS,A>::    void set_protocol_service(protocol_service_type& ps)
+    {
+      this->service.set_service(this->implementation, ps);
+    }
+
+    /// Return `true` if the request is still open (ie. not aborted or closed)
+  template<typename RS, typename PS, typename A>
+  basic_request<RS,PS,A>::    bool is_open()
+    {
+      return this->service.is_open(this->implementation);
+    }
+
+    /// Synchronously read/parse the request meta-data
+    /**
+     * Note: 'loading' including reading/parsing STDIN if parse_stdin == true
+     */
+    // Throwing semantics
+    void load(bool parse_stdin = false)
+    {
+      boost::system::error_code ec;
+      this->service.load(this->implementation, parse_stdin, ec);
+      detail::throw_error(ec);
+    }
+
+    // Error-code semantics (**FIXME**)
+    boost::system::error_code&
+      load(bool parse_stdin, boost::system::error_code& ec)
+    {
+      return this->service.load(this->implementation, parse_stdin, ec);
+    }
+
+    // Error-code semantics (**FIXME**)
+    boost::system::error_code&
+      load(boost::system::error_code& ec, bool parse_stdin = false)
+    {
+      return this->service.load(this->implementation, parse_stdin, ec);
+    }
+
+    buffer_type& get_buffer()
+    {
+      return this->implementation.buffer_;
+    }
+
+    // **FIXME**
+    /// Asynchronously read/parse the request meta-data
+    /**
+     * Note: 'loading' including reading/parsing STDIN if parse_stdin == true
+     */
+    //template<typename Handler>
+    //void async_load(Handler handler, bool parse_stdin = false)
+    //{
+    //  this->service.async_load(this->implementation, parse_stdin
+    //                          , handler);
+    //}
+
+    /// Notify the server the request has finished being handled
+    /**
+     * In certain situations (such as a Proactor client using the async read
+     * functions) it will be necessary to call end, rather than just returning
+     * from the sub_main function.
+     *
+     * @param program_status This value is returned to the server indicating the
+     * state of the request after it was finished handling. It is
+     * implementation defined how the server deals with this, and it may have
+     * no effect on the http status code returned to the client (eg. 200 OK).
+     *
+     * @returns The value of program_status
+     */
+    int close(common::http::status_code http_status = http::ok
+             , int program_status = 0)
+    {
+      //BOOST_ASSERT( request_status_ != status_type::ended );
+
+      //this->service.set_status(this->implementation, http_status);
+      boost::system::error_code ec;
+      this->service.close(this->implementation, http_status,
+          program_status, ec);
+      detail::throw_error(ec);
+      return program_status;
+    }
+
+    int close(common::http::status_code http_status
+             , int program_status
+             , boost::system::error_code& ec)
+    {
+      return this->service.close(this->implementation, http_status
+                                , program_status, ec);
+    }
+
+    /// Reject the request with a standard '500 Internal Server Error' error
+    int reject()
+    {
+      this->service.set_status(this->implementation, aborted);
+      return this->service.close(this->implementation
+                                , http::internal_server_error);
+    }
+
+    /// Abort a request
+    void abort()
+    {
+      this->service.set_status(this->implementation, aborted);
+    }
+
+    /// Clear the data for the request, for reusing this object.
+    // I'd imagine clearing and re-loading a request is quicker than 
+    // destroying/re-creating one. **Unverified claims** **FIXME**
+    void clear()
+    {
+      this->service.clear(this->implementation);
+    }
+
+    /// Get the client connection associated with the request
+    /**
+     * You use the client for read/write calls. Y
+		 */
+    client_type& client()
+    {
+      return this->service.client(this->implementation);
+    }
+
+    /// Read some data into the request, parsing if necessary.
+    void read_some()
+    {
+      boost::system::error_code ec;
+      this->service.read_some(this->implementation, ec);
+      detail::throw_error(ec);
+    }
+
+    /// Read some data into the request, parsing if necessary.
+    std::size_t
+    read_some(boost::system::error_code& ec)
+    {
+      return this->service.read_some(this->implementation, ec);
+    }
+
+    /// Read some data into the supplied buffer, parsing if necessary.
+    // **FIXME** (remove - use req.client().read_some() instead)
+    template<typename MutableBufferSequence>
+    void read_some(const MutableBufferSequence& buf)
+    {
+      boost::system::error_code ec;
+      this->service.read_some(this->implementation, buf, ec);
+      detail::throw_error(ec);
+    }
+
+    /// Read some data into the supplied buffer, parsing if necessary.
+    // **FIXME** (remove - use req.client().read_some() instead)
+    template<typename MutableBufferSequence>
+    std::size_t
+    read_some(const MutableBufferSequence& buf
+             , boost::system::error_code& ec)
+    {
+      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(cgi::sink dest, boost::system::error_code& ec)
+    {
+      this->service(this->implementation, dest, ec);
+    }
+    */
+
+    // [helper-functions for the basic CGI 1.1 meta-variables.
+    string_type& auth_type()
+    { return env_("AUTH_TYPE"); }
+
+    string_type& content_length()
+    { return env_("CONTENT_LENGTH"); }
+
+    string_type& content_type()
+    { return env_("CONTENT_TYPE"); }
+
+    string_type& gateway_interface()
+    { return env_("GATEWAY_INTERFACE"); }
+
+    string_type& path_info()
+    { return env_("PATH_INFO"); }
+
+    string_type& path_translated()
+    { return env_("PATH_TRANSLATED"); }
+
+    string_type& query_string()
+    { return env_("QUERY_STRING"); }
+
+    string_type& remote_addr()
+    { return env_("REMOTE_ADDR"); }
+
+    string_type& remote_host()
+    { return env_("REMOTE_HOST"); }
+
+    string_type& remote_ident()
+    { return env_("REMOTE_IDENT"); }
+
+    string_type& remote_user()
+    { return env_("REMOTE_USER"); }
+
+    string_type& request_method()
+    { return env_("REQUEST_METHOD"); }
+
+    string_type& script_name()
+    { return env_("SCRIPT_NAME"); }
+
+    string_type& server_name()
+    { return env_("SERVER_NAME"); }
+
+    string_type& server_port()
+    { return env_("SERVER_PORT"); }
+
+    string_type& server_protocol()
+    { return env_("SERVER_PROTOCOL"); }
+
+    string_type& server_software()
+    { return env_("SERVER_SOFTWARE"); }
+
+    string_type& referer()
+    { return env_("HTTP_REFERER"); }
+    // -- end helper-functions]
+
+    /// Get the charset from the CONTENT_TYPE header
+    string_type charset()
+    {
+      // Not sure if regex is needlessly heavy-weight here.
+      boost::regex re(";[ ]?charset=([-\\w]+);");
+      boost::smatch match;
+      if (!boost::regex_match(this->content_type(), match, re))
+        return ""; // A default could go here.
+
+      return match[1];
+    }
+
+    /// The role that the request is playing
+    /**
+     * The default role type is responder.
+     *
+     * In some cases - for instance with FastCGI - the role type can be
+     * different
+     * eg. authorizer, or filter.
+     */
+    role_type& role()
+    {
+      return this->service.get_role(this->implementation);
+    }
+
+    void set_status(common::http::status_code const& status)
+    {
+      this->service.set_status(this->implementation, status);
+    }
+
+    ////////////////////////////////////////////////////////////
+    // Note on operator[]
+    // ------------------
+    // It is overloaded on different enum types to allow
+    // compile-time (I hope) retrieval of different data
+    // maps.
+    //
+
+    // The first three overloads are for directly looking into the 
+    // environment.
+    // eg.
+    // string_type& val = req["some name"];
+
+    /// Get the value of the environment variable with name `n`.
+    string_type& operator[](string_type const& n)
+    {
+      return env_vars(this->implementation.vars_)[n.c_str()];
+    }
+
+    /// Get the value of the environment variable with name `n`.
+    string_type& operator[](const char* n)
+    {
+      return env_vars(this->implementation.vars_)[n];
+    }
+
+    /// Get the value of the environment variable with name `n`.
+    string_type& operator[](common::name const& n)
+    {
+      return env_vars(this->implementation.vars_)[n];
+    }
+
+    /// Get a `common::env_map&` of all the environment variables.
+    env_map& operator[](common::env_data_type const&)
+    {
+      return env_vars(this->implementation.vars_);
+    }
+
+    /// Get a `common::get_map&` of all the GET variables.
+    get_map& operator[](common::get_data_type const&)
+    {
+      return get_vars(this->implementation.vars_);
+    }
+
+    /// Get a `common::post_map&` of all the POST variables.
+    post_map& operator[](common::post_data_type const&)
+    {
+      return post_vars(this->implementation.vars_);
+    }
+
+    /// Get a `common::cookie_map&` of all the cookies.
+    cookie_map& operator[](common::cookie_data_type const&)
+    {
+      return cookie_vars(this->implementation.vars_);
+    }
+
+    /// Get a `common::form_map&` of either the GET or POST variables.
+    form_map& operator[](common::form_data_type const&)
+    {
+      if (request_method() == "GET")
+        return get_vars(this->implementation.vars_);
+      else
+      if (request_method() == "POST")
+        return post_vars(this->implementation.vars_);
+      else
+        return env_vars(this->implementation.vars_);
+    }
+    ////////////////////////////////////////////////////////////
+
+    /// The id of this request.
+    /**
+     * This is 1 for CGI/aCGI requests, but may be != 1 for FastCGI requests.
+     * Note that for FastCGI requests, the id's are assigned on a
+     * *per-connection* policy, so in one application you may have several
+     * requests with the same id.
+     */
+    int id()
+    {
+      return this->service.request_id(this->implementation);
+    }
+
+  private:
+    // Internal shortcut for named env-var functions (eg. script_name() above).
+    string_type& env_(const char* name)
+    {
+      return env_vars(this->implementation.vars_)[name];
+    }
+  };
+
+ } // namespace common
+} // namespace cgi
+
+#include "boost/cgi/detail/pop_options.hpp"
+
+#endif // CGI_BASIC_REQUEST_HPP_INCLUDED__
+
+/*
+NOTES::future_plans:
+* When a request is aborted (eg. when the client closes the connection)
+  the library can call an abort_handler() function stored in the request.
+  - The user should supply an abort_handler-derived function if they want
+    any special handling of aborted requests
+*/
+
Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/fcgi_request_service.ipp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/fcgi_request_service.ipp	(original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/impl/fcgi_request_service.ipp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -120,7 +120,7 @@
      *    packet for this request arrives from the server.
      *
      */
-    
+/*    
     /// Synchronously read/parse the request meta-data
     BOOST_CGI_INLINE boost::system::error_code
     fcgi_request_service::load(
@@ -129,7 +129,7 @@
     {
       if (parse_opts & common::parse_env)
       {
-        if (read_env_vars(impl, ec)) // returns an error_code
+        if (!read_env_vars(impl, ec)) // returns an error_code
           return ec;
       }
 
@@ -153,7 +153,7 @@
 
       if (parse_opts & common::parse_cookie)
       {
-        if (parse_cookie_vars(impl, ec)) // returns an error_code
+        if (!parse_cookie_vars(impl, ec)) // returns an error_code
           return ec;
       }
 
@@ -161,7 +161,7 @@
 
       return ec;
     }
-
+*/
     BOOST_CGI_INLINE boost::system::error_code
     fcgi_request_service::load(
         implementation_type& impl, bool parse_stdin
Added: sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/redirect.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/redirect.hpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -0,0 +1,39 @@
+
+#ifndef BOOST_CGI_REDIRECT_HPP_INCLUDED_
+#define BOOST_CGI_REDIRECT_HPP_INCLUDED_
+
+#include <string>
+///////////////////////////////////////////////////////////
+#include <boost/system/error_code.hpp>
+///////////////////////////////////////////////////////////
+#include "boost/cgi/write.hpp"
+#include "boost/cgi/header.hpp"
+#include "boost/cgi/detail/throw_error.hpp"
+
+namespace cgi {
+ namespace common {
+
+   /// Redirect a request to another place.
+   template <typename RequestT>
+   boost::system::error_code
+   redirect(RequestT& req, typename RequestT::string_type const& dest
+           , boost::system::error_code& ec)
+   {
+     basic_header<typename RequestT::char_type> hdr("Location", dest);
+     write(req.client(), buffer(hdr.content), ec);
+     return ec;
+   }
+
+   template <typename RequestT>
+   void redirect(RequestT& req, std::string const& dest)
+   {
+     boost::system::error_code ec;
+     redirect(req, dest, ec);
+     detail::throw_error(ec);
+   }
+
+ } // namespace common
+} // namespace cgi
+
+#endif // BOOST_CGI_REDIRECT_HPP_INCLUDED_
+
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/build/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/build/Jamfile.v2	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/build/Jamfile.v2	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -8,6 +8,46 @@
   DEFINES = <define>BOOST_CGI_BUILD_LIB ;
 } 
 
+# --------------------------------
+rule tag ( name : type ? : property-set )
+{
+    if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
+    {
+        if $(layout) = versioned
+        {
+            local result = [ common.format-name
+                <base> <toolset> <threading> <runtime> # -$(BOOST_VERSION_TAG)
+                # -$(BUILD_ID)
+                : $(name) : $(type) : $(property-set) ] ;
+            
+            # Optionally add version suffix.
+            # On NT, library with version suffix won't be recognized
+            # by linkers. On CYGWIN, we get strage duplicate symbol
+            # errors when library is generated with version suffix.
+            # On OSX, version suffix is not needed -- the linker expets
+            # libFoo.1.2.3.dylib format.
+            # AIX linkers don't accept version suffixes either.
+            # Pgi compilers can't accept library with version suffix
+            #if $(type) = SHARED_LIB &&
+            #  ( ! ( [ $(property-set).get <target-os> ] in windows cygwin darwin aix ) &&
+            #    ! ( [ $(property-set).get <toolset> ] in pgi ) )
+            #{
+            #    result = $(result).$(BOOST_VERSION)  ;
+            #}
+            
+            return $(result) ;
+        }
+        else
+        {
+            return [ common.format-name
+                <base> <threading> <runtime> # -$(BUILD_ID)
+                : $(name) : $(type) : $(property-set) ] ;
+        }
+    }
+}
+
+# --------------------------------
+
 project boost/cgi
   : build-dir
       $(top)/bin.v2
@@ -17,6 +57,7 @@
       <library>/boost/thread/
       <library>/boost/system/
       <library>/boost/regex/
+			<library>/boost/date_time/
       <define>_CRT_SECURE_NO_WARNINGS
       <define>_SCL_SECURE_NO_WARNINGS
       $(DEFINES)
@@ -26,7 +67,11 @@
       <library>/boost/thread/
       <library>/boost/system/
       <library>/boost/regex/
-      <linkflags>-pthread
+			<library>/boost/date_time/
+      <define>_CRT_SECURE_NO_WARNINGS
+      <define>_SCL_SECURE_NO_WARNINGS
+      <os>unix:<linkflags>-pthread
+      #<tag>@$(__name__).tag
       $(DEFINES)
   ;
 
@@ -34,7 +79,7 @@
 { # compile library
   ECHO "Building CGI library" ;
 
-  # make BB recognise .ipp files as .cpp files.
+  # make BB recognise .ipp files as .cpp (source) files.
   import type ;
   type.register IPP : ipp : CPP ;
 
@@ -50,6 +95,10 @@
 else
 {
   alias boost_cgi ;
+
+  # make BB recognise .ipp files as .hpp (header) files.
+	import type ;
+	type.register IPP : ipp : HPP ;
 }
 
 install install
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	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -6,9 +6,9 @@
 #project boost.cgi.docs
 #  ;
 
-#import boostbook : boostbook ;
-import quickbook ;
+import boostbook : boostbook ;
 import doxygen ;
+import quickbook ;
 
 # compile the doxygen sources here
 doxygen autodoc
@@ -33,10 +33,10 @@
 
     [ glob ../../../boost/cgi/connections/*.hpp ]
   :
-    #<doxygen.processor>doxproc
-    #<doxygen.doxproc.index>yes
-    #<doxygen.doxproc.title>"Developer Reference"
-    #<doxygen.doxproc.id>"developer_reference"
+    <doxygen.processor>doxproc
+    <doxygen.doxproc.index>yes
+    <doxygen.doxproc.title>"Developer Reference"
+    <doxygen.doxproc.id>"developer_reference"
 
     <doxygen:param>HIDE_UNDOC_MEMBERS=NO
     <doxygen:param>EXTRACT_PRIVATE=NO
@@ -75,8 +75,8 @@
     #<xsl:param>chunk.section.depth=2 # chunk
          ;
 
-#install html
-#	:
-#	  /boost//doc/html/boostbook.css
+install html
+	:
+	  /boost//doc/html/boostbook.css
 #	  /bin/doc/$(toolset)/debug/cgi_xml.xml 
-#	;
+	;
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	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -78,7 +78,7 @@
 ]
 
 [important
-This manual does [*not] document a library that is a part of __Boost__. The major part of it has been developed this summer as part of the Google Summer of Code, '[@http://code.google.com/soc GSoC07]'. Everything from here on in is alpha-grade, some bits more than others; [link boost.cgi.preface.comments_and_support comments and bug reports] are welcome.
+This manual does [*not] document a library that is a part of __Boost__. The major part of it has been developed this summer as part of the Google Summer of Code, '[@http://code.google.com/soc/2007 GSoC07]'. Everything from here on in is alpha-grade, some bits more than others; [link boost.cgi.preface.comments_and_support comments and bug reports] are welcome.
 
 These documents are either hosted at [@http://sourceforge.net/projects/cgi/ sourceforge], or at [@http://svn.boost.org/svn/boost/browser/sandbox/SOC/2007/cgi svn.boost.org]. For free!
 ]
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/user_guide/tutorial/10_min_intro.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/user_guide/tutorial/10_min_intro.cpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/user_guide/tutorial/10_min_intro.cpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -12,9 +12,9 @@
   request req;
 
 /*`
-At this point, the environment variables are accessible. This includes cookie and form variables too, which by default are all parsed.
+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 is simpler. 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!".
+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!".
 */
 
   response resp;
@@ -23,7 +23,7 @@
 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.cookie_("user_name") );
+  std::string user_name( req[cookie]["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.
@@ -45,7 +45,7 @@
 /*`
 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");
+  user_name = req[form]["user_name"];
 
   if (!user_name.empty())
   {
@@ -60,18 +60,16 @@
     resp<< cookie("user_name", user_name)
         << header("Date", "Tue, 15 Nov 1994 08:12:31 GMT")
         << header("Content-type", "text/plain")
-        << header() // this terminates the headers
         << "Hello there, " << user_name << ". You're new around here.";
 
     resp.send(req);
   }
 
 /*`
-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 `req.set_header("Content-type", "text/html")` or `resp<< header("Content-type", "text/html")`. Since writing with raw strings is error-prone, the shortcut below is available.
+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<< content_type("text/html")
-      << header() // remember to end the headers
       << "Hello there. What's your name?" "<p />"
          "<form method='POST'>"
          "<input type='text' name='user_name' />"
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/echo/main.cpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/echo/main.cpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -93,7 +93,7 @@
     try {
 
       boost::system::error_code ec;
-      req.load(ec, true);
+      req.load(ec, parse_all); // parse everything.
 
       if (ec)
       {
@@ -130,19 +130,22 @@
                  "<input type=submit value=submit />"
                "</form><p />";
 
-      format_map(resp, req[env],     "Environment Variables");
-      format_map(resp, req[get],     "GET Variables");
-      format_map(resp, req[post],    "POST Variables");
+      format_map(resp, req[env], "Environment Variables");
+      format_map(resp, req[get], "GET Variables");
+      format_map(resp, req[post], "POST Variables");
       format_map(resp, req[cookies], "Cookie Variables");
 
-      resp<<   "<pre>";
-      BOOST_FOREACH(char& ch, req.post_buffer())
+      if (req["request_method"] = "GET")
       {
-        resp<< ch;
+        resp<<   "<pre>";
+        BOOST_FOREACH(char& ch, req.post_buffer())
+        {
+          resp<< ch;
+        }
+        resp<<   "</pre>"
+               "</body>"
+               "</html>";
       }
-      resp<<   "</pre>"
-             "</body>"
-             "</html>";
 
       return_(resp, req, 0); // All ok.
 
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/Jamfile.v2	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/Jamfile.v2	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -6,7 +6,12 @@
 
 project boost/cgi/example/cgi/hello_world ;
 
-exe cgi_hello_world : main.cpp /boost/regex/ ;
+exe cgi_hello_world
+  :
+     main.cpp /boost/regex/ /boost/cgi/
+  :
+  ;
+
 
 # Our install rule (builds binaries and copies them to <location>)
 install install
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/echo/main.cpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/echo/main.cpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -152,8 +152,7 @@
   //
   resp<< "Response content-length == "
       << resp.content_length() // the content-length (returns std::size_t)
-      << content_length(resp)  // a content-length header
-      << ">";
+      << content_length(resp); // a content-length header
 
   // This funky macro finishes up:
   return_(resp, req, 0);
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/Jamfile.v2	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/Jamfile.v2	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -2,7 +2,7 @@
 
 project
   : requirements
-      <include>$(BOOST_ROOT)
+      <include>$(boost-root)
       <include>../../../
       # suppress annoying MSVC warnings
       <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/request_test_template.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/request_test_template.hpp	(original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/request_test_template.hpp	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -3,13 +3,13 @@
                                                                                  \
   /* Check environment parsing */                                                \
   BOOST_CHECK( req[env_data].size() );                                           \
-  BOOST_CHECK_EQUAL( req[env_data]["HTTP_HOST"], "localhost" );                  \
-  BOOST_CHECK_EQUAL( req[env_data]["EMPTY_VAR"], "" );                           \
-  BOOST_CHECK_EQUAL( req[env_data]["UGLY_VAR"], "$££$^%%£&&^%@%26$ £_abcd" );    \
-  BOOST_CHECK_EQUAL( req[env_data]["QUERY_STRING"]                               \
+  BOOST_CHECK_EQUAL( req[env]["HTTP_HOST"], "localhost" );                       \
+  BOOST_CHECK_EQUAL( req[env]["EMPTY_VAR"], "" );                                \
+  BOOST_CHECK_EQUAL( req[env]["UGLY_VAR"], "$££$^%%£&&^%@%26$ £_abcd" );         \
+  BOOST_CHECK_EQUAL( req[env]["QUERY_STRING"]                                    \
                    , "hello=world&foo=bar&encoded=%22!%C2%A3$%^$*^hh%%thd@:~" ); \
   /* Check case-insensitive name comparing */                                    \
-  BOOST_CHECK_EQUAL( req[env_data]["http_host"], "localhost" );                  \
+  BOOST_CHECK_EQUAL( req[env]["http_host"], "localhost" );                       \
   /* Check helper function (need to test them all?) */                           \
   BOOST_CHECK_EQUAL( req.script_name(), "some/test/script" ); 
 
@@ -20,45 +20,47 @@
   BOOST_CHECK_EQUAL( req.request_method(), "GET" );                             \
                                                                                 \
   /* Check GET data/query string parsing */                                     \
-  BOOST_CHECK( req[get_data].size() );                                          \
-  BOOST_CHECK_EQUAL( req[get_data]["hello"], "world" );                         \
-  BOOST_CHECK_EQUAL( req[get_data]["foo"], "bar" );                             \
+  BOOST_CHECK( req[get].size() );                                               \
+  BOOST_CHECK_EQUAL( req[get]["hello"], "world" );                              \
+  BOOST_CHECK_EQUAL( req[get]["foo"], "bar" );                                  \
   /* Case-insensitive check */                                                  \
-  BOOST_CHECK_EQUAL( req[get_data]["FOO"], "bar" );                             \
+  BOOST_CHECK_EQUAL( req[get]["FOO"], "bar" );                                  \
   /* Value should be case-sensitive */                                          \
-  BOOST_CHECK_NE( req[get_data]["foo"], "BAR" );                                \
+  BOOST_CHECK_NE( req[get]["foo"], "BAR" );                                     \
   /* Check url-decoding */                                                      \
-  BOOST_CHECK_EQUAL( req[get_data]["encoded"], "\"!£$%^$*^hh%%thd@:~" );
+  BOOST_CHECK_EQUAL( req[get]["encoded"], "\"!£$%^$*^hh%%thd@:~" );
 
 
 #define TEST_ONE_COOKIE(req)                                                    \
                                                                                 \
     /* Check cookie parsing */                                                  \
-    BOOST_CHECK( req[cookie_data].size() );                                     \
-    BOOST_CHECK_EQUAL( req[cookie_data]["foo"], "bar" );                        \
+    BOOST_CHECK( req[cookies].size() );                                         \
+    BOOST_CHECK_EQUAL( req[cookies]["foo"], "bar" );                            \
     /* Check case-insensitive name comparing */                                 \
-    BOOST_CHECK_EQUAL( req[cookie_data]["FOO"], "bar" );
+    BOOST_CHECK_EQUAL( req[cookies]["FOO"], "bar" );
 
 #define TEST_TWO_COOKIES(req)                                                   \
                                                                                 \
-    BOOST_CHECK_EQUAL( req[cookie_data]["foo"], "bar" );                        \
-    BOOST_CHECK_EQUAL( req[cookie_data]["another_one"], "stuff" );
+    BOOST_CHECK_EQUAL( req[cookies]["foo"], "bar" );                            \
+    BOOST_CHECK_EQUAL( req[cookies]["another_one"], "stuff" );
  
 #define TEST_ENCODED_COOKIE(req)                                                \
                                                                                 \
-    BOOST_CHECK_EQUAL( req[cookie_data]["foo"], "bar" );                        \
-    BOOST_CHECK_EQUAL( req[cookie_data]["encoded"], "\"£$%^$*^hh%%thd@:" );
+    BOOST_CHECK_EQUAL( req[cookies]["foo"], "bar" );                            \
+    BOOST_CHECK_EQUAL( req[cookies]["encoded"], "\"£$%^$*^hh%%thd@:" );
 
 
 #include <string>
 #include <cstdlib>
 #include <boost/config.hpp>
 
-#ifdef BOOST_MSVC
+#ifdef BOOST_WINDOWS
   // MSVC doesn't support setenv, but it does support putenv
   void setenv(std::string const& name, std::string const& val, int reset = 0)
   {
-    if (putenv((name + val).c_str()) != 0)
+	 
+    //char *envvar = new char["
+    if (0 != _putenv((name + "=" + val).c_str()))
     {
       std::cerr<< "Error adding environment variable." << std::endl;
     }
Modified: sandbox/SOC/2007/cgi/trunk/project-root.jam
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/project-root.jam	(original)
+++ sandbox/SOC/2007/cgi/trunk/project-root.jam	2008-08-04 17:17:01 EDT (Mon, 04 Aug 2008)
@@ -136,3 +136,4 @@
 use-project /boost/cgi/ : $(top)/libs/cgi/build ;
 
 project anon : build-dir bin.v2 ;
+