Boost logo

Boost-Commit :

From: drrngrvy_at_[hidden]
Date: 2007-07-12 14:09:08


Author: drrngrvy
Date: 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
New Revision: 7418
URL: http://svn.boost.org/trac/boost/changeset/7418

Log:
Restructuring basic_request and subclasses to model *ReadStream and *WriteStream asio concepts; removing some old files.

Added:
   sandbox/SOC/2007/cgi/boost/cgi/connections/
   sandbox/SOC/2007/cgi/boost/cgi/connections/async_stdio_connection.hpp
   sandbox/SOC/2007/cgi/boost/cgi/connections/stdio_connection.hpp
   sandbox/SOC/2007/cgi/boost/cgi/connections/stdio_connection_impl.hpp
   sandbox/SOC/2007/cgi/boost/cgi/connections/tcp_connection.hpp
   sandbox/SOC/2007/cgi/boost/cgi/detail/extract_params.hpp
   sandbox/SOC/2007/cgi/boost/cgi/detail/url_decode.hpp
   sandbox/SOC/2007/cgi/boost/cgi/request_impl/async_cgi_request_impl.hpp
   sandbox/SOC/2007/cgi/boost/cgi/service_impl/
   sandbox/SOC/2007/cgi/boost/cgi/service_impl/async_cgi_service_impl.hpp
   sandbox/SOC/2007/cgi/boost/cgi/service_impl/cgi_service_impl.hpp
Properties modified:
   sandbox/SOC/2007/cgi/libs/cgi/doc/ (props changed)
Text files modified:
   sandbox/SOC/2007/cgi/boost/cgi/basic_connection.hpp | 130 +-------------------
   sandbox/SOC/2007/cgi/boost/cgi/basic_request.hpp | 236 ++++++++++++++++++++----------------
   sandbox/SOC/2007/cgi/boost/cgi/basic_request_acceptor.hpp | 20 +-
   sandbox/SOC/2007/cgi/boost/cgi/detail/request_traits.hpp | 21 +-
   sandbox/SOC/2007/cgi/boost/cgi/logger.hpp | 5
   sandbox/SOC/2007/cgi/boost/cgi/ostream.hpp | 2
   sandbox/SOC/2007/cgi/boost/cgi/request_acceptor_service.hpp | 26 +++
   sandbox/SOC/2007/cgi/boost/cgi/request_base.hpp | 7 +
   sandbox/SOC/2007/cgi/boost/cgi/request_impl/cgi_request_impl.hpp | 253 +++++++++++++++------------------------
   sandbox/SOC/2007/cgi/boost/cgi/request_impl/fcgi_request_impl.hpp | 91 ++++++++------
   sandbox/SOC/2007/cgi/boost/cgi/request_service.hpp | 73 ++++++-----
   11 files changed, 383 insertions(+), 481 deletions(-)

Modified: sandbox/SOC/2007/cgi/boost/cgi/basic_connection.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/basic_connection.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/basic_connection.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -23,140 +23,24 @@
   {
   public:
     typedef connection_impl<ProtocolService::protocol_type> impl_type;
+ typedef boost::shared_ptr<conection_base> pointer;
 
- private:
- impl_type* impl_;
- };
-
- template<typename ProtocolService>
- class basic_connection<tags::stdio>
- : public connection_base
- {
- public:
- typedef ProtocolService protocol_service_type;
-
- basic_connection(protocol_service_type& ps)
- : in_(std::cin)
- , out_(std::cout)
- {
- }
-
- template<typename MutableBufferSequence>
- std::size_t read(MutableBufferSequence buf, boost::system::error_code& ec)
- {
- if( buf.data() != in_.rdbuf() )
- return in_.read(buf.data(), buf.size());
- return buf.size();
- }
-
- template<typename MutableBufferSequence, typename Handler>
- void async_read(MutableBufferSequence buf, Handler handler)
- {
- handler(boost::system_error(), read(buf));
- }
-
- template<typename ConstBufferSequence>
- std::size_t write(ConstBufferSequence& buf)
- {
- return out_.write(buf.data(), buf.size());
- }
-
- template<typename ConstBufferSequence, typename Handler>
- void async_write(ConstBufferSequence& buf, Handler handler)
- {
- out_.write(buf.data(), buf.size());
- protocol_service_.post(handler);
- }
-
- private:
- protocol_service_type& protocol_service_;
- std::istream& in_;
- std::ostream& out_;
- };
-
- template<typename ProtocolService>
- class basic_connection<tags::stdio_async>
- : public connection_base
- {
- public:
- typedef ProtocolService protocol_service_type;
-
- basic_connection(protocol_service_type& ps)
- : protocol_service_(ps)
- , in_(std::cin)
- , out_(std::cout)
- {
- }
-
- template<typename MutableBufferSequence>
- std::size_t read(MutableBufferSequence buf)
- {
- if( buf.data() != in_.rdbuf() )
- return in_.read(buf.data(), buf.size());
- return buf.size();
- }
-
- template<typename MutableBufferSequence, typename Handler>
- void async_read(MutableBufferSequence buf, Handler handler)
- {
- std::size_t bytes_read;
- if( buf.data() != in_.rdbuf() )
- bytes_read = in_.read(buf.data(), buf.size());
- else
- bytes_read = buf.size();
-
- protocol_service_.post(boost::bind(&Handler
- , handler
- , boost::system::system_error()
- , bytes_read ));
- }
-
- template<typename ConstBufferSequence>
- std::size_t write(ConstBufferSequence& buf)
- {
- return out_.write(buf.data(), buf.size());
- }
-
- template<typename ConstBufferSequence, typename Handler>
- void async_write(ConstBufferSequence& buf, Handler handler)
- {
- out_.write(buf.data(), buf.size());
- protocol_service_.post(handler);
- }
-
- private:
- protocol_service_type& protocol_service_;
- std::istream& in_;
- std::ostream& out_;
- };
-
-
-
- template<typename ProtocolService>
- class basic_connection<ProtocolService, tags::tcp_socket>
- : public connection_base
- {
- public:
- typedef ProtocolService protocol_service_type;
-
- basic_connection(protocol_service_type& ps)
- : protocol_service_(ps)
- , sock_(ps.io_service())
+ explicit basic_connection(protocol_service_type& ps)
+ : impl_(ps)
     {
     }
 
- template<typename ConstBufferSequence, typename Handler>
- void async_write(ConstBufferSequence& buf, Handler handler)
+ static pointer create()
     {
+ return new basic_connection<protocol_service_type
+ , connection_type>(impl_.protocol_service());
     }
 
   private:
- protocol_service_type protocol_service_;
- boost::asio::ip::tcp::socket sock_;
+ impl_type impl_;
   };
 
 
- typedef basic_connection<tags::stdio> stdio_connection;
   typedef basic_connection<tags::tcp> tcp_connection;
   //typedef basic_connection<tags::pipe> pipe_connection; // not implemented
 

Modified: sandbox/SOC/2007/cgi/boost/cgi/basic_request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/basic_request.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/basic_request.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -12,6 +12,8 @@
 #include <iostream>
 #include <boost/noncopyable.hpp>
 
+#include "detail/request_traits.hpp"
+
 namespace cgi {
 
   enum status_type
@@ -34,65 +36,78 @@
    * 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)
+ *
+ * Note: From 10/07/07 this class is going to require a protocol_service be
+ * passed to it. This is good for FastCGI/SCGI and asynchronous CGI. A full
+ * specialisation of this class for sync CGI can be provided... The reasoning
+ * for this is that the added complexity for allowing a non-async CGI request
+ * to use the acceptor and this class doesn't seem worth it: it makes the
+ * whole library much simpler to do it this way.
    */
   template<typename Protocol
- , enum RequestRole = role_type::responder
+ , typename Service = request_traits<Protocol>::service_type
+ , enum Role = role_type::responder
           , typename ProtocolService = basic_protocol_service<Protocol>
                 , typename Allocator = std::allocator<char> >
   class basic_request
     : public request_base
+ //, public boost::asio::basic_io_object<Service>
     , private boost::noncopyable
   {
   public:
- typedef basic_request<Protocol, RequestRole
+ typedef basic_request<Protocol, Service, Role
                          , ProtocolService, Allocator > type;
     typedef Protocol protocol_type;
- typedef RequestRole role_type;
+ typedef Role role_type;
     typedef ProtocolService protocol_service_type;
- //typedef meta_data<protocol_type> data_type;
     typedef boost::shared_ptr<type> pointer;
 
- typedef request_traits<Protocol> traits;
- typedef typename traits::impl_type impl_type;
- typedef typename traits::service_type service_type;
+ typedef Service service_type;
+ typedef Service::impl_type impl_type;
     typedef boost::shared_ptr<connection_base> connection_ptr;
 
 
     explicit basic_request(protocol_service_type& s, bool load_now = false)
- : impl_(s)
+ :// boost::asio::basic_io_object<Service>(s.io_service())
+ next_layer_(s)
+ , service_(boost::asio::use_service<Service>(next_layer_.io_service()))
+ , impl_(service_.null())
       , status_num_(0)
- //, strand_(s.io_service())
     {
- if( load_now ) load();
+ service_.construct(impl_);
+ if( load_now ) service_.load(impl_);
     }
 
- /// Alternate constructor for CGI requests, which don't require a service
- explicit basic_request(bool load_now = false)
- : impl_()
- , status_num_(0)
+ ~basic_request()
     {
- if( load_now ) load();
+ service_.destroy(impl_);
     }
 
- ~basic_request()
+ boost::asio::io_service& io_service()
     {
- end(status_num_);
+ return next_layer_.io_service();
     }
 
     /// Synchronously read/parse the request meta-data
     /**
      * Note: 'loading' including reading/parsing STDIN if parse_stdin == true
      */
- bool load(bool parse_stdin = false)
+ // Throwing semantics
+ void load(bool parse_stdin = false)
     {
- if( !service_.load(impl_, parse_stdin) )
- {
- status_ = status_type::aborted;
- return false;
- }
- return true;
+ boost::system::error_code ec;
+ service_.load(impl_, parse_stdin);
+ boost::throw_error(ec);
     }
 
+ // Error-code semantics
+ boost::system::error_code& load(boost::system::error_code& ec
+ , bool parse_stdin = false)
+ {
+ return service_.load(impl_, parse_stdin, ec);
+ }
+
+
     /// Asynchronously read/parse the request meta-data
     /**
      * Note: 'loading' including reading/parsing STDIN if parse_stdin == true
@@ -103,43 +118,6 @@
       service_.async_load(impl_, parse_stdin, handler);
     }
 
- /// Read num_bytes into a default buffer (post-data buffer)
- std::size_t read(std::size_t num_bytes)
- {
- std::size_t bytes_read = impl_.read(connection_, buffer());
- // buff.commit(bytes_read)
- return bytes_read;
- }
-
- /// Read data synchronously into the provided buffer
- /**
- * @return the number of bytes read
- */
- template<typename MutableBufferSequence>
- std::size_t read(MutableBufferSequence& buf)
- {
- return impl_.read(connection_, buf);
- }
-
- /// Read data asynchronously into the provided buffer
- template<typename MutableBufferSequence, typename Handler>
- void async_read(MutableBufferSequence& buf, Handler handler)
- {
- impl_.async_read(connection_, buf, handler);
- }
-
- template<typename ConstBufferSequence>
- std::size_t write(ConstBufferSequence& buf)
- {
- return impl_.async_write(connection_, buf);
- }
-
- template<typename ConstBufferSequence, typename Handler>
- void async_write(ConstBufferSequence& buf, Handler handler)
- {
- impl_.async_write(connection_, buf, handler);
- }
-
     /// Notify the server the request has finished being handled
     /**
      * In certain situations (such as a Proactor client using the async read
@@ -155,10 +133,10 @@
     {
       BOOST_ASSERT( request_status_ != status_type::ended );
 
- request_status_ = status_type::ended;
+ service_.set_status(request_status_ = status_type::ended;
       http_status_ = http_status;
       program_status_ = program_status;
- service_.end(impl_);
+ service_.end(impl_, http_status);
       //io_service_.dispatch(set_status(status_type::ended));
       //impl_.end_request(this, status_code);
     }
@@ -168,6 +146,46 @@
 
     }
 
+ /// Reject the request with a standard '500 Internal Server Error' error
+ void reject()
+ {
+ service_.set_status(impl_, status_type::aborted);
+ service_.end(impl_, http::status_code::internal_server_error);
+ }
+
+ /// Read some data from the request
+ template<typename MutableBufferSequence>
+ std::size_t read_some(const MutableBufferSequence& buf)
+ {
+ error_code ec;
+ std::size_t s = service.read_some(buf, ec);
+ boost::throw_error(ec);
+ return s;
+ }
+
+ template<typename MutableBufferSequence>
+ std::size_t read_some(const MutableBufferSequence& buf
+ , boost::system::error_code& ec)
+ {
+ return service.read_some(buf, ec);
+ }
+
+ template<typename ConstBufferSequence>
+ std::size_t write_some(const ConstBufferSequence& buf)
+ {
+ error_code ec;
+ std::size_t s = service.write_some(buf, ec);
+ boost::throw_error(ec);
+ return s;
+ }
+
+ template<typename ConstBufferSequence>
+ std::size_t write_some(const ConstBufferSequence& buf
+ , boost::system::error_code& ec)
+ {
+ return service.write_some(buf, ec);
+ }
+
 /* Not sure if these are needed; leaving it for open discussion to decide.
 
     template<class VarType = ENV>
@@ -186,7 +204,7 @@
     /// Find the get meta-variable matching name
     std::string meta_get(const std::string& name) const
     {
- return impl_.var<tags::GET>(name);
+ return service_.meta_get(impl_, name);
     }
 
     /// Find the post meta-variable matching name
@@ -197,23 +215,19 @@
      */
     std::string meta_post(const std::string& name, bool greedy = true)
     {
- std::string& value = impl_.var<POST>(name);
- if( value.empty() && greedy && impl_.post_data_read() )
- return service_.var<tags::POST>(name);
-
- return value;
+ return service_.meta_post(impl_, name, greedy);
     }
 
     /// Find the cookie meta-variable matching name
     std::string meta_cookie(const std::string& name) const
     {
- return impl_.var<tags::COOKIE>(name);
+ return service_.meta_cookie(impl_, name);
     }
 
     /// Find the environment meta-variable matching name
     std::string meta_env(const std::string& name) const
     {
- return impl_.var<tags::ENV>(name);
+ return service_.meta_env(impl_, name);
     }
 
     /// Search through all meta vars for the meta-variable matching name
@@ -224,35 +238,38 @@
      *
      * Notes:
      * One option is to parse everything, making this option
- * a very poor one in production applications.
+ * very inefficient.
      * Another is to leave this function as a 'lazy' search:
      * it'll search with what it's got and no more. Then, also
      * provide a meta_var_all() function which is greedy; the
      * ugly/long name there to discourage use.
      */
- std::string meta_var(const std::string& name) const
+ std::string meta_var(const std::string& name, bool greedy = false) const
     {
       std::string request_method( meta_env("REQUEST_METHOD") );
 
       std::string tmp;
 
       // If it's not a POST request search meta_get first
- if( request_method.empty() || request_method == "GET" )
+ if (request_method.empty() || request_method == "GET")
       {
- tmp = meta_get(name);
- if( !tmp.empty() )
- return tmp;
+ tmp = meta_get(name);
+ if (!tmp.empty())
+ return tmp;
       }
 
       tmp = meta_cookie(name);
- if( !tmp.empty() ) return tmp;
+ if (!tmp.empty())
+ return tmp;
+
       tmp = meta_env(name);
- if( !tmp.empty() ) return tmp;
+ if (!tmp.empty())
+ return tmp;
 
- if( !request_method.empty() && request_method == "POST" )
+ if (!request_method.empty() && request_method == "POST")
       {
         tmp = meta_post(name);
- if( !tmp.empty() )
+ if (!tmp.empty())
           return tmp;
       }
 
@@ -262,55 +279,55 @@
 
     // Some helper functions for the basic CGI 1.1 meta-variables
     std::string auth_type()
- { return impl_.var<tags::ENV>("AUTH_TYPE"); }
+ { return service_.meta_env(impl_, "AUTH_TYPE"); }
 
     std::string content_length()
- { return impl_.var<tags::ENV>("CONTENT_LENGTH"); }
+ { return service_.meta_env(impl_, "CONTENT_LENGTH"); }
 
     std::string content_type()
- { return impl_.var<tags::ENV>("CONTENT_TYPE"); }
+ { return service_.meta_env(impl_, "CONTENT_TYPE"); }
 
     std::string gateway_interface()
- { return impl_.var<tags::ENV>("GATEWAY_INTERFACE"); }
+ { return service_.meta_env(impl_, "GATEWAY_INTERFACE"); }
 
     std::string path_info()
- { return impl_.var<tags::ENV>("PATH_INFO"); }
+ { return service_.meta_env(impl_, "PATH_INFO"); }
 
     std::string path_translated()
- { return impl_.var<tags::ENV>("PATH_TRANSLATED"); }
+ { return service_.meta_env(impl_, "PATH_TRANSLATED"); }
 
     std::string query_string()
- { return impl_.var<tags::ENV>("QUERY_STRING"); }
+ { return service_.meta_env(impl_, "QUERY_STRING"); }
 
     std::string remote_addr()
- { return impl_.var<tags::ENV>("REMOTE_ADDR"); }
+ { return service_.meta_env(impl_, "REMOTE_ADDR"); }
 
     std::string remote_host()
- { return impl_.var<tags::ENV>("REMOTE_HOST"); }
+ { return service_.meta_env(impl_, "REMOTE_HOST"); }
 
     std::string remote_ident()
- { return impl_.var<tags::ENV>("REMOTE_IDENT"); }
+ { return service_.meta_env(impl_, "REMOTE_IDENT"); }
 
     std::string remote_user()
- { return impl_.var<tags::ENV>("REMOTE_USER"); }
+ { return service_.meta_env(impl_, "REMOTE_USER"); }
 
     std::string request_method()
- { return impl_.var<tags::ENV>("REQUEST_METHOD"); }
+ { return service_.meta_env(impl_, "REQUEST_METHOD"); }
 
     std::string script_name()
- { return impl_.var<tags::ENV>("SCRIPT_NAME"); }
+ { return service_.meta_env(impl_, "SCRIPT_NAME"); }
 
     std::string server_name()
- { return impl_.var<tags::ENV>("SERVER_NAME"); }
+ { return service_.meta_env(impl_, "SERVER_NAME"); }
 
     std::string server_port()
- { return impl_.var<tags::ENV>("SERVER_PORT"); }
+ { return service_.meta_env(impl_, "SERVER_PORT"); }
 
     std::string server_protocol()
- { return impl_.var<tags::ENV>("SERVER_PROTOCOL"); }
+ { return service_.meta_env(impl_, "SERVER_PROTOCOL"); }
 
     std::string server_software()
- { return impl_.var<tags::ENV>("SERVER_SOFTWARE"); }
+ { return service_.meta_env(impl_, "SERVER_SOFTWARE"); }
 
 
     /// The role that the request is playing
@@ -323,7 +340,7 @@
      */
     role_type& role()
     {
- return impl_.role();
+ return service_.get_role(impl_);
     }
 
     /// Get the strand associated with the request (if any)
@@ -331,10 +348,11 @@
     // function like basic_request<>::wrap() should be provided: in the case of
     // a synchronous request type the wrapping would still function as expected
     // and there would be no need for protocol-specific code in user programs.
- boost::asio::strand* strand()
+ /* boost::asio::strand* strand()
     {
       return impl_.strand();
     }
+ */
 
     /// Get the implementation type for the request
     impl_type& impl() const
@@ -342,14 +360,24 @@
       return impl_;
     }
 
+ void set_status(http::status_code status)
+ {
+ service_.set_http_status(impl_, status);
+ }
+
+ bool is_open()
+ {
+ return service_.is_open(impl_);
+ }
+
   private:
- connection_ptr conn_;
+ //connection_ptr conn_;
     service_type& service_;
     impl_type impl_;
 
- int app_status_; // what to return to the server on request completion
- http_status http_status_;
- status_type request_status_;
+ //int app_status_; // what to return to the server on request completion
+ //http::status_code http_status_;
+ //status_type request_status_;
 
     //boost::shared_ptr<data_type> data_;
 

Modified: sandbox/SOC/2007/cgi/boost/cgi/basic_request_acceptor.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/basic_request_acceptor.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/basic_request_acceptor.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -13,46 +13,48 @@
 
 namespace cgi {
 
- template<typename Protocol>
+ template<typename RequestAcceptorService>
   class basic_request_acceptor
     : private boost::noncopyable
+ , public boost::asio::basic_io_object<RequestAcceptorService>
   {
   public:
     // typedef impl_type;
- typedef Protocol protocol_type;
+ typedef RequestAcceptorService service_type;
+ typedef service_type::protocol_type protocol_type;
 
- explicit basic_request_acceptor(basic_protocol_service<Protocol>& pserv)
- : service_(pserv)
+ explicit basic_request_acceptor(basic_protocol_service<protocol_type>& s)
+ : boost::asio::use_service<RequestAcceptorService>(s.io_service())
     {
     }
 
     ~basic_request_acceptor()
     {
- service_.cancel();
+ this->service.cancel();
     }
 
     template<typename CommonGatewayRequest>
     void accept(CommonGatewayRequest& request)
     {
       boost::system::error_code ec;
- service_.accept(request, ec);
+ this->service.accept(request, ec);
       boost::throw_error(ec);
     }
 
     template<typename CommonGatewayRequest> boost::system::error_code&
     accept(CommonGatewayRequest& request, boost::system::error_code& ec)
     {
- return service_.accept(request, ec);
+ return this->service.accept(request, ec);
     }
 
     template<typename CommonGatewayRequest, typename Handler>
     void async_accept(CommonGatewayRequest& request, Handler handler)
     {
- service_.async_accept(request, handler);
+ this->service.async_accept(request, handler);
     }
 
   private:
- request_acceptor_service<protocol_type> service_;
+ service_type& service_;
   };
 
 

Added: sandbox/SOC/2007/cgi/boost/cgi/connections/async_stdio_connection.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/connections/async_stdio_connection.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,60 @@
+// -- async_stdio_connection_impl.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+#ifndef CGI_ASYNC_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
+#define CGI_ASYNC_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
+
+namespace cgi {
+
+ template<typename ProtocolService>
+ class basic_connection<tags::stdio_async>
+ : public connection_base
+ {
+ public:
+ typedef ProtocolService protocol_service_type;
+
+ basic_connection(protocol_service_type& ps)
+ : protocol_service_(ps)
+ , in_(std::cin)
+ , out_(std::cout)
+ {
+ }
+
+ template<typename MutableBufferSequence, typename Handler>
+ void async_read_some(MutableBufferSequence buf, boost::system::error_code& ec
+ , Handler handler)
+ {
+ std::size_t bytes_read;
+ if( buf.data() != in_.rdbuf() )
+ bytes_read = in_.read(buf.data(), buf.size());
+ else
+ bytes_read = buf.size();
+
+ protocol_service_.post(boost::bind(&Handler
+ , handler
+ , boost::system::system_error()
+ , bytes_read ));
+ }
+
+ template<typename ConstBufferSequence, typename Handler>
+ void async_write_some(ConstBufferSequence& buf, boost::system::error_code& ec
+ , Handler handler)
+ {
+ out_.write(buf.data(), buf.size());
+ protocol_service_.post(handler);
+ }
+
+ private:
+ protocol_service_type& protocol_service_;
+ std::istream& in_;
+ std::ostream& out_;
+ };
+
+} // namespace cgi
+
+#endif // CGI_ASYNC_STDIO_CONNECTION_IMPL_HPP_INCLUDED__

Added: sandbox/SOC/2007/cgi/boost/cgi/connections/stdio_connection.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/connections/stdio_connection.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,56 @@
+// -- stdio_connection_impl.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+#ifndef CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
+#define CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
+
+namespace cgi {
+
+ template<typename ProtocolService>
+ class basic_connection<tags::stdio>
+ : public connection_base
+ {
+ public:
+ typedef ProtocolService protocol_service_type;
+
+ basic_connection()
+ : in_(std::cin)
+ , out_(std::cout)
+ {
+ }
+
+ basic_connection(protocol_service_type&)
+ : in_(std::cin)
+ , out_(std::cout)
+ {
+ }
+
+ template<typename MutableBufferSequence>
+ std::size_t read_some(MutableBufferSequence buf, boost::system::error_code& ec)
+ {
+ if( buf.data() != in_.rdbuf() )
+ return in_.read(buf.data(), buf.size());
+ return buf.size();
+ }
+
+ template<typename ConstBufferSequence>
+ std::size_t write_some(ConstBufferSequence& buf, boost::system::error_code& ec)
+ {
+ return out_.write(buf.data(), buf.size());
+ }
+
+ private:
+ std::istream& in_;
+ std::ostream& out_;
+ };
+
+ typedef basic_connection<tags::stdio> stdio_connection;
+
+} // namespace cgi
+
+#endif // CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
\ No newline at end of file

Added: sandbox/SOC/2007/cgi/boost/cgi/connections/stdio_connection_impl.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/connections/stdio_connection_impl.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,56 @@
+// -- stdio_connection_impl.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+#ifndef CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
+#define CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
+
+namespace cgi {
+
+ template<typename ProtocolService>
+ class basic_connection<tags::stdio>
+ : public connection_base
+ {
+ public:
+ typedef ProtocolService protocol_service_type;
+
+ basic_connection()
+ : in_(std::cin)
+ , out_(std::cout)
+ {
+ }
+
+ basic_connection(protocol_service_type&)
+ : in_(std::cin)
+ , out_(std::cout)
+ {
+ }
+
+ template<typename MutableBufferSequence>
+ std::size_t read_some(MutableBufferSequence buf, boost::system::error_code& ec)
+ {
+ if( buf.data() != in_.rdbuf() )
+ return in_.read(buf.data(), buf.size());
+ return buf.size();
+ }
+
+ template<typename ConstBufferSequence>
+ std::size_t write_some(ConstBufferSequence& buf, boost::system::error_code& ec)
+ {
+ return out_.write(buf.data(), buf.size());
+ }
+
+ private:
+ std::istream& in_;
+ std::ostream& out_;
+ };
+
+ typedef basic_connection<tags::stdio> stdio_connection;
+
+} // namespace cgi
+
+#endif // CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
\ No newline at end of file

Added: sandbox/SOC/2007/cgi/boost/cgi/connections/tcp_connection.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/connections/tcp_connection.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,40 @@
+// -- tcp_connection_impl.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+#ifndef CGI_TCP_CONNECTION_IMPL_HPP_INCLUDED__
+#define CGI_TCP_CONNECTION_IMPL_HPP_INCLUDED__
+
+namespace cgi {
+
+ template<typename ProtocolService>
+ class basic_connection<ProtocolService, tags::tcp_socket>
+ : public connection_base
+ {
+ public:
+ typedef ProtocolService protocol_service_type;
+
+ basic_connection(protocol_service_type& ps)
+ : protocol_service_(ps)
+ , sock_(ps.io_service())
+ {
+ }
+
+ template<typename ConstBufferSequence, typename Handler>
+ void async_write(ConstBufferSequence& buf, Handler handler)
+ {
+ }
+
+ private:
+ protocol_service_type protocol_service_;
+ boost::asio::ip::tcp::socket sock_;
+ };
+
+
+} // namespace cgi
+
+#endif // CGI_TCP_CONNECTION_IMPL_HPP_INCLUDED__

Added: sandbox/SOC/2007/cgi/boost/cgi/detail/extract_params.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/detail/extract_params.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,60 @@
+// -- extract_params.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+#ifndef CGI_DETAIL_EXTRACT_PARAMS_HPP_INCLUDED__
+#define CGI_DETAIL_EXTRACT_PARAMS_HPP_INCLUDED__
+
+namespace cgi {
+ namespace detail {
+
+ template<typename Map, typename Separator>
+ boost::system::error_code& extract_params(const std::string& input
+ , Map& destination
+ , const Separator& separator
+ , boost::system::error_code& ec)
+ {
+ if( input.empty() )
+ return boost::system::error_code(34, boost::system::errno_ecat);
+
+ typedef boost::tokenizer<Separator> tokenizer;
+
+ tokenizer toker(input, sep);
+
+ std::string name, current_token;
+
+ for(tokenizer::iterator iter = toker.begin()
+ ; iter != toker.end()
+ ; ++iter)
+ {
+// if( *iter == "%" )
+// {
+// current_token += detail::url_decode( *++iter );
+// }else
+ if(*iter == "=")
+ {
+ name = current_token;
+ current_token.clear();
+ }else
+ if( *iter == "&" )
+ {
+ impl_.get_vars_[name] = current_token;
+ current_token.clear();
+ name.clear();
+ }else
+ {
+ current_token = url_decode(*iter);
+ }
+ }
+ if( !name.empty() )
+ impl_.get_vars_[name] = current_token;
+ }
+
+ } // namespace detail
+} // namespace cgi
+
+#endif // CGI_DETAIL_EXTRACT_PARAMS_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/boost/cgi/detail/request_traits.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/detail/request_traits.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/detail/request_traits.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -9,41 +9,38 @@
     template<typename Protocol, typename RequestType = request_type::responder>
     struct request_traits
     {
-/*
- typedef Protocol protocol_type;
- typedef basic_request<Protocol> request_type;
- typedef gateway<Protocol> gateway_type;
- typedef basic_service<Protocol> service_type;
- typedef service_options<Protocol> service_options; // just an idea
-**/
     };
 
     template<>
     struct request_traits<protocol::cgi>
     {
       typedef cgi_request_impl impl_type;
- typedef request_service<protocol::cgi> service_type;
+ //typedef request_service<protocol::cgi> service_type;
+ typedef cgi_service_impl service_impl_type;
     };
 
     template<>
     struct request_traits<protocol::async_cgi>
     {
- typedef cgi_async_request_impl impl_type;
- typedef request_service<protocol::async_cgi> service_type;
+ typedef async_cgi_request_impl impl_type;
+ //typedef request_service<protocol::async_cgi> service_type;
+ typedef async_cgi_service_impl service_impl_type;
     };
 
     template<>
     struct request_traits<protocol::fcgi>
     {
       typedef fcgi_request_impl impl_type;
- typedef request_service<protocol::fcgi> service_type;
+ //typedef request_service<protocol::fcgi> service_type;
+ typedef fcgi_service_impl service_impl_type;
     };
 
     template<>
     struct request_traits<protocol::scgi>
     {
       typedef scgi_request_impl impl_type;
- typedef request_service<protocol::scgi> service_type;
+ //typedef request_service<protocol::scgi> service_type;
+ typedef scgi_service_impl service_impl_type;
     };
 
  } // namespace detail

Added: sandbox/SOC/2007/cgi/boost/cgi/detail/url_decode.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/detail/url_decode.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,60 @@
+// -- url_decode.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+#ifndef CGI_DETAIL_URL_DECODE_HPP_INCLUDED__
+#define CGI_DETAIL_URL_DECODE_HPP_INCLUDED__
+
+namespace cgi {
+ namespace detail {
+
+ /// URL-decode a string
+ std::string url_decode( const std::string& str )
+ {
+ std::string ret;
+
+ for( unsigned int i=0; i < str.size(); i++ )
+ {
+ switch( str[i] )
+ {
+ case ' ':
+ break;
+ case '+':
+ ret += ' ';
+ break;
+ case '%':
+ ret += url_decode(str[i+1], str[i+2]);
+ i += 2;
+ break;
+ default:
+ ret += str[i];
+ }
+ }
+
+ return ret;
+ }
+
+ /// Take two characters (a hex sequence) and return a char
+ char url_decode( const char c1, const char c2 )
+ {
+ int ret = ( (c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')
+ ? ((c1 & 0xdf) - 'A') + 10
+ : (c1 - '0')
+ ) << 4;
+
+ ret += ( (c2 >= 'A' && c2 <= 'Z') || (c2 >= 'a' && c2 <= 'z')
+ ? ((c2 & 0xdf) - 'A') + 10
+ : (c2 - '0')
+ );
+
+ return static_cast<char>(ret);
+ }
+
+ } // namespace detail
+} // namespace cgi
+
+#endif // CGI_DETAIL_URL_DECODE_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/boost/cgi/logger.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/logger.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/logger.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -24,6 +24,7 @@
   public:
     /// Default constructor
     explicit logger()
+ : ostream(tags::stderr)
     {
     }
 
@@ -33,7 +34,7 @@
      * destruction.
      */
     logger(std::streambuf* buf)
- : ostream(buf)
+ : ostream(buf, tags::stderr)
     {
     }
 
@@ -48,7 +49,7 @@
      */
     template<typename CommonGatewayRequest>
     logger(CommonGatewayRequest& req)
- : ostream(req)
+ : ostream(req, tags::stderr)
     {
     }
 

Modified: sandbox/SOC/2007/cgi/boost/cgi/ostream.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/ostream.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/ostream.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -248,7 +248,7 @@
       req.async_write(ostream_.rdbuf(), destination_, handler));
     }
 
- /// Get the buffer associated with the
+ /// Get the buffer associated with the stream
     std::streambuf* rdbuf() const { return ostream_.rdbuf(); }
 
     void set_status(http::status_code& num) { http_status_ = num; }

Modified: sandbox/SOC/2007/cgi/boost/cgi/request_acceptor_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/request_acceptor_service.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/request_acceptor_service.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -16,9 +16,22 @@
   {
   public:
     typedef Protocol protocol_type;
+ typedef basic_request<Protocol, ...> implementation_type;
 
- request_acceptor_service(basic_protocol_service<protocol_type>& pserv)
- : pservice_(pserv)
+ explicit request_acceptor_service(basic_protocol_service<protocol_type>& s)
+ : pservice_(s)
+ {
+ }
+
+ void shutdown_service()
+ {
+ }
+
+ void construct(implementation_type& impl)
+ {
+ }
+
+ void destroy(implementation_type& impl)
     {
     }
 
@@ -27,7 +40,8 @@
      * Check if there is a waiting request in the queue. If not, accept a
      * connection, and associate it with the request.
      */
- template<typename CommonGatewayRequest> boost::system::error_code&
+ template<typename CommonGatewayRequest>
+ boost::system::error_code&
     accept(CommonGatewayRequest& request, boost::system::error_code& ec)
     {
       boost::thread::mutex::scoped_lock lk(io_service_.mutex_);
@@ -45,8 +59,8 @@
     }
 
     /// Asynchronously accept a request
- template<typename RequestService, typename Handler>
- void async_accept( basic_request<RequestService>& request, Handler handler )
+ template<typename CommonGatewayRequest, typename Handler>
+ void async_accept(CommonGatewayRequest& request, Handler handler)
     {
       boost::thread::mutex::scoped_lock lk(io_service_.mutex_);
       if( !io_service_.request_queue_.empty() )
@@ -57,7 +71,7 @@
               return ec;
       }
       lk.unlock();
- pservice_.gateway_.async_accept(&request.connection(), handler);
+ pservice_.gateway_.async_accept(request.connection(), handler);
     }
 
   private:

Modified: sandbox/SOC/2007/cgi/boost/cgi/request_base.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/request_base.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/request_base.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -82,6 +82,13 @@
      * supported in production servers {{AFAIK}}
      */
     virtual role_type role() = 0;
+
+ /* SyncReadStream function */
+ template<typename MutableBufferSequence>
+ virtual std::size_t read_some(MutableBufferSequence) = 0;
+
+ template<typename MutableBufferSequence>
+ virtual std::size_t read_some(MutableBufferSequence, error_code&) = 0;
   };
 
 } // namespace cgi

Added: sandbox/SOC/2007/cgi/boost/cgi/request_impl/async_cgi_request_impl.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/request_impl/async_cgi_request_impl.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,26 @@
+#ifndef CGI_ASYNC_CGI_REQUEST_IMPL_HPP_INCLUDED__
+#define CGI_ASYNC_CGI_REQUEST_IMPL_HPP_INCLUDED__
+
+namespace cgi {
+
+ class async_cgi_request_impl
+ : public cgi_request_impl
+ {
+ public:
+ //typedef std::map<std::string,std::string> map_type;
+
+ async_cgi_request_impl(protocol_service_type& protocol_service)
+ : cgi_request_impl(protocol_service)
+ , protocol_service_(protocol_service)
+ {
+ }
+
+ protected:
+ friend class async_cgi_service_impl;
+
+ protocol_service_type& protocol_service_;
+ };
+
+} // namespace cgi
+
+#endif // CGI_ASYNC_CGI_REQUEST_IMPL_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/boost/cgi/request_impl/cgi_request_impl.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/request_impl/cgi_request_impl.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/request_impl/cgi_request_impl.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -1,157 +1,106 @@
 // -- cgi_request_impl.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
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 //
 ////////////////////////////////////////////////////////////////
-#ifndef CGI_CGI_REQUEST_IMPL_HPP_INCLUDED__
-#define CGI_CGI_REQUEST_IMPL_HPP_INCLUDED__
-
-#include <map>
-#include <boost/noncopyable.hpp>
-
-namespace cgi {
- namespace detail {
- typename std::map<std::string,std::string> map_type;
- } // namespace detail
-
-
- /// Implementation for a standard CGI request
- /**
- * Note: This isn't noncopyable since there's no real reason it can't be
- * copied around. Since basic_request is noncopyable, basic copying will be
- * restricted but if someone really wants to copy the data, then they can.
- */
- class cgi_request_impl
- {
- public:
- /// Constructor
- /**
- * Since this request type is synchronous, there is no need for an
- * io_service, so the passed ProtocolService is just ignored.
- */
- template<typename ProtocolService>
- cgi_request_impl(ProtocolService& pserv)
- {
- load(false);
- }
-
- /// Synchronously read/parse the request meta-data
- /**
- * @param parse_stdin if true then STDIN data is also read/parsed
- */
- bool load(bool parse_stdin)
- {
- }
-
- /// Asynchronously read/parse the request meta-data
- /**
- * @param parse_stdin if true then STDIN data is also read/parsed
- */
- template<typename Handler>
- void async_load(bool parse_stdin, Handler handler)
- {
- load(parse_stdin);
- handler();
- }
-
- template<typename ConnectionPtr, typename MutableBufferSequence>
- std::size_t read(ConnectionPtr conn, MutableBufferSequence buf)
- {
- return conn.read(buf);
- }
-
- template<typename ConnectionPtr, typename MutableBufferSequence
- , typename Handler>
- void async_read(ConnectionPtr conn, MutableBufferSequence buf
- , Handler handler)
- {
- conn.async_read(buf, handler);
- }
-
- template<typename ConnectionPtr, typename ConstBufferSequence>
- std::size_t write(ConnectionPtr conn, ConstBufferSequence buf)
- {
- return conn.write(buf);
- }
-
- template<typename ConnectionPtr, typename ConstBufferSequence
- , typename Handler>
- void async_write(ConnectionPtr conn, ConstBufferSequence buf
- , Handler handler)
- {
- conn.async_write(buf, handler);
- }
-
- template<typename VarType> map_type& var() const;
-
- template<typename VarType>
- const std::string& var(const std::string& name) const
- {
- map_type& meta_data = var<VarType>();
- if((map_type::iterator pos = meta_data.find(name))
- != meta_data.end())
- {
- return *pos;
- }
- return std::string();
-
- /* Alt:
- if( meta_data.find(name) != meta_data.end() )
- return meta_data[name];
- return std::string();
- **/
- }
-
- void* strand() const { return NULL; }
- role_type role() const { return role_type::responder; }
-
- private: // functions
-
-
- private: // variables
- //map_type env_map_;
- map_type http_map_;
- map_type cookie_map_;
- map_type get_map_;
- map_type post_map_;
- };
-
- template<> inline const std::string&
- cgi_request_impl::var<tags::ENV>(const std::string& name)
- {
- return ::getenv(name);
- }
-
- /// Get a request map of all the environment meta-variables (slow)
- /**
- * -- NOT IMPLEMENTED FOR NOW --
- *
- * In the case of a CGI request, the environment meta-data is usually stored
- * in the process environment, which means there is no direct access to all
- * of them as a map_type&. In other words, this function call will have to
- * load all of the variables into memory and then return the map
- */
- //template<> inline cgi_request_impl::map_type&
- //cgi_request_impl::var<tags::ENV>()
- //{
- // throw std::logic_error("Can't get all environment vars as a map_type&");
- //}
-
- template<> inline cgi_request_impl::map_type&
- cgi_request_impl::var<tags::HTTP>() { return http_map_; }
-
- template<> inline cgi_request_impl::map_type&
- cgi_request_impl::var<tags::COOKIE>() { return cookie_map_; }
-
- template<> inline cgi_request_impl::map_type&
- cgi_request_impl::var<tags::GET>() { return get_map_; }
-
- template<> inline cgi_request_impl::map_type&
- cgi_request_impl::var<tags::POST>() { return post_map_; }
-
-} // namespace cgi
-
-#endif // CGI_CGI_REQUEST_IMPL_HPP_INCLUDED__
+#ifndef CGI_CGI_REQUEST_IMPL_HPP_INCLUDED__
+#define CGI_CGI_REQUEST_IMPL_HPP_INCLUDED__
+
+#include <map>
+#include <boost/noncopyable.hpp>
+
+namespace cgi {
+ namespace detail {
+ typename std::map<std::string,std::string> map_type;
+ } // namespace detail
+
+
+ /// Implementation for a standard CGI request
+ /**
+ * Note: This isn't noncopyable since there's no real reason it can't be
+ * copied around. Since basic_request is noncopyable, basic copying will be
+ * restricted but if someone really wants to copy the data, then they can.
+ */
+ class cgi_request_impl
+ {
+ public:
+ typedef std::map<std::string, std::string> map_type;
+
+ /// Constructor
+ /**
+ * Since this request type is synchronous, there is no need for an
+ * io_service, so the passed ProtocolService is just ignored.
+ */
+ template<typename ProtocolService>
+ cgi_request_impl(ProtocolService& pserv)
+ : stdin_read_(false)
+ , http_status_(http::status_code::ok)
+ , request_status_(request_status::unloaded)
+ {
+ }
+
+ private:
+ friend class cgi_service_impl;
+
+ protected:
+ map_type get_vars_;
+ map_type post_vars_;
+ map_type cookie_vars_;
+
+ bool stdin_read_;
+
+ http::status_code http_status_;
+ request_status request_status_;
+ };
+
+
+ private: // functions
+
+
+ private: // variables
+ //map_type env_map_;
+ map_type http_map_;
+ map_type cookie_map_;
+ map_type get_map_;
+ map_type post_map_;
+ };
+
+ template<> inline const std::string&
+ cgi_request_impl::var<tags::ENV>(const std::string& name)
+ {
+ return ::getenv(name);
+ }
+
+ /// Get a request map of all the environment meta-variables (slow)
+ /**
+ * -- NOT IMPLEMENTED FOR NOW --
+ *
+ * In the case of a CGI request, the environment meta-data is usually stored
+ * in the process environment, which means there is no direct access to all
+ * of them as a map_type&. In other words, this function call will have to
+ * load all of the variables into memory and then return the map
+ */
+ //template<> inline cgi_request_impl::map_type&
+ //cgi_request_impl::var<tags::ENV>()
+ //{
+ // throw std::logic_error("Can't get all environment vars as a map_type&");
+ //}
+
+ template<> inline cgi_request_impl::map_type&
+ cgi_request_impl::var<tags::HTTP>() { return http_map_; }
+
+ template<> inline cgi_request_impl::map_type&
+ cgi_request_impl::var<tags::COOKIE>() { return cookie_map_; }
+
+ template<> inline cgi_request_impl::map_type&
+ cgi_request_impl::var<tags::GET>() { return get_map_; }
+
+ template<> inline cgi_request_impl::map_type&
+ cgi_request_impl::var<tags::POST>() { return post_map_; }
+
+} // namespace cgi
+
+#endif // CGI_CGI_REQUEST_IMPL_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/boost/cgi/request_impl/fcgi_request_impl.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/request_impl/fcgi_request_impl.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/request_impl/fcgi_request_impl.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -1,44 +1,57 @@
 // -- fcgi_request_impl.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
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 //
 ////////////////////////////////////////////////////////////////
-#ifndef CGI_FCGI_REQUEST_IMPL_HPP_INCLUDED__
-#define CGI_FCGI_REQUEST_IMPL_HPP_INCLUDED__
-
-namespace cgi {
-
- /// Implementation for a FastCGI Responder request
- class fcgi_responder_request_impl
- {
- fcgi_request() {} // private default constructor
- public:
- fcgi_request(protocol_service_type& pserv)
- : protocol_service_(pserv)
- {
- }
-
- bool load(bool parse_stdin)
- {
- }
-
- template<typename Handler>
- void async_load(bool parse_stdin, Handler handler)
- {
- }
-
- /// The role of the request; in this case a responder
- static role_type& role() { return role_type::responder; }
- private:
- protocol_service_type& protocol_service_;
-
- /// Finished reading from stdin buffer (ie. POST data)
- bool stdin_read_;
- };
-
-} // namespace cgi
-
-#endif // CGI_FCGI_REQUEST_IMPL_HPP_INCLUDED__
+#ifndef CGI_FCGI_REQUEST_IMPL_HPP_INCLUDED__
+#define CGI_FCGI_REQUEST_IMPL_HPP_INCLUDED__
+
+namespace cgi {
+
+ /// Implementation for a FastCGI request
+ class fcgi_request_impl
+ {
+ fcgi_request() {} // private default constructor
+ public:
+ typedef tags::fastcgi protocol_type;
+
+ explicit fcgi_request_impl(protocol_service_type& pserv
+ , const role_type& role = role_type::responder
+ , boost::weak_ptr<connection_base> connection = NULL)
+ : protocol_service_(pserv)
+ , role_(role)
+ , connection_(connection)
+ , data_read_(role_ == role_type::filter ? false : true)
+ , stdin_read_(role_ == role_type::authorizer ? true : false)
+ {
+ }
+
+ protected:
+ protocol_service_type& protocol_service_;
+
+ /// The role the request plays
+ role_type role_;
+
+ map_type env_vars_;
+ map_type cookie_vars_;
+ map_type post_vars_;
+ map_type get_vars_;
+
+ std::string stdin_buffer_;
+ std::string data_buffer_;
+
+ /// Finished reading from stdin buffer (ie. POST data)
+ bool stdin_read_;
+
+ /// Finished reading from data buffer (for Filter requests)
+ bool data_read_;
+
+ friend class fcgi_service_impl;
+ };
+
+} // namespace cgi
+
+#endif // CGI_FCGI_REQUEST_IMPL_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/boost/cgi/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/request_service.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -15,68 +15,75 @@
   class request_service
     : public boost::asio::io_service::service
   {
+ // The platform-specific implementation (only one for now)
+ typedef detail::request_traits<Protocol>::service_impl_type
+ service_impl_type;
+
   public:
+ typedef service_impl_type::impl_type impl_type;
+
     typedef Protocol protocol_type;
     typedef basic_protocol_service<Protocol> protocol_service_type;
     typedef basic_request<Protocol> request_type;
     //typedef request_impl<Protocol>
 
 
- request_service(io_service_type& ios)
- : boost::asio::io_service::service(ios.io_service())
- , io_service_(ios)
+ /// The unique service identifier
+ static boost::asio::io_service::id id;
+
+ request_service(protocol_service_type& ps)
+ : boost::asio::io_service::service(ps.io_service())
+ , service_impl_(boost::asio::use_service<service_impl_type>(ps.io_service()))
     {
     }
 
- void shutdown_service()
+ void create(impl_type& impl)
     {
+ service_impl_.create(impl);
     }
 
- //void construct
-
- bool load()
+ void destroy(impl_type& impl)
     {
+ service_impl_.destroy(impl);
     }
 
- template<typename ProtocolService, typename Handler>
- class load_handler
+ void shutdown_service()
     {
- public:
- load_handler(ProtocolService& ps, Handler handler)
- : service_(ps)
- , handler_(handler)
- {
- }
+ service_impl_.shutdown_service();
+ }
 
- void operator()(boost::system::error_code& ec)
- {
- if( ec )
- handler(ec);
+ impl_type null() const
+ {
+ return service_impl_.null();
+ }
 
+ //void construct
 
- //service_.dispatch(handler_(ec));
- }
+ boost::system::error_code& load(bool parse_stdin, boost::system::error_code& ec)
+ {
+ return service_impl_.load(parse_stdin, ec);
+ }
 
- private:
- ProtocolService& service_;
- Handler handler_;
- };
 
     template<typename Handler>
- void async_load(Handler handler)
+ void async_load(impl_type& impl, bool parse_stdin, boost::system::error_code& ec
+ , Handler handler)
     {
+ service_impl_.async_load(impl, parse_stdin, ec, handler);
     }
- private:
- io_service_type& io_service_;
- };
 
- template<>
- class request_service<protocol::cgi>
- {
- public:
+ bool is_open(impl_type& impl);
+ {
+ return service_impl_.is_open(impl);
+ }
 
+ private:
+ service_impl_type& service_impl_;
   };
 
+ template<typename Protocol>
+ boost::asio::io_service::id request_service<Protocol>::id;
+
 } // namespace cgi
 
 #endif // CGI_REQUEST_SERVICE_HPP_INCLUDED

Added: sandbox/SOC/2007/cgi/boost/cgi/service_impl/async_cgi_service_impl.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/service_impl/async_cgi_service_impl.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,84 @@
+#ifndef CGI_ASYNC_CGI_SERVICE_IMPL_HPP_INCLUDED__
+#define CGI_ASYNC_CGI_SERVICE_IMPL_HPP_INCLUDED__
+
+namespace cgi {
+
+ class async_cgi_service_impl
+ : public boost::asio::io_service::service
+ , public cgi_service_impl<async_cgi_request_impl>
+ {
+ public:
+ typedef tags::async_cgi protocol_type;
+ typedef typename protocol_type::service_type protocol_service_type;
+
+ /// The unique service identifier
+ static boost::asio::io_service::id id;
+
+ explicit async_cgi_service_impl(protocol_service_type& protocol_service)
+ : boost::asio::io_service::service(protocol_service.io_service())
+ , cgi_service_impl<async_cgi_request_impl>()
+ {
+ }
+
+ void shutdown_service()
+ {
+ }
+
+ /// Construct a new cgi request implementation
+ void construct(impl_type& impl)
+ {
+ }
+
+ template<typename ImplType, typename Handler>
+ class load_handler
+ {
+ public:
+ load_handler(impl_type& impl, bool parse_stdin, Handler handler)
+ : impl_(impl)
+ , service_(impl.service_)
+ , work_(service.io_service())
+ , parse_stdin_(parse_stdin)
+ , handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& error)
+ {
+ if (error)
+ service_.post(boost::bind(&Handler, handler_, error));
+
+ }
+ private:
+ protocol_service_type& service_;
+ protocol_service_type::work work_;
+ Handler handler_;
+ ImplType impl_;
+ };
+
+ /// Asynchronously read/parse the request meta-data
+ /**
+ * @param parse_stdin if true then STDIN data is also read/parsed
+ */
+ template<typename Handler>
+ void async_load(impl_type& impl, bool parse_stdin, Handler handler)
+ {
+ impl.service_.post(boost::bind(&load_handler<impl_type, Handler>
+ (impl, parse_stdin, handler)));
+ }
+
+ template<typename MutableBufferSequence, typename Handler>
+ void async_read_some(impl_type& impl, const MutableBufferSequence& buf
+ , Handler handler)
+ {
+ impl.connection_->async_read_some(buf, handler);
+ }
+
+ template<typename ConstBufferSequence, typename Handler>
+ void async_write_some(impl_type& impl, const ConstBufferSequence& buf
+ , Handler handler)
+ {
+ impl.connection_->async_write_some(buf, handler);
+ }
+ };
+
+#endif // CGI_ASYNC_CGI_SERVICE_IMPL_HPP_INCLUDED__

Added: sandbox/SOC/2007/cgi/boost/cgi/service_impl/cgi_service_impl.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/service_impl/cgi_service_impl.hpp 2007-07-12 14:09:06 EDT (Thu, 12 Jul 2007)
@@ -0,0 +1,214 @@
+#ifndef CGI_CGI_SERVICE_IMPL_HPP_INCLUDED__
+#define CGI_CGI_SERVICE_IMPL_HPP_INCLUDED__
+
+namespace cgi {
+
+ template<typename RequestImplType>
+ class cgi_service_impl
+ {
+ public:
+ typedef RequestImplType impl_type;
+
+ explicit cgi_service_impl()
+ {
+ }
+
+ explicit cgi_service_impl(protocol_service_type&)
+ {
+ }
+
+ void shutdown_service()
+ {
+ }
+
+ void create(impl_type& impl)
+ {
+ }
+
+ void destroy(impl_type& impl)
+ {
+ }
+
+ /// Synchronously read/parse the request meta-data
+ /**
+ * @param parse_stdin if true then STDIN data is also read/parsed
+ */
+ boost::system::error_code& load(boost::system::error_code& ec
+ , bool parse_stdin)
+ {
+ std::string request_method = meta_get("REQUEST_METHOD");
+ if (request_method == "GET")
+ if (parse_get_vars(ec))
+ return ec;
+ else
+ if (request_method == "POST" && parse_stdin)
+ if (parse_post_vars(ec))
+ return ec;
+
+ parse_cookie_vars(ec);
+ return ec;
+ }
+
+ template<typename ConnectionPtr, typename MutableBufferSequence>
+ std::size_t read_some(impl_type& impl, const MutableBufferSequence& buf
+ , boost::system::error_code& ec)
+ {
+ std::size_t s = impl.connection_->read_some(buf, ec);
+ return s;
+ }
+
+ template<typename ConnectionPtr, typename ConstBufferSequence>
+ std::size_t write_some(impl_type& impl, const ConstBufferSequence& buf
+ , boost::system::error_code& ec)
+ {
+ return impl.connection_->write_some(buf, ec);
+ }
+
+
+ //template<typename VarType> map_type& var(impl_type&) const;
+
+ const std::string& var(map_type& meta_data, const std::string& name
+ , boost::system::error_code& ec) const
+ {
+ if ((map_type::iterator pos = meta_data.find(name)) != meta_data.end())
+ {
+ return *pos;
+ }
+ return std::string();
+
+ /* Alt:
+ if( meta_data.find(name) != meta_data.end() )
+ return meta_data[name];
+ return std::string();
+ **/
+ }
+
+ const std::string& meta_get(impl_type& impl, const std::string& name
+ , boost::system::error_code& ec) const
+ {
+ return var(impl.get_vars_, name, ec);
+ }
+
+ map_type& meta_get(impl_type& impl) const
+ {
+ return impl.get_vars_;
+ }
+
+ /// Find the post meta-variable matching name
+ /**
+ * @param greedy This determines whether more data can be read to find
+ * the variable. The default is true to cause least surprise in the common
+ * case of having not parsed any of the POST data.
+
+ -----------------------------------------------
+ Should this return a pair of iterators instead?
+ What about url_decoding?
+ -----------------------------------------------
+
+ */
+ const std::string& meta_post(impl_type& impl, const std::string& name
+ , boost::system::error_code& ec
+ , bool greedy = true)
+ {
+ const std::string& val = var(impl.post_vars_, name, ec);
+ if (var.empty() && greedy && !ec)
+ {
+
+ }
+
+ return val;
+ }
+
+ map_type& meta_post(impl_type& impl) const
+ {
+ return impl.post_vars_;
+ }
+
+
+ /// Find the cookie meta-variable matching name
+ const std::string& meta_cookie(impl_type& impl, const std::string& name
+ , boost::system::error_code& ec) const
+ {
+ return var(impl.cookie_vars_, name, ec, false);
+ }
+
+ map_type& meta_cookie(impl_type& impl) const
+ {
+ return impl.cookie_vars_;
+ }
+
+
+ /// Find the environment meta-variable matching name
+ const std::string& meta_env(impl_type& impl, const std::string& name,
+ , boost::system::error_code& ec) const
+ {
+ return ::getenv(name);
+ }
+
+
+ role_type get_role(impl_type& impl) const
+ {
+ return role_type::responder;
+ }
+
+ protected:
+ boost::system::error_code& parse_get_vars(impl_type& impl
+ , boost::system::error_code& ec)
+ {
+ // Make sure this function hasn't already been called
+ BOOST_ASSERT( impl.get_vars_.empty() );
+
+ extract_params(meta_env("QUERY_STRING")
+ , impl.get_vars_
+ , boost::char_separator<char>
+ ("", "=&", boost::keep_empty_tokens)
+ , ec);
+
+ return ec;
+ }
+
+ boost::system::error_code& parse_cookie_vars(impl_type& impl
+ , boost::system::error_code& ec)
+ {
+ // Make sure this function hasn't already been called
+ BOOST_ASSERT( impl.cookie_vars_.empty() );
+
+ std::string vars = meta_env("HTTP_COOKIE");
+ if (vars.empty())
+ return ec;
+
+ extract_params(meta_env("HTTP_COOKIE")
+ , impl.cookie_vars_
+ , boost::char_separator<char>
+ ("", "=&", boost::keep_empty_tokens)
+ , ec);
+
+ return ec;
+ }
+
+ boost::system::error_code& parse_post_vars(impl_type& impl
+ , boost::system::error_code& ec)
+ {
+ // Make sure this function hasn't already been called
+ BOOST_ASSERT( impl.cookie_vars_.empty() );
+
+# error "Not implemented"
+
+ if (impl_.stdin_parsed_)
+ {
+ }
+
+ return ec;
+ }
+
+ boost::system::error_code& parse_one_post_var(impl_type& impl
+ , boost::system::error_code& ec)
+ {
+# error "Not implemented"
+ return ec;
+ }
+ };
+
+} // namespace cgi
+
+#endif // CGI_CGI_SERVICE_IMPL_HPP_INCLUDED__


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