Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55766 - in sandbox/SOC/2007/cgi/branches/pickmeup: boost/cgi boost/cgi/common boost/cgi/connections boost/cgi/detail boost/cgi/impl boost/cgi/utility libs/cgi/build libs/cgi/build/msvc/9.0/Boost.CGI libs/cgi/build/msvc/9.0/Boost.CGI/acgi_cookie_game libs/cgi/build/msvc/9.0/Boost.CGI/acgi_echo libs/cgi/doc libs/cgi/doc/src libs/cgi/example/acgi/amortization libs/cgi/example/acgi/cookie_game2 libs/cgi/example/acgi/echo libs/cgi/example/acgi/login libs/cgi/example/fcgi/amortization libs/cgi/example/fcgi/hello_world libs/cgi/example/fcgi/server1 libs/cgi/example/fcgi/server2 libs/cgi/example/fcgi/server3 libs/cgi/test/run
From: lists.drrngrvy_at_[hidden]
Date: 2009-08-24 14:07:14


Author: drrngrvy
Date: 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
New Revision: 55766
URL: http://svn.boost.org/trac/boost/changeset/55766

Log:
Development commit - please test and report bugs to darren_at_[hidden]
* Added proxies maps to the basic_request<> class, allowing direct to the request data as member variables (eg. req.env, req.get, req.cookies)
* Added charset() function to set the charset for a response.
* Updated MSVC project files.
* [WARNING] Testing using a multimap for GET data. (change to one line in common/map.hpp).
* Added path_info for better access to the PATH_INFO. Get it using eg. req.path_info()
* Minor other fixes and changes
Added:
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/doc/src/design.qbk (contents, props changed)
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/test/run/has_key.cpp (contents, props changed)
Binary files modified:
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.ncb
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.suo
Text files modified:
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/basic_request.hpp | 120 ++++++++++++++++++++++++++-----
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/header.hpp | 20 +++++
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/map.hpp | 3
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/path_info.hpp | 16 +++-
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/request_base.hpp | 31 +++++--
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/response.hpp | 9 ++
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/tags.hpp | 1
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/connections/stdio.hpp | 2
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/cgi_service_impl_base.hpp | 49 ++----------
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/extract_params.hpp | 11 +-
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/save_environment.hpp | 10 +-
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/impl/form_parser.ipp | 2
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/impl/response.ipp | 15 +++
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/utility/get.hpp | 5
   sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/utility/has_key.hpp | 20 ++--
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/Jamfile.v2 | 21 +++--
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.sln | 17 ++++
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/acgi_cookie_game/acgi_cookie_game.vcproj | 2
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/acgi_echo/acgi_echo.vcproj | 4
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/doc/Jamfile.v2 | 150 ++++++++++++++++++++++++++++++---------
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/amortization/main.cpp | 23 +----
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/cookie_game2/Jamfile.v2 | 12 --
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/cookie_game2/main.cpp | 32 +++++--
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/echo/main.cpp | 60 ++++++++++-----
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/CheckCookie.cpp | 4
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/Login.cpp | 14 +-
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/Logout.cpp | 3
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/amortization/main.cpp | 30 ++++---
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/hello_world/main.cpp | 17 +--
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server1/main.cpp | 6
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server2/main.cpp | 6
   sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server3/main.cpp | 2
   32 files changed, 474 insertions(+), 243 deletions(-)

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/basic_request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/basic_request.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/basic_request.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -24,19 +24,19 @@
 #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/path_info.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/source_enums.hpp"
-#include "boost/cgi/fwd/basic_request_fwd.hpp"
 #include "boost/cgi/common/request_service.hpp"
+#include "boost/cgi/http/status_code.hpp"
+#include "boost/cgi/fwd/basic_request_fwd.hpp"
+#include "boost/cgi/fwd/basic_protocol_service_fwd.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"
+#include "boost/cgi/detail/throw_error.hpp"
+#include "boost/cgi/detail/protocol_traits.hpp"
 
 namespace cgi {
  namespace common {
@@ -53,7 +53,7 @@
    *
    * 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
+ * as an argument and lock it. (Async calls could get messy if you need a
    * protected request object).
   **/
   template<typename RequestService
@@ -86,11 +86,75 @@
     typedef typename implementation_type::client_type client_type;
     typedef typename implementation_type::buffer_type buffer_type;
 
+ /// A proxy class to provide access to the data maps as member variables.
+ /**
+ * This wraps the underlying data map and exposes a std::map-like interface
+ * for the different data maps.
+ *
+ * It also includes an as<> member function which casts the found data into
+ * any type the user specifies.
+ */
+ template<typename MapType>
+ struct data_map_proxy
+ {
+ typedef MapType map_type;
+ typedef typename map_type::key_type key_type;
+ typedef typename map_type::value_type value_type;
+ typedef typename map_type::mapped_type mapped_type;
+ typedef typename map_type::size_type size_type;
+ typedef typename map_type::iterator iterator;
+ typedef typename map_type::const_iterator const_iterator;
+ typedef typename map_type::reverse_iterator reverse_iterator;
+ typedef typename map_type::const_reverse_iterator const_reverse_iterator;
+ typedef typename map_type::allocator_type allocator_type;
+
+ void set(map_type& data) { impl = &data; }
+
+ iterator begin() { return impl->begin(); }
+ iterator end() { return impl->end(); }
+ const_iterator begin() const { return impl->begin(); }
+ const_iterator end() const { return impl->end(); }
+
+ reverse_iterator rbegin() { return impl->rbegin(); }
+ reverse_iterator rend() { return impl->rend(); }
+ const_reverse_iterator rbegin() const { return impl->rbegin(); }
+ const_reverse_iterator rend() const { return impl->rend(); }
+
+ bool empty() { return impl->empty(); }
+
+ void clear() { return impl->clear(); }
+
+ size_type size() const { return impl->size(); }
+
+ size_type count(const key_type& key) { return impl->count(key); }
+
+ template<typename T>
+ T as(key_type const& key) {
+ mapped_type& val((*impl)[key]);
+ return val.empty() ? T() : boost::lexical_cast<T>(val);
+ }
+
+ mapped_type& operator[](key_type const& varname) {
+ return (*impl)[varname.c_str()];
+ }
+
+ operator map_type&() { return *impl; }
+
+ private:
+ map_type* impl;
+ };
+
+ data_map_proxy<env_map> env;
+ data_map_proxy<post_map> post;
+ data_map_proxy<get_map> get;
+ data_map_proxy<cookie_map> cookies;
+
     basic_request(const parse_options opts = parse_none
                  , char** base_env = NULL)
       : detail::basic_sync_io_object<service_type>()
     {
       if (opts > parse_none) load(opts, base_env);
+ construct();
     }
 
     // Won't throw
@@ -99,7 +163,8 @@
                  , char** base_env = NULL)
       : detail::basic_sync_io_object<service_type>()
     {
- if (opts > parse_none) load(opts, ec);
+ if (opts > parse_none) load(opts, ec);
+ construct();
     }
 
     // Throws
@@ -110,6 +175,7 @@
     {
       set_protocol_service(s);
       if (opts > parse_none) load(opts, base_env);
+ construct();
     }
 
     // Won't throw
@@ -121,6 +187,7 @@
     {
       set_protocol_service(s);
       if (opts > parse_none) load(opts, ec, base_env);
+ construct();
     }
 
     /// Make a new mutiplexed request from an existing connection.
@@ -132,6 +199,7 @@
       boost::system::error_code ec;
       this->service.begin_request_helper(this->implementation
                                         , impl.header_buf_, ec);
+ construct();
       detail::throw_error(ec);
     }
 
@@ -143,6 +211,7 @@
       set_protocol_service(*impl.service_);
       this->service.begin_request_helper(this->implementation
                                         , impl.header_buf_, ec);
+ construct();
     }
       
     ~basic_request()
@@ -150,6 +219,14 @@
       //if (is_open())
       // close(http::internal_server_error, 0);
     }
+
+ void construct()
+ {
+ this->env.set(env_vars(this->implementation.vars_));
+ this->post.set(post_vars(this->implementation.vars_));
+ this->get.set(get_vars(this->implementation.vars_));
+ this->cookies.set(cookie_vars(this->implementation.vars_));
+ }
 
     static pointer create(protocol_service_type& ps)
     {
@@ -176,8 +253,8 @@
     {
       boost::system::error_code ec;
       this->service.load(this->implementation, parse_opts, ec);
- if (!ec && base_env)
- load(base_env);
+ //if (base_env)
+ // load(base_env);
       detail::throw_error(ec);
     }
 
@@ -186,8 +263,7 @@
       load(parse_options parse_opts, boost::system::error_code& ec
           , char** base_environment = NULL, bool is_command_line = true)
     {
- boost::system::error_code& ec (
- this->service.load(this->implementation, parse_opts, ec));
+ this->service.load(this->implementation, parse_opts, ec);
       if (base_environment)
         this->service.load_environment(this->implementation, base_environment
                                       , is_command_line);
@@ -342,11 +418,15 @@
     { return env_("AUTH_TYPE"); }
 
     /// Get the content length as a long.
+ /**
+ * The content length defaults to zero if it isn't explicitly set
+ * by your HTTP server.
+ */
     long content_length()
- { return boost::lexical_cast<long>(env_("CONTENT_LENGTH")); }
-
- //string_type& content_length()
- //{ return env_("CONTENT_LENGTH"); }
+ {
+ string_type& cl(env_("CONTENT_LENGTH"));
+ return boost::lexical_cast<long>(cl.empty() ? "0" : cl);
+ }
 
     string_type& content_type()
     { return env_("CONTENT_TYPE"); }
@@ -354,7 +434,7 @@
     string_type& gateway_interface()
     { return env_("GATEWAY_INTERFACE"); }
 
- string_type& path_info()
+ common::path_info path_info()
     { return env_("PATH_INFO"); }
 
     string_type& path_translated()
@@ -511,10 +591,12 @@
      */
     form_map& operator[](common::form_data_type const&)
     {
- if (request_method() == "GET")
+ // Save the method as a case-insensitive string (saves on lookups too).
+ common::name rm(request_method().c_str());
+ if (rm == "GET" || rm == "HEAD")
         return get_vars(this->implementation.vars_);
       else
- if (request_method() == "POST")
+ if (rm == "POST")
         return post_vars(this->implementation.vars_);
       else
         return env_vars(this->implementation.vars_);

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/header.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/header.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/header.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -55,6 +55,20 @@
 
      string_type content;
    };
+
+ template<typename CharT>
+ struct charset_header
+ {
+ typedef CharT char_type;
+ typedef typename std::basic_string<CharT> string_type;
+
+ charset_header(const string_type& _content)
+ : content(_content)
+ {
+ }
+
+ string_type content;
+ };
 
 /*
   template<typename StringT>
@@ -89,6 +103,12 @@
      return basic_header<CharT>("Content-type", str);
    }
 
+ template<typename CharT> charset_header<CharT>
+ charset(const CharT* str)
+ {
+ return charset_header<CharT>(str);
+ }
+
    template<typename CharT> basic_header<CharT>
      content_encoding(std::basic_string<CharT> const& str)
    {

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/map.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/map.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/map.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -13,6 +13,7 @@
  namespace common {
 
   typedef std::map< ::cgi::common::name, std::string> map;
+ typedef std::multimap< ::cgi::common::name, std::string> multimap;
 
    /**
     * If you want to add a new data type to a request you need to:
@@ -23,7 +24,7 @@
     * next to the other uses of it.
     */
   typedef map env_map;
- typedef map get_map;
+ typedef multimap get_map;
   typedef map post_map;
   typedef map form_map;
   typedef map cookie_map;

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/path_info.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/path_info.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/path_info.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -11,13 +11,14 @@
 namespace cgi {
  namespace common {
 
- namespace algo = boost::string::algorithm;
+ namespace algo = boost::algorithm;
 
    struct path_info
    {
- typedef std::string value_type;
- typedef std::vector<value_type> vector_type;
- typedef vector_type::iterator iterator;
+ typedef std::string value_type;
+ typedef std::vector<value_type> vector_type;
+ typedef vector_type::iterator iterator;
+ typedef vector_type::const_iterator const_iterator;
 
      template<typename S, typename P, typename A>
      path_info(basic_request<S,P,A> & request)
@@ -32,6 +33,13 @@
      {
              algo::split(parts, value, algo::is_any_of("/"));
      }
+
+ value_type& operator[](int i) { return parts[i]; }
+
+ iterator begin() { return parts.begin(); }
+ iterator end() { return parts.end(); }
+ const_iterator begin() const { return parts.begin(); }
+ const_iterator end() const { return parts.end(); }
 
      value_type value;
      vector_type parts;

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/request_base.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/request_base.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/request_base.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -65,9 +65,19 @@
         , common::post_map, common::cookie_map
         , common::session_map
> var_map_type;
+
+ /// Construct.
+ impl_base()
+ : vars_(), post_buffer_()
+ , get_parsed_(false), env_parsed_(false)
+ {}
 
       var_map_type vars_;
       buffer_type post_buffer_;
+ /// Whether the get data has been parsed yet.
+ bool get_parsed_;
+ /// Whether the environment has been parsed yet.
+ bool env_parsed_;
 
       mutable_buffers_type prepare(std::size_t size)
       {
@@ -130,7 +140,8 @@
 
       std::string const& request_method = env_vars(impl.vars_)["REQUEST_METHOD"];
 
- if (request_method == "GET" && parse_opts & common::parse_get)
+ if ((request_method == "GET" || request_method == "HEAD")
+ && (parse_opts & common::parse_get))
       {
         parse_get_vars(impl, ec);
       }
@@ -160,14 +171,16 @@
     {
       // Make sure the request is in a pre-loaded state
       //BOOST_ASSERT (impl.status() <= unloaded);
-
- std::string const& vars (env_vars(impl.vars_)["QUERY_STRING"]);
- if (!vars.empty())
- detail::extract_params(vars, get_vars(impl.vars_)
- , boost::char_separator<char>
- ("", "=&", boost::keep_empty_tokens)
- , ec);
-
+ if (!impl.get_parsed_)
+ {
+ std::string const& vars (env_vars(impl.vars_)["QUERY_STRING"]);
+ if (!vars.empty())
+ detail::extract_params(vars, get_vars(impl.vars_)
+ , boost::char_separator<char>
+ ("", "=&", boost::keep_empty_tokens)
+ , ec);
+ impl.get_parsed_ = true;
+ }
       return ec;
     }
 

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/response.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/response.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/response.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -154,6 +154,8 @@
     void clear_headers();
 
     void reset_headers();
+
+ string_type& charset() { return charset_; }
 
     bool headers_terminated() const;
 
@@ -192,6 +194,8 @@
   protected:
     // Vector of all the headers, each followed by a CRLF
     std::vector<string_type> headers_;
+
+ string_type charset_;
 
     // The buffer is a shared_ptr, so you can keep it cached elsewhere.
     boost::shared_ptr<common::streambuf> buffer_;
@@ -243,6 +247,11 @@
     operator<< (cgi::common::basic_response<CharT>& resp
                , cgi::common::basic_header<CharT> const& hdr);
 
+ template<typename CharT>
+ cgi::common::basic_response<CharT>&
+ operator<< (cgi::common::basic_response<CharT>& resp
+ , cgi::common::charset_header<CharT> const& hdr);
+
   /// You can stream a cgi::cookie into a response.
   /**
    * This is just a shorthand way of setting a header that will set a

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/tags.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/tags.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/common/tags.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -40,6 +40,7 @@
 
     // Connection types
     struct stdio {};
+ //struct stderr {};
     struct async_stdio {};
     struct tcp_socket {};
     // A shareable tcp_socket (ie. one that can be locked)

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/connections/stdio.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/connections/stdio.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/connections/stdio.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -69,7 +69,7 @@
       }
 
       if (std::feof(stdin))
- ec = boost::asio::error::eof;
+ ec = ::cgi::error::eof;
       else
       if (std::ferror(stdin))
         ec = ::cgi::error::bad_read;

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/cgi_service_impl_base.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/cgi_service_impl_base.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/cgi_service_impl_base.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -97,7 +97,7 @@
     {
     }
 
- typedef implementation_type impl_type;
+ //typedef implementation_type impl_type;
 
     /// Return if the request is still open
     /**
@@ -145,12 +145,13 @@
 
       std::string const& request_method = env_vars(impl.vars_)["REQUEST_METHOD"];
 
- if (request_method == "GET" && parse_opts & common::parse_get)
+ if ((request_method == "GET" || request_method == "HEAD")
+ && (parse_opts & common::parse_get))
       {
         parse_get_vars(impl, ec);
       }
       else
- if (request_method == "POST" && parse_opts & common::parse_post)
+ if (request_method == "POST" && (parse_opts & common::parse_post))
       {
         parse_post_vars(impl, ec);
       }
@@ -180,29 +181,8 @@
                           ? common::parse_all
                           : (common::parse_env | common::parse_cookie)
                  , ec);
- }/*
- detail::save_environment(env_vars(impl.vars_));
- 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_get_vars(impl, ec);
- else
- if (request_method == "POST" && parse_stdin)
- parse_post_vars(impl, ec);
-
- if (ec) return ec;
-
- parse_cookie_vars(impl, ec);
- impl.status() = common::loaded;
-
- //BOOST_ASSERT(impl.status() >= loaded);
-
- return ec;
     }
-*/
+
     role_type
     get_role(implementation_type& impl)
     {
@@ -233,7 +213,10 @@
     boost::system::error_code
     read_env_vars(RequestImpl& impl, boost::system::error_code& ec)
     {
- detail::save_environment(env_vars(impl.vars_));
+ // Only do this once.
+ if (!impl.env_parsed_)
+ detail::save_environment(env_vars(impl.vars_));
+ impl.env_parsed_ = true;
       return ec;
     }
 
@@ -254,20 +237,6 @@
                 , post_vars(impl.vars_)
                 , env_vars(impl.vars_)["CONTENT_TYPE"]
                 , callback_functor<self_type>(impl, this)
- //boost::bind(
- //&self_type::read_some
- //& typename ::cgi::common::request_base<
- // ::cgi::cgi_service_impl_base<
- // RequestImplType
- // > >::read_some<
- // typename ::cgi::cgi_service_impl_base<
- // RequestImplType
- // >::implementation_type
- // >
- //&cgi::common::base_type::read_some<typename self_type::implementation_type>
- //, this
- //, boost::ref(impl)
- //)
                 , impl.client_.bytes_left_
                 , impl.stdin_parsed_
                 )

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/extract_params.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/extract_params.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/extract_params.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -36,6 +36,7 @@
        return ec;// = boost::system::error_code(34, boost::system::errno_ecat);
 
      typedef typename boost::tokenizer<Separator> tokenizer;
+ typedef typename Map::value_type value_type;
 
      tokenizer toker(input, separator);
 
@@ -54,16 +55,16 @@
        {
 // Empty parameters (eg. `empty` in /path/to/script?empty&foo=bar) aren't
 // guaranteed by the CGI spec to be kept, but you might want to use them.
-// You just have to define `BOOST_CGI_KEEP_EMPTY_VARS` (**FIXME** currently
+// You just have to define `BOOST_CGI_KEEP_EMPTY_VARS` (**TODO** currently
 // on by default).
 // Note that you'll want to check that your server keeps empty query string
 // parameters.
 #if defined(BOOST_CGI_KEEP_EMPTY_VARS)
          if (name.empty())
- destination.insert(std::make_pair(common::name(current_token.c_str()), ""));
+ destination.insert(value_type(current_token.c_str(), ""));
          else
 #endif // BOOST_CGI_KEEP_EMPTY_VARS
- destination[name.c_str()] = current_token;
+ destination.insert(value_type(name.c_str(), current_token));
          current_token.clear();
          name.clear();
        }else
@@ -73,11 +74,11 @@
      }
      // Save the name if the last n/v pair has no value.
      if ( !name.empty() )
- destination[name.c_str()] = current_token;
+ destination.insert(value_type(name.c_str(), current_token));
 #if defined(BOOST_CGI_KEEP_EMPTY_VARS)
      else // Save the final 'toggle' - eg /path/to/script?foo=bar&toggle
      if ( !current_token.empty() )
- destination[current_token.c_str()] = "";
+ destination.insert(value_type(current_token.c_str(), ""));
 #endif
 
      return ec;

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/save_environment.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/save_environment.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/detail/save_environment.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -15,7 +15,7 @@
 #include "boost/cgi/common/map.hpp"
 
 // The process' environment
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+#if BOOST_WINDOWS
   // MSVC warns of 'inconsistent dll linkage' here...
   _CRTIMP extern char** _environ;
 #else
@@ -48,8 +48,8 @@
     
      BOOST_ASSERT(env && "Trying to save environment, but the passed in environment is empty / invalid.");
 
- std::string sa;
- std::string sb;
+ typename MapT::key_type sa;
+ typename MapT::mapped_type sb;
 
      for(; env && *env; ++env)
      {
@@ -65,13 +65,13 @@
          sb.assign((*env+i+1), j-i-1);
        else
          sb.clear();
- env_map[sa.c_str()] = sb;
+ env_map[sa] = sb;
 #else
        if ((*env)[i+1] != '\0')
        {
          sa.assign(*env, i);
          sb.assign((*env+i+1), j-i-1);
- env_map[sa.c_str()] = sb;
+ env_map[sa] = sb;
        }
 #endif
          }

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/impl/form_parser.ipp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/impl/form_parser.ipp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/impl/form_parser.ipp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -11,8 +11,8 @@
 
 #include "boost/cgi/error.hpp"
 #include "boost/cgi/basic_client.hpp"
+#include "boost/cgi/common/form_part.hpp"
 #include "boost/cgi/detail/url_decode.hpp"
-#include "boost/cgi/common/form_parser.hpp"
 #include "boost/cgi/common/source_enums.hpp"
 
 #include <iostream> // **FIXME**

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/impl/response.ipp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/impl/response.ipp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/impl/response.ipp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -59,7 +59,7 @@
 //}
 # define BOOST_CGI_ADD_DEFAULT_HEADER \
       if (headers_.empty()) \
- headers_.push_back("Content-type: "BOOST_CGI_DEFAULT_CONTENT_TYPE"\r\n")
+ headers_.push_back("Content-type: "BOOST_CGI_DEFAULT_CONTENT_TYPE" ; Charset: " + charset_ + "\r\n")
 #endif // defined(BOOST_CGI_NO_DEFAULT_CONTENT_TYPE)
 
 
@@ -72,6 +72,7 @@
     , ostream_(buffer_.get())
     , http_status_(sc)
     , headers_terminated_(false)
+ , charset_("ISO-8859-1")
   {
   }
 
@@ -85,6 +86,7 @@
       http::status_code sc)
     : ostream_(buf)
     , http_status_(sc)
+ , charset_("ISO-8859-1")
   {
   }
 
@@ -391,6 +393,8 @@
   void basic_response<T>::prepare_headers(ConstBufferSequence& headers)
   {
     BOOST_CGI_ADD_DEFAULT_HEADER;
+
+ headers_[0].insert(headers_[0].length()-2, "; charset: " + charset_);
 
     // Terminate the headers.
     if (!headers_terminated_)
@@ -452,6 +456,15 @@
     }
   }
 
+ template<typename CharT> BOOST_CGI_INLINE
+ cgi::common::basic_response<CharT>&
+ operator<< (cgi::common::basic_response<CharT>& resp
+ , cgi::common::charset_header<CharT> const& hdr)
+ {
+ resp.charset() = hdr.content;
+ return resp;
+ }
+
   /// You can stream a cgi::cookie into a response.
   /**
    * This is just a shorthand way of setting a header that will set a

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/utility/get.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/utility/get.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/utility/get.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -16,9 +16,10 @@
     */
     template<typename MapT>
     std::string
- get_value(MapT& data, common::name const& name, std::string const& default_value)
+ get_value(MapT& data, typename MapT::key_type const& key
+ , typename MapT::mapped_type const& default_value)
     {
- return has_key(data, name) ? data["name"] : default_value;
+ return has_key(data, key) ? data[key] : default_value;
     }
 
  } // namespace common

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/utility/has_key.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/utility/has_key.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/boost/cgi/utility/has_key.hpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -14,7 +14,7 @@
     * Examples:
     *
     * Take a map who's keys are case insensitive:
- *
+ *
     * std::map<common::name,std::string> icase_map;
     * icase_map["key1"] = "value1";
     * icase_map["key2"] = "value2";
@@ -40,16 +40,16 @@
     * with the same data `foo=bar`.
     */
     template<typename MapT>
- bool has_key(MapT& data, typename MapT::key_type const& name)
+ bool has_key(MapT& data, typename MapT::key_type const& key)
     {
- if (!data.empty())
- for(typename MapT::const_iterator iter = data.begin(), end = data.end();
- iter != end; ++iter)
- {
- if (iter->first == name)
- return true;
- }
- return false;
+ if (!data.empty())
+ for(typename MapT::const_iterator iter = data.begin(), end = data.end();
+ iter != end; ++iter)
+ {
+ if (iter->first == key)
+ return true;
+ }
+ return false;
     }
 
  } // namespace common

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/Jamfile.v2 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -1,6 +1,8 @@
 
 import modules ;
 
+#use-project /boost/ : $(boost-root) ;
+
 local DEFINES ;
 
 if [ MATCH "^(--build-cgi)" : [ modules.peek : ARGV ] ]
@@ -54,20 +56,20 @@
   : requirements
       <include>$(top)
       <include>$(boost-root)
- <library>/boost/thread/
- <library>/boost/system/
- <library>/boost/regex/
- <library>/boost/date_time/
+ <library>/boost//thread/
+ <library>/boost//system/
+ <library>/boost//regex/
+ <library>/boost//date_time/
       <define>_CRT_SECURE_NO_WARNINGS
       <define>_SCL_SECURE_NO_WARNINGS
       $(DEFINES)
   : usage-requirements
       <include>$(top)
       <include>$(boost-root)
- <library>/boost/thread/
- <library>/boost/system/
- <library>/boost/regex/
- <library>/boost/date_time/
+ <library>/boost//thread/
+ <library>/boost//system/
+ <library>/boost//regex/
+ <library>/boost//date_time/
       <define>_CRT_SECURE_NO_WARNINGS
       <define>_SCL_SECURE_NO_WARNINGS
       <os>unix:<linkflags>-pthread
@@ -77,13 +79,14 @@
   ;
 
 if [ MATCH "^(--build-cgi)" : [ modules.peek : ARGV ] ]
-{ # compile library
+{ # compile the library
   ECHO "Building CGI library" ;
 
   # make BB recognise .ipp files as .cpp (source) files.
   import type ;
   type.register IPP : ipp : CPP ;
 
+ # library_sources.cpp includes all compilable source files.
   SOURCES = $(top)/libs/cgi/src/library_sources.cpp ;
 
   lib boost_cgi

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.ncb
==============================================================================
Binary files. No diff available.

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.sln
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.sln (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.sln 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -5,6 +5,12 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "acgi_echo", "acgi_echo\acgi_echo.vcproj", "{83BF52DF-C606-4BB7-B06F-EDC28DE829B1}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "acgi_ctemplate_cookie_game", "acgi_ctemplate_cookie_game\acgi_ctemplate_cookie_game.vcproj", "{AC2E336C-7C32-468C-9847-470436CF668F}"
+EndProject
+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
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -19,6 +25,17 @@
                 {83BF52DF-C606-4BB7-B06F-EDC28DE829B1}.Debug|Win32.Build.0 = Debug|Win32
                 {83BF52DF-C606-4BB7-B06F-EDC28DE829B1}.Release|Win32.ActiveCfg = Release|Win32
                 {83BF52DF-C606-4BB7-B06F-EDC28DE829B1}.Release|Win32.Build.0 = Release|Win32
+ {AC2E336C-7C32-468C-9847-470436CF668F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AC2E336C-7C32-468C-9847-470436CF668F}.Debug|Win32.Build.0 = Debug|Win32
+ {AC2E336C-7C32-468C-9847-470436CF668F}.Release|Win32.ActiveCfg = Release|Win32
+ {AC2E336C-7C32-468C-9847-470436CF668F}.Release|Win32.Build.0 = Release|Win32
+ {CED278B4-18C9-41F5-9026-1DB8CD0AC5D4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {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
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/Boost.CGI.suo
==============================================================================
Binary files. No diff available.

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/acgi_cookie_game/acgi_cookie_game.vcproj
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/acgi_cookie_game/acgi_cookie_game.vcproj (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/acgi_cookie_game/acgi_cookie_game.vcproj 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -119,7 +119,7 @@
                                 Name="VCCLCompilerTool"
                                 Optimization="2"
                                 EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories="&quot;C:\Code\C++\Boost.CGI\current&quot;;&quot;C:\Code\C++\boost\svn\branches\release&quot;"
+ AdditionalIncludeDirectories=""
                                 PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_SCL_SECURE_NO_WARNINGS"
                                 RuntimeLibrary="2"
                                 EnableFunctionLevelLinking="true"

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/acgi_echo/acgi_echo.vcproj
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/acgi_echo/acgi_echo.vcproj (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/build/msvc/9.0/Boost.CGI/acgi_echo/acgi_echo.vcproj 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -42,7 +42,7 @@
                                 Name="VCCLCompilerTool"
                                 AdditionalOptions="/D &quot;_SCL_SECURE_NO_WARNINGS&quot;"
                                 Optimization="0"
- AdditionalIncludeDirectories="&quot;C:\Code\C++\Boost.CGI\current&quot;;&quot;C:\Code\C++\boost\svn\branches\release&quot;"
+ AdditionalIncludeDirectories=""
                                 PreprocessorDefinitions="_SCL_SECURE_NO_WARNINGS"
                                 MinimalRebuild="true"
                                 BasicRuntimeChecks="3"
@@ -64,7 +64,7 @@
                                 Name="VCLinkerTool"
                                 AdditionalOptions="libboost_system-vc90-mt-gd-1_38.lib"
                                 LinkIncremental="2"
- AdditionalLibraryDirectories="C:\Boost\lib"
+ AdditionalLibraryDirectories=""
                                 GenerateDebugInformation="true"
                                 SubSystem="1"
                                 TargetMachine="1"

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/doc/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/doc/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/doc/Jamfile.v2 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -3,11 +3,13 @@
 # subject to the Boost Software License, Version 1.0. (See accompanying
 # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
-#project boost.cgi.docs
-# ;
+project boost.cgi.docs
+ ;
 
+import boostbook : boostbook ;
 import doxygen ;
 import quickbook ;
+#import auto-index ;
 
 # compile the doxygen sources here
 doxygen autodoc
@@ -16,6 +18,12 @@
 # [ 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/acgi/*.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
@@ -26,24 +34,54 @@
     $(top)/boost/cgi/cgi/service.hpp
     $(top)/boost/cgi/cgi/request.hpp
     $(top)/boost/cgi/http/status_code.hpp
- #[ glob $(top)/boost/cgi/acgi/*.hpp ]
- #[ glob $(top)/boost/cgi/cgi/*.hpp ]
- [ glob $(top)/boost/cgi/common/*.hpp ]
-
- [ glob ../../../boost/cgi/connections/*.hpp ]
   :
- <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
- <doxygen:param>EXTRACT_ALL=YES
+ <doxygen:param>TAB_SIZE=2
+ # <doxygen:param>EXTRACT_ALL=YES
+ <doxygen:param>HIDE_UNDOC_MEMBERS=YES
+ # 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
- <doxygen:param>GENERATE_TREEVIEW=ALL
- <doxygen:param>TYPEDEF_HIDES_STRUCT=YES
-# <doxygen:param>INCLUDE_PATH=$(BOOST_ROOT)
+ # 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
+ # 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
+ # 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
+ # List of the files that are included by a file in the documentation of that
+ # file.
+ <doxygen:param>SHOW_INCLUDE_FILES=NO
+ # Prepend the brief description of a member or function before the detailed
+ # description
+ <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
+ # 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
+ # 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
   ;
 
 xml cgi_xml : src/cgi.qbk ;
@@ -54,24 +92,65 @@
     autodoc
     #cgi_dox
   :
- #<xsl:param>project.root=../../../..
- #<xsl:param>boost.libraries=/usr/local/src/boost/trunk/libs/libraries.htm
- #<xsl:param>boost.images=http://beta.boost.org/images
- # the depth (of sub-pages) the TOC shows
- #<xsl:param>toc.max.depth=1
- # Path to the stylesheet
- #<xsl:param>html.stylesheet=../../../../../../boost/trunk/doc/html/boostbook.css
-
- #
- #<xsl:param>toc.section.depth=2
-
+ # This one turns on indexing:
+ #<auto-index>on
+ # Choose indexing method for pdf's:
+ #<format>pdf:<auto-index-internal>off
+ # Choose indexing method for html:
+ #<format>html:<auto-index-internal>on
+ # Set the name of the script file to use:
+ #<auto-index-script>index.idx
+
+ # Some general style settings:
+ <xsl:param>table.footnote.number.format=1
+ <xsl:param>footnote.number.format=1
+
+ # HTML options first:
+ # 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
+ # 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
     # How far down we go with TOC's
- #<xsl:param>generate.section.toc.level=10
- # how many sections are on the first page
- #<xsl:param>chunk.first.sections=1
+ <xsl:param>generate.section.toc.level=10
+ #<xsl:param>root.filename="svg_plot"
+
+ # <xsl:param>project.root=http://beta.boost.org/development
+ # <xsl:param>annotation.support=1
+ # <xsl:param>quickbook.source.style.show="'true'"
+
+ # PDF Options:
+ # TOC Generation
+ <xsl:param>fop1.extensions=0
+ <format>pdf:<xsl:param>xep.extensions=1
+ <format>pdf:<xsl:param>fop.extensions=0
+
+ # No indent on body text:
+ <format>pdf:<xsl:param>body.start.indent=0pt
+ # Margin size:
+ <format>pdf:<xsl:param>page.margin.inner=0.5in
+ # Margin size:
+ <format>pdf:<xsl:param>page.margin.outer=0.5in
+ # Paper type = A4
+ <format>pdf:<xsl:param>paper.type=A4
+ # Yes, we want graphics for admonishments:
+ <xsl:param>admon.graphics=1
+ # Set this one for PDF generation *only*:
+ # default pnd graphics are awful in PDF form,
+ # better use SVG's instead:
+ <format>pdf:<xsl:param>admon.graphics.extension=".svg"
+ <format>pdf:<xsl:param>use.role.for.mediaobject=1
+ <format>pdf:<xsl:param>preferred.mediaobject.role=print
+ <format>pdf:<xsl:param>img.src.path=$(images_location)/
+ <format>pdf:<xsl:param>admon.graphics.path=$(images_location)/images/
+ <format>pdf:<xsl:param>draft.mode="no"
 
- # To chunk (together) or not to chunk (divide)
- #<xsl:param>chunk.section.depth=2 # chunk
+ <dependency>autodoc
          ;
 
 install html
@@ -79,3 +158,6 @@
           /boost//doc/html/boostbook.css
 # /bin/doc/$(toolset)/debug/cgi_xml.xml
         ;
+
+install pdf-install : standalone : <location>. <install-type>PDF ;
+

Added: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/doc/src/design.qbk
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/doc/src/design.qbk 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -0,0 +1,12 @@
+
+[section:design Design Decisions]
+
+Below is some detail about the various design decisions made for this library. If you think anything is missing or just plain wrong, [link contact contact us].
+
+[section Environment Variables]
+
+
+
+[endsect]
+
+[endsect]
\ No newline at end of file

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/amortization/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/amortization/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/amortization/main.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -216,27 +216,14 @@
     resp<< req[form]["YearlyIntRate"];
   
     return_(resp, req, 0);
- }catch(boost::system::system_error* err){
- std::cout<< "Content-type: text/plain\r\n\r\n"
- << "Error (" << err->code() << "): " << err->what();
- return 0;
   }catch(boost::system::system_error& err){
- std::cout<< "Content-type: text/plain\r\n\r\n"
- << "Error (" << err.code() << "): " << err.what();
- return 0;
- }catch(std::exception* e){
- std::cout<< "Content-type: text/html\r\n\r\n"
- << "Exception caught: " << e->what();
- return 0;
- }catch(std::exception& e){
- std::cout<< "Content-type: text/html\r\n\r\n"
- << "Exception caught: " << e.what();
- return 0;
+ std::cerr<< "System Error: [" << err.id() << "] - " << err.message() << std::endl;
+ }catch(std::exception const& e){
+ std::cerr<< "Exception: [" << typeid(e).name() << "] - " << e.what() << std::endl;
   }catch(...){
- std::cout<< "Content-type: text/html\r\n\r\n"
- << "Unknown error!";
- return 0;
+ std::cerr<< "boom<blink>!</blink>";
   }
+ return 0;
 }
 //]
 

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/cookie_game2/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/cookie_game2/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/cookie_game2/Jamfile.v2 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -8,21 +8,13 @@
 
 import os ;
 
-if [ os.name ] = NT
-{
- lib ctemplate : : <file>c:/cc/src/ctemplate/ctemplate-0.9/Release/libctemplate.lib ;
-}
-else
-{
- lib ctemplate ;
-}
-
+#lib ctemplate : : <name>ctemplate <search>C:/Packages/ctemplate/lib ;
 
 exe acgi_cookie_game2
   :
     main.cpp
   :
- <library>ctemplate
+ <library>/user-config/ctemplate
   :
     <linkflags>-lctemplate
   ;

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/cookie_game2/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/cookie_game2/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/cookie_game2/main.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -11,15 +11,20 @@
 // Cookie Test With cTemplate
 // --------------------------
 //
-// This file uses Google cTemplate to show the benefits of using an HTML
+// This file uses Google cTemplate [1] to show the benefits of using an HTML
 // template engine. Using cTemplate to separate how you show the response and
 // how you figure out what to respond with, is keeping to the MVC paradigm.
 // Read up on that if you're not familiar; if you already are, you can
 // probably stop scowling at the last cookie_game example now.
-
-//#include <boost/cgi/acgi.hpp>
+//
+// [1] - http://code.google.com/p/google-ctemplate/
+//
+#include <boost/cgi/acgi.hpp>
 #include <boost/cgi/utility.hpp>
 #include <google/template.h>
+#include <boost/throw_exception.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/filesystem.hpp>
 //]
 
 /**
@@ -31,6 +36,7 @@
 //[main
 
 using namespace boost::acgi;
+namespace fs = boost::filesystem;
 
 // The types we use. Only here because this is an example.
 
@@ -66,6 +72,8 @@
 // only here to keep the cTemplate code out of the core of this example...
 stencil_type* get_stencil(std::string const& filename)
 {
+ if (!fs::exists(filename))
+ throw std::runtime_error(std::string("Template file not found: '") + fs::path(filename).string() + "'");
   return google::Template::GetTemplate(filename, google::STRIP_WHITESPACE);
 }
 
@@ -98,9 +106,10 @@
 
     response_type resp;
 
+ // Check if we are resetting the user.
     if (has_key(req[form], "reset") && req[form]["reset"] == "true")
     {
- resp<< cookie("name")
+ resp<< cookie("name") // delete the 'name' cookie.
           << redirect(req, req.script_name()); // redirect them.
       resp.send(req.client());
       return 0;
@@ -128,7 +137,10 @@
 
     print_formatted_data(req[cookies], dict);
 
- dict.SetValue("SCRIPT_NAME", req.script_name());
+ dict.SetValue("SCRIPT_NAME", req.script_name());
+ // get_value is defined in boost/cgi/util/
+ // Looks up the key in the map, returns a default value if the key
+ // isn't found.
     dict.SetValue("COOKIE_NAME", get_value(req[form], "name", ""));
     dict.SetValue("COOKIE_VALUE", req[form]["value"]);
 
@@ -145,13 +157,13 @@
 
     // Send the response to the requestor and return control.
     return_(resp, req, http::ok);
-
- }catch(std::exception* e){
- std::cout<< "Exception: [" << typeid(e).name() << "] - " << e->what() << std::endl;
+
+ }catch(boost::system::system_error& err){
+ std::cerr<< "System Error: [" << err.code() << "] - " << err.what() << std::endl;
   }catch(std::exception const& e){
- std::cout<< "Exception: [" << typeid(e).name() << "] - " << e.what() << std::endl;
+ std::cerr<< "Exception: [" << typeid(e).name() << "] - " << e.what() << std::endl;
   }catch(...){
- std::cout<< "boom<blink>.</blink>";
+ std::cerr<< "boom<blink>!</blink>";
   }
 }
 //]

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/echo/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/echo/main.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -83,11 +83,13 @@
 
 int main()
 {
+ response resp;
   try{
     //std::ofstream of("c:/cc/log/cgi.error");
     //if (!of)
     // throw std::runtime_error("Couldn't open file for writing");
     //std::cerr.rdbuf() = of.rdbuf();
+
     service s;
     request req(s);
 
@@ -97,14 +99,15 @@
       
       // This spits out a form with a file upload facility (these aren't
       // stored, just parsed. Before parsing the POST'd form data, first
- // check that the content-length isn't too long.
+ // check that the content-length isn't too long. We need to load
+ // up the request environment to check the content length.
       req.load(parse_env);
-
- response resp;
 
       if (req.content_length() > 1000L)
       {
- resp<< "You're only allowed to upload 1k of data";
+ resp<< content_type("text/html");
+ resp<< "You're only allowed to upload 1k of data.\n"
+ << "Content-length: " << req.content_length();
         // Exit the application here.
         return_(resp, req, 0);
       }
@@ -122,7 +125,6 @@
         resp.send(req.client());
       }
 
- response resp;
       resp<< content_type("text/html") <<
              "<html>"
              "<head>"
@@ -132,15 +134,20 @@
                "</style>"
              "<head>"
              "<body>"
+ "Environment stuffs:<br />"
+ " > content_type: " << req.env["Content_type"] << "<br />"
+ " > script uri: " << req.env["script_uri"] << "<br />"
+ " > count('girl'): " << req.get.count("girl") << "<br />"
+ "Environment stuffs:<br />"
                "Request ID = " << req.id() << "<br />"
                "Process ID = " << process_id() << "<br />"
                "<form method=POST enctype='application/x-www-form-urlencoded'>"
                  "<input type=text name=name value='"
- << (has_key(req[post],"name") ? req[post]["name"] : "")
+ << (has_key(req.post,"name") ? req.post["name"] : "")
           << "' />"
                  "<br />"
                  "<input type=text name=hello value='"
- << (has_key(req[post],"hello") ? req[post]["hello"] : "")
+ << (has_key(req.post,"hello") ? req.post["hello"] : "")
           << "' />"
                  "<br />"
                  "<input type=file name=user_file />"
@@ -149,10 +156,10 @@
                  "<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[cookies], "Cookie 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");
 
       if (req["request_method"] == "GET")
       {
@@ -188,15 +195,30 @@
     // The request object will be destroyed before the next exception handlers
     // are reached.
 
- }catch(std::exception* e){
- std::cout
- << content_type("text/plain").content
- << "Exception: " << e->what();
- return 3;
+ }catch(boost::system::system_error& ec)
+ { // This is the type of error this library throws.
+ std::cout
+ << content_type("text/plain").content
+ << std::endl << std::endl
+ << "Error " << ec.code() << ": "
+ << ec.what()
+ << http::internal_server_error
+ << std::endl
+ << resp.str(); // note the status_code
+ return 2;
+ }catch(std::exception& e){
+ std::cout
+ << content_type("text/plain").content
+ << std::endl << std::endl
+ << "Exception: " << e.what()<< std::endl
+ << resp.str();
+ return 3;
   }catch(...){
- std::cout<< content_type("text/plain").content
- << "Unknown error.";
- return 4;
+ std::cout<< content_type("text/plain").content
+ << std::endl << std::endl
+ << "Unknown error."<< std::endl
+ << resp.str();
+ return 4;
   }
 }
 //]

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/CheckCookie.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/CheckCookie.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/CheckCookie.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -12,10 +12,10 @@
 
   response resp;
 
- if (!req[cookie_data]["uuid"].empty())
+ if (!req[cookies]["uuid"].empty())
   { // The cookie has been set correctly!
     boost::system::error_code ec;
- std::string fwd (req[form_data]["fwd"]);
+ std::string fwd (req[form]["fwd"]);
     resp<< location(fwd);
   // resp<< location(req.form("fwd"));
   }else

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/Login.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/Login.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/Login.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -13,8 +13,8 @@
            "You provided the following data:"
            "<p>"
            "<h3>Form data:</h3>";
- for (boost::acgi::map::iterator i = req[form_data].begin();
- i != req[form_data].end();
+ for (boost::acgi::map::iterator i = req[form].begin();
+ i != req[form].end();
        ++i)
   {
     resp<< "<b>" << i->first << "</b> = <i>" << i->second << "</i>";
@@ -87,7 +87,7 @@
           "the underscore character."
           "</span>"
           "<input type='text' name='name' value='"
- << req[post_data]["name"] <<"' />"
+ << req[post]["name"] <<"' />"
           "<input type='button' name='cmd' value='login' />"
          "</form>"
        "</center>";
@@ -135,18 +135,18 @@
 
   // If there's already a session id set, warn them and then redirect
   // them to where they would be going anyway.
- if (!req[cookie_data]["uuid"].empty()) {
+ if (!req[cookies]["uuid"].empty()) {
     return show_already_logged_in_page(req, resp);
   }
 
   // If they haven't asked explicitly to log in, show the default page.
- string cmd (req[post_data]["cmd"]);
+ string cmd (req[post]["cmd"]);
   if (cmd.empty() || cmd != "login") {
     return show_default_page(req, resp);
   }
 
   // If they're name is invalid, inform them.
- string name (req[post_data]["name"]);
+ string name (req[post]["name"]);
   if (!verify_name(name)) {
     return show_name_error_page(req, resp);
   }
@@ -155,7 +155,7 @@
   // Here we give them a 'universally unique id' and forward them to a
   // cookie checking page.
   resp<< cookie("uuid", make_uuid())
- << location("CheckCookie?fwd=" + req[post_data]["fwd"]);
+ << location("CheckCookie?fwd=" + req[post]["fwd"]);
   resp.send(req.client());
 
   return req.close(http::ok);

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/Logout.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/Logout.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/acgi/login/Logout.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -14,8 +14,7 @@
 
   resp<< cookie("uuid");
   boost::system::error_code ec;
- std::string fwd (req[form_data]["fwd"]);
- resp<< location(fwd);
+ resp<< location(req[form]["fwd"]);
 
   resp.send(req.client());
   return req.close(http::ok);

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/amortization/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/amortization/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/amortization/main.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -38,11 +38,10 @@
 template<typename Request>
 void fill_amortization_dictionary(google::TemplateDictionary& dict, Request& req)
 {
- std::string tmp( req.POST("LoanAmt") );
- dict.SetValue("LoanAmt", tmp.empty() ? "$250,000" : tmp);
-
- tmp = req.POST("YearlyIntRate");
- dict.SetValue("YearlyIntRate", tmp.empty() ? "6.000" : tmp);
+ dict.SetValue("LoanAmt", has_key(req[post], "LoanAmt")
+ ? "$250,000" : req[post]["LoanAmt"]);
+ dict.SetValue("YearlyIntRate", has_key(req[post], "YearlyIntRate")
+ ? "6.000" : req[post]["YearlyIntRate"]);
 
   boost::array<std::string, 8> year_opts
     = {{ "5", "7", "10", "20", "30", "40", "50" }};
@@ -52,7 +51,7 @@
     dict.SetValueAndShowSection("TermYrs", year, "SELECT_TERM_YEARS");
   }
 
- if (req.POST("Amortize").empty())
+ if (req[post]["Amortize"]).empty())
     dict.ShowSection("NotAmortize");
   else
   {
@@ -107,7 +106,7 @@
   std::string h("Content-type: text/html\r\n\r\n");
   write(req.client(), buffer(h));
 
- std::string arg(req.GET("arg"));
+ std::string arg(req[get]["arg"]));
   if (arg.empty())
     arg = "2"; // set this as default (for no particular reason).
 
@@ -158,10 +157,10 @@
     // creating/destructing request objects). You must call close() first though!
     a.accept(req);
 
- req.load(true);
+ req.load(parse_all);
 
     resp<< content_type("text/html")
- << "map size := " << req.POST().size() << "<p>";
+ << "map size := " << req[post].size() << "<p>";
   
     ret = write_amortization_template(req, resp);
 
@@ -194,12 +193,17 @@
     
     return 0;
 
- }catch(boost::system::error_code& err){
- std::cerr<< "CGI error(" << err.value() << "): " << err.message() << std::endl;
   }catch(boost::system::system_error& err){
- std::cerr<< "System error(" << err.code() << "): " << err.what() << std::endl;
+ std::cout<< "Content-type: text/plain\r\n\r\n"
+ << "Error (" << err.code() << "): " << err.what();
+ return 0;
+ }catch(std::exception& e){
+ std::cout<< "Content-type: text/html\r\n\r\n"
+ << "Exception caught: " << e.what();
+ return 0;
   }catch(...){
- std::cerr<< "ERROR!! BOOM!" << std::endl;
+ std::cout<< "Content-type: text/html\r\n\r\n"
+ << "Unknown error!";
   }
 }
 //]

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/hello_world/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/hello_world/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/hello_world/main.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -75,17 +75,12 @@
       if (!a.is_open()) break; // Quit completely if the acceptor bails out.
     }
   */
- } // This library throws only this type of exception (see Boost.System documentation).
- catch(boost::system::system_error const& err)
- {
- std::cerr<< "System error " << err.code() << ": "
- << err.what() << std::endl;
- return 1;
- }
- catch(...)
- {
- std::cerr<< "Unknown error!" << std::endl;
- return 2;
+ }catch(boost::system::system_error& err){
+ std::cerr<< "System Error: [" << err.id() << "] - " << err.message() << std::endl;
+ }catch(std::exception const& e){
+ std::cerr<< "Exception: [" << typeid(e).name() << "] - " << e.what() << std::endl;
+ }catch(...){
+ std::cerr<< "boom<blink>!</blink>";
   }
   return ret;
 }

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server1/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server1/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server1/main.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -53,9 +53,9 @@
       << "Hello there, universe!<p />";
 
   // Use the function defined above to show some of the request data.
- format_map(resp, req[env_data], "Environment Variables");
- format_map(resp, req[get_data], "GET Variables");
- format_map(resp, req[cookie_data], "Cookie Variables");
+ format_map(resp, req[env], "Environment Variables");
+ format_map(resp, req[get], "GET Variables");
+ format_map(resp, req[cookies], "Cookie Variables");
    // Response headers can be added at any time before send/flushing it:
   resp<< "<h3>Response Length</h3>" << resp.content_length()
       // response::content_length() returns the length of the *body*

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server2/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server2/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server2/main.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -65,9 +65,9 @@
       << "Hello there, universe!<p />";
 
   // Use the function defined above to show some of the request data.
- format_map(resp, req[env_data], "Environment Variables");
- format_map(resp, req[get_data], "GET Variables");
- format_map(resp, req[cookie_data], "Cookie Variables");
+ format_map(resp, req[env], "Environment Variables");
+ format_map(resp, req[get], "GET Variables");
+ format_map(resp, req[cookies], "Cookie Variables");
 
   //log_<< "Handled request, handling another." << std::endl;
 

Modified: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server3/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server3/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/example/fcgi/server3/main.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -107,7 +107,7 @@
       }
   
       // Load in the request data so we can access it easily.
- new_request->load(ec, true); // The 'true' means read and parse POST data.
+ new_request->load(ec, parse_post | parse_cookies); // Read and parse POST data and cookies.
 
       ret = handler_(*new_request, ec);
 

Added: sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/test/run/has_key.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/branches/pickmeup/libs/cgi/test/run/has_key.cpp 2009-08-24 14:07:11 EDT (Mon, 24 Aug 2009)
@@ -0,0 +1,45 @@
+
+#include <map>
+#include "boost/cgi/utility/has_key.hpp"
+
+#define BOOST_TEST_MODULE has_key_test_suite
+#include <boost/test/unit_test.hpp>
+
+using boost::cgi::has_key;
+
+BOOST_AUTO_TEST_CASE( std_map )
+{
+ typedef std::map<std::string, std::string> map_type;
+
+ map_type m;
+ m["1"] = "one";
+ m["two"] = "2";
+
+ BOOST_CHECK_EQUAL(has_key(m, "1"), true);
+ BOOST_CHECK_EQUAL(m["1"], "one");
+ BOOST_CHECK_EQUAL(has_key(m, "two"), true);
+ BOOST_CHECK_EQUAL(m["two"], "2");
+
+ BOOST_CHECK_EQUAL(has_key(m, "3"), false);
+}
+
+#include "boost/cgi/common/map.hpp"
+
+BOOST_AUTO_TEST_CASE( map_test )
+{
+ typedef cgi::common::map map_type;
+ map_type m;
+
+ /// First check that upper case compares with lower case.
+ m["foo"] = "bar";
+ BOOST_CHECK_EQUAL( has_key(m,"foo"), true );
+ BOOST_CHECK_EQUAL( has_key(m,"FOO"), true );
+
+ /// Then check that lower case compares with upper case.
+ m["FATFOO"] = "minibar";
+ BOOST_CHECK_EQUAL( has_key(m,"FATFOO"), true );
+ BOOST_CHECK_EQUAL( has_key(m,"fatfoo"), true );
+
+ // Sanity check.
+ BOOST_CHECK_EQUAL( has_key(m,"nonfoo"), false );
+}


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