Boost logo

Boost-Commit :

From: drrngrvy_at_[hidden]
Date: 2007-07-05 20:17:23


Author: drrngrvy
Date: 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
New Revision: 7371
URL: http://svn.boost.org/trac/boost/changeset/7371

Log:
removing some old files; fixing http/status_code.hpp; updating conflicted files from last update; adding ostream.hpp and logger.hpp/reply.hpp, which are interfaces for a cgi::ostream (for logging/error output and standard output respectively)

Added:
   sandbox/SOC/2007/cgi/boost/cgi.hpp
   sandbox/SOC/2007/cgi/boost/cgi/detail/cgi_acceptor_service.hpp
   sandbox/SOC/2007/cgi/boost/cgi/detail/fcgi_acceptor_service.hpp
   sandbox/SOC/2007/cgi/boost/cgi/detail/request_impl.hpp
   sandbox/SOC/2007/cgi/boost/cgi/detail/take_buffer.hpp
   sandbox/SOC/2007/cgi/boost/cgi/logger.hpp
   sandbox/SOC/2007/cgi/boost/cgi/ostream.hpp
   sandbox/SOC/2007/cgi/boost/cgi/protocol_traits.hpp
   sandbox/SOC/2007/cgi/boost/cgi/protocols.hpp
   sandbox/SOC/2007/cgi/boost/cgi/request_type.hpp
Removed:
   sandbox/SOC/2007/cgi/boost/cgi/basic_service.hpp
Text files modified:
   sandbox/SOC/2007/cgi/boost/cgi/basic_request.hpp | 473 +++++++++++++++++++++++++++++++++++++--
   sandbox/SOC/2007/cgi/boost/cgi/basic_request_acceptor.hpp | 12
   sandbox/SOC/2007/cgi/boost/cgi/gateway.hpp | 237 ++++++++++---------
   sandbox/SOC/2007/cgi/boost/cgi/http/status_code.hpp | 126 +++++-----
   sandbox/SOC/2007/cgi/boost/cgi/reply.hpp | 152 +-----------
   sandbox/SOC/2007/cgi/boost/cgi/request.hpp | 102 ++++++++
   sandbox/SOC/2007/cgi/boost/cgi/request_acceptor_service.hpp | 4
   7 files changed, 770 insertions(+), 336 deletions(-)

Added: sandbox/SOC/2007/cgi/boost/cgi.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,16 @@
+// -- cgi.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_HPP_INCLUDED__
+#define CGI_HPP_INCLUDED__
+
+// #include all headers except for cgi/cgi.hpp, cgi/fcgi.hpp, cgi/scgi.hpp
+
+#include "cgi/basic_request.hpp"
+
+#endif // CGI_HPP_INCLUDED__

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-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -1,41 +1,143 @@
-#ifndef CGI_BASIC_REQUEST_HPP_INCLUDE_
-#define CGI_BASIC_REQUEST_HPP_INCLUDE_
+// -- basic_request.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+#ifndef CGI_BASIC_REQUEST_HPP_INCLUDED__
+#define CGI_BASIC_REQUEST_HPP_INCLUDED__
 
+#include <iostream>
 #include <boost/noncopyable.hpp>
 
 namespace cgi {
 
- /// The 'role' of the request
- /**
- * See the section on 'role types' in the Design notes for more information.
- * @code responder @endcode is by far the most common type
- */
- enum role_type
- { undefined
- , responder
- , authorizer // American spelling, yes
- , filter
- };
-
   enum status_type
     { ok
     , aborted
     , ended
     };
 
- template< typename ServiceType, typename Allocator = std::allocator() >
+
+ /// The basic_request class, primary entry point to the library
+ /**
+ * Note: This class is supposed to make simple use of the library easy.
+ * This comes with some restrictions, such as being noncopyable, and also
+ * providing copies of the meta-variables rather than references. This makes
+ * sure the internal data is protected.
+ * The underlying impl_type classes aren't like this (and as such aren't
+ * quite as 'safe' to use) but they may be more suited to certain needs.
+ *
+ * Note: This class isn't thread safe: carrying around a mutex-per-request
+ * seems prohibitively expensive. There could be functions which take a mutex
+ * as an arguement and lock it. (Async calls could get messy if you need a
+ * protected request object)
+ */
+ template<typename Protocol
+ , enum RequestRole = role_type::responder
+ , typename ProtocolService = basic_protocol_service<Protocol>
+ , typename Allocator = std::allocator<char> >
   class basic_request
     : public request_base
     , private boost::noncopyable
   {
   public:
- typedef ServiceType service_type;
- typedef typename ServiceType::protocol_type protocol_type;
+ typedef basic_request<Protocol, RequestRole
+ , ProtocolService, Allocator > type;
+ typedef Protocol protocol_type;
+ typedef RequestRole 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 boost::shared_ptr<connection_base> connection_ptr;
+
+
+ explicit basic_request(protocol_service_type& s, bool load_now = false)
+ : impl_(s)
+ , status_num_(0)
+ //, strand_(s.io_service())
+ {
+ if( load_now ) load();
+ }
+
+ /// Alternate constructor for CGI requests, which don't require a service
+ explicit basic_request(bool load_now = false)
+ : impl_()
+ , status_num_(0)
+ {
+ if( load_now ) load();
+ }
+
+ ~basic_request()
+ {
+ end(status_num_);
+ }
+
+ /// Synchronously read/parse the request meta-data
+ /**
+ * Note: 'loading' including reading/parsing STDIN if parse_stdin == true
+ */
+ bool load(bool parse_stdin = false)
+ {
+ if( !service_.load(impl_, parse_stdin) )
+ {
+ status_ = status_type::aborted;
+ return false;
+ }
+ return true;
+ }
+
+ /// Asynchronously read/parse the request meta-data
+ /**
+ * Note: 'loading' including reading/parsing STDIN if parse_stdin == true
+ */
+ template<typename Handler>
+ void async_load(Handler handler, bool parse_stdin = false)
+ {
+ 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);
+ }
 
- explicit basic_request(service_type& s)
- : service_(s)
- , role_(undefined)
+ 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
@@ -44,24 +146,339 @@
      * functions) it will be necessary to call end, rather than just returning
      * from the sub_main function.
      *
- * @param status_code This value is returned to the server indicating the
+ * @param program_status This value is returned to the server indicating the
      * state of the request after it was finished handling. It is
      * implementation defined how the server deals with this, and it may have
      * no effect on the http status code returned to the client (eg. 200 OK).
      */
- void end(int status_code)
+ void close(http::status_code http_status, int program_status)
     {
- service_.end_request(this, status_code);
- status_ = status_type::ended;
+ BOOST_ASSERT( request_status_ != status_type::ended );
+
+ request_status_ = status_type::ended;
+ http_status_ = http_status;
+ program_status_ = program_status;
+ service_.end(impl_);
+ //io_service_.dispatch(set_status(status_type::ended));
+ //impl_.end_request(this, status_code);
+ }
+
+ void close(int http_status, int program_status)
+ {
+
     }
+
+/* Not sure if these are needed; leaving it for open discussion to decide.
+
+ template<class VarType = ENV>
+ const std::string& var(const std::string& name) const
+ {
+ return impl_.var<VarType>(name);
+ }
+
+ template<typename ToType, class VarType = ENV>
+ const std::string& var_as(const std::string& name) const
+ {
+ return boost::lexical_cast<ToType>(var<VarType>(name));
+ }
+**/
+
+ /// Find the get meta-variable matching name
+ std::string meta_get(const std::string& name) const
+ {
+ return impl_.var<tags::GET>(name);
+ }
+
+ /// 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.
+ */
+ 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;
+ }
+
+ /// Find the cookie meta-variable matching name
+ std::string meta_cookie(const std::string& name) const
+ {
+ return impl_.var<tags::COOKIE>(name);
+ }
+
+ /// Find the environment meta-variable matching name
+ std::string meta_env(const std::string& name) const
+ {
+ return impl_.var<tags::ENV>(name);
+ }
+
+ /// Search through all meta vars for the meta-variable matching name
+ /**
+ * The policy w.r.t. POST data (ie. whether it should all
+ * be read/parsed and included in this search or not) is
+ * to be decided.
+ *
+ * Notes:
+ * One option is to parse everything, making this option
+ * a very poor one in production applications.
+ * 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 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" )
+ {
+ tmp = meta_get(name);
+ if( !tmp.empty() )
+ return tmp;
+ }
+
+ tmp = meta_cookie(name);
+ if( !tmp.empty() ) return tmp;
+ tmp = meta_env(name);
+ if( !tmp.empty() ) return tmp;
+
+ if( !request_method.empty() && request_method == "POST" )
+ {
+ tmp = meta_post(name);
+ if( !tmp.empty() )
+ return tmp;
+ }
+
+ tmp = meta_get(name);
+ return tmp.empty() ? "" : tmp;
+ }
+
+ // Some helper functions for the basic CGI 1.1 meta-variables
+ std::string auth_type()
+ { return impl_.var<tags::ENV>("AUTH_TYPE"); }
+
+ std::string content_length()
+ { return impl_.var<tags::ENV>("CONTENT_LENGTH"); }
+
+ std::string content_type()
+ { return impl_.var<tags::ENV>("CONTENT_TYPE"); }
+
+ std::string gateway_interface()
+ { return impl_.var<tags::ENV>("GATEWAY_INTERFACE"); }
+
+ std::string path_info()
+ { return impl_.var<tags::ENV>("PATH_INFO"); }
+
+ std::string path_translated()
+ { return impl_.var<tags::ENV>("PATH_TRANSLATED"); }
+
+ std::string query_string()
+ { return impl_.var<tags::ENV>("QUERY_STRING"); }
+
+ std::string remote_addr()
+ { return impl_.var<tags::ENV>("REMOTE_ADDR"); }
+
+ std::string remote_host()
+ { return impl_.var<tags::ENV>("REMOTE_HOST"); }
+
+ std::string remote_ident()
+ { return impl_.var<tags::ENV>("REMOTE_IDENT"); }
+
+ std::string remote_user()
+ { return impl_.var<tags::ENV>("REMOTE_USER"); }
+
+ std::string request_method()
+ { return impl_.var<tags::ENV>("REQUEST_METHOD"); }
+
+ std::string script_name()
+ { return impl_.var<tags::ENV>("SCRIPT_NAME"); }
+
+ std::string server_name()
+ { return impl_.var<tags::ENV>("SERVER_NAME"); }
+
+ std::string server_port()
+ { return impl_.var<tags::ENV>("SERVER_PORT"); }
+
+ std::string server_protocol()
+ { return impl_.var<tags::ENV>("SERVER_PROTOCOL"); }
+
+ std::string server_software()
+ { return impl_.var<tags::ENV>("SERVER_SOFTWARE"); }
+
+
+ /// The role that the request is playing
+ /**
+ * The default role type is responder.
+ *
+ * In some cases - for instance with FastCGI - the role type can be
+ * different
+ * eg. authorizer, or filter.
+ */
+ role_type& role()
+ {
+ return impl_.role();
+ }
+
+ /// Get the strand associated with the request (if any)
+ // Not sure if the strand concept should be kept separate or a member
+ // 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()
+ {
+ return impl_.strand();
+ }
+
+ /// Get the implementation type for the request
+ impl_type& impl() const
+ {
+ return impl_;
+ }
+
   private:
+ connection_ptr conn_;
     service_type& service_;
- role_type role_;
- int status_code_; // the what to return to the server on request completion
- status_type status_;
+ impl_type impl_;
+
+ int app_status_; // what to return to the server on request completion
+ http_status http_status_;
+ status_type request_status_;
+
+ //boost::shared_ptr<data_type> data_;
+
+ /// The data for the request is held in its own struct
+ //data_type* data_;
+
+ /// The actual data held by the request
+ //std::auto_ptr<meta_data> data_;
+
+
   };
 
+
+
+
+ //template<typename T>
+ //std::string& basic_request<T>::var<GET>(const std::string& name) const
+ //{
+ // return data_.get_var(name);
+ //}
+
+ //template<typename T>
+ //std::string& basic_request<T>::var<POST>(const std::string& name) const
+ //{
+ // return data_.post_var(name);
+ //}
+
+ //template<typename T>
+ //std::string& basic_request<T>::var<COOKIE>(const std::string& name) const
+ //{
+ // return data_.cookie_var(name);
+ //}
+
+
+ //template<>
+ //class basic_request<protocol::cgi>::meta_data
+ //{
+ //public:
+ // meta_data()
+ // : bytes_left_(-1)
+ // {}
+
+ // std::string get_var(const std::string& name)
+ // {
+ // if( get_vars_.find(name) != get_vars_.end() )
+ // return get_vars_[name];
+ // return "";
+ // }
+ // std::string post_var(const std::string& name)
+ // {
+ // assert( getenv("REQUEST_METHOD") == "POST" );
+
+ // // see if we already have the value stored
+ // if( post_vars_.find(name) != post_vars_.end() )
+ // return post_vars_[name];
+ // // else check if there's more data to read
+ // while( !read_all_data() )
+ // {
+ // switch( read_var(name) )
+ // {
+ // case true:
+ // return post_vars_[name];
+ // case false:
+ // break;
+ // default:
+ // continue;
+ // }
+ // }
+ // return "";
+ // }
+ // std::string cookie_var(const std::string& name)
+ // {
+ // return getenv(name);
+ // }
+ // std::string env_var(const std::string& name)
+ // {
+ // return getenv(name);
+ // }
+ //private:
+ // /// Read a name/value pair from stdin
+ // /**
+ // * @return true if the name (of the n/v pair) read == name
+ // */
+ // bool read_var(std::string& name)
+ // {
+ // char ch;
+ // std::string n;
+ // std::string v;
+ // while( std::cin.get(ch) && bytes_left_-- )
+ // {
+
+
+ // std::getline(std::cin, n, '=');
+ // std::getline(std::cin, v, '&');
+
+
+ // int bytes_left_;
+ // var_map get_vars_;
+ // var_map post_vars_;
+ //};
+
+ //template<>
+ //class basic_request<protocol::fcgi>::meta_data
+ //{
+ //public:
+ // std::string get_var(const std::string& name)
+ // std::string post_var(const std::string& name)
+ // std::string cookie_var(const std::string& name)
+ // std::string env_var(const std::string& name)
+ //private:
+ //};
+
+ //template<>
+ //class basic_request<protocol::scgi>::meta_data
+ //{
+ // std::string get_var(const std::string& name)
+ // std::string post_var(const std::string& name)
+ // std::string cookie_var(const std::string& name)
+ // std::string env_var(const std::string& name)
+ //};
+
 } // namespace cgi
 
-#endif // CGI_BASIC_REQUEST_HPP_INCLUDE_
+#endif // CGI_BASIC_REQUEST_HPP_INCLUDED__
 
+/*
+NOTES:
+* When a request is aborted (eg. when the client closes the connection)
+ the library can call an abort_handler() function stored in the request.
+ - The user should supply an abort_handler-derived function if they want
+ any special handling of aborted requests
+*/

Modified: sandbox/SOC/2007/cgi/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-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -31,22 +31,22 @@
       service_.cancel();
     }
 
- template<typename CGI_Request>
- void accept(CGI_Request& request)
+ template<typename CommonGatewayRequest>
+ void accept(CommonGatewayRequest& request)
     {
       boost::system::error_code ec;
       service_.accept(request, ec);
       boost::throw_error(ec);
     }
 
- template<typename CGI_Request> boost::system::error_code&
- accept(CGI_Request& request, boost::system::error_code& ec)
+ template<typename CommonGatewayRequest> boost::system::error_code&
+ accept(CommonGatewayRequest& request, boost::system::error_code& ec)
     {
       return service_.accept(request, ec);
     }
 
- template<typename CGI_Request, typename Handler>
- void async_accept(CGI_Request& request, Handler handler)
+ template<typename CommonGatewayRequest, typename Handler>
+ void async_accept(CommonGatewayRequest& request, Handler handler)
     {
       service_.async_accept(request, handler);
     }

Deleted: sandbox/SOC/2007/cgi/boost/cgi/basic_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/basic_service.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
+++ (empty file)
@@ -1,100 +0,0 @@
-#ifndef CGI_BASIC_SERVICE_HPP_INCLUDE__
-#define CGI_BASIC_SERVICE_HPP_INCLUDE__
-
-#include <boost/noncopyable.hpp>
-#include <boost/asio.hpp>
-
-namespace cgi {
-
- /*
- * This should inherit another object, such as service_base, which takes the
- * protocol as a template arguement. Things like the mutexes don't need to be
- * here for standard CGI.
- *
- * The question is whether the standard CGI service is so different from the
- * more general network-interface case that the whole class should
- * specialised for it (it probably should be).
- */
- template< typename Protocol >
- class basic_service
- : public boost::asio::io_service::service
- , private boost::noncopyable
- {
- public:
- typedef Protocol protocol;
- typedef basic_request<Protocol> request_type;
- typedef basic_service<Protocol> type;
- typedef service_options<Protocol> service_options; // just an idea
-
- template< typename Handler >
- explicit basic_service(Handler handler, service_options& opts)
- : work_io_service()
- , boost::asio::io_service::service(work_io_service_)
- , work_(new boost::asio::io_service::work(work_io_service_))
- , gateway_(this, opts.max_concurrent_connections)
- {
- }
-
- /**
- * If the user passes in an asio::io_service, set that as the 'owner'
- * instead of the (internal) work_io_service_ instance.
- */
- template< typename Handler >
- explicit basic_service( boost::asio::io_service& ios, Handler handler
- , service_options& opts )
- : work_io_service()
- , boost::asio::io_service::service(ios)
- , work_(new boost::asio::io_service::work(work_io_service_))
- , gateway_(this, opts.max_concurrent_connections)
- {
- }
-
- /// Block until a request can be returned
- /**
- * This function is called in the construction of a @code basic_request
- * @endcode, or a general @code request @endcode. It either returns a
- * valid request from the request queue immediately, or blocks on a
- * condition variable.
- *
- * Before blocking, if there are available connection slots then another
- * is @code accept() @endcode ed.
- */
- request_type& get_request()
- {
- boost::mutex::scoped_lock lk(mutex_);
- if( !request_queue_.empty() )
- {
- request_type& req = request_queue_.front();
- request_queue_.pop();
- return req;
- }
- // see gateway::accept() reference about this
- if( gateway_.accept() )
- {
- // parse the request now and return it
- }
- cond_.wait(lk);
- if( !request_queue_.empty() )
- {
- request_type& req = request_queue_.front();
- request_queue_.pop();
- return req;
- }
- }
-
- private:
- static boost::asio::io_service::id id;
- boost::asio::io_service work_io_service_;
- boost::scoped_ptr<boost::io_service::work> work_;
-
- gateway gateway_;
-
-
- boost::mutex mutex_;
- boost::condition cond_;
- };
-
-} // namespace cgi
-
-#endif // CGI_BASIC_SERVICE_HPP_INCLUDE__
-

Added: sandbox/SOC/2007/cgi/boost/cgi/detail/cgi_acceptor_service.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/detail/cgi_acceptor_service.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,12 @@
+#ifndef CGI_CGI_ACCEPTOR_SERVICE_HPP_INCLUDED__
+#define CGI_CGI_ACCEPTOR_SERVICE_HPP_INCLUDED__
+
+namespace cgi {
+namespace detail {
+
+
+
+} // namespace detail
+} // namespace cgi
+
+#endif // CGI_CGI_ACCEPTOR_SERVICE_HPP_INCLUDED__

Added: sandbox/SOC/2007/cgi/boost/cgi/detail/fcgi_acceptor_service.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/detail/fcgi_acceptor_service.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,17 @@
+#ifndef CGI_FCGI_ACCEPTOR_SERVICE_HPP_INCLUDED__
+#define CGI_FCGI_ACCEPTOR_SERVICE_HPP_INCLUDED__
+
+namespace cgi {
+namespace detail {
+
+ class fcgi_acceptor_service
+ {
+ public:
+
+ private:
+ };
+
+} // namespace detail
+} // namespace cgi
+
+#endif // CGI_FCGI_ACCEPTOR_SERVICE_HPP_INCLUDED__

Added: sandbox/SOC/2007/cgi/boost/cgi/detail/request_impl.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/detail/request_impl.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,31 @@
+#ifndef CGI_REQUEST_IMPL_HPP_INCLUDED
+#define CGI_REQUEST_IMPL_HPP_INCLUDED
+
+/// The data structure holding the request details
+
+namespace cgi {
+
+ template<typename CommonGatewayRequest>
+ class request_impl
+ {
+ public:
+ typedef std::map<std::string,std::string> header_type;
+ typedef CommonGatewayRequest request_type;
+ typedef request_type::buffer_type buffer_type;
+
+ request_impl(
+ /// Reset the object so it can be used again
+ //void reset()
+ //{
+ //
+ //}
+
+ private:
+ header_type headers_;
+ buffer_type stdin_buf_;
+ };
+
+} // namespace cgi
+
+#endif // CGI_REQUEST_IMPL_HPP_INCLUDED
+

Added: sandbox/SOC/2007/cgi/boost/cgi/detail/take_buffer.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/detail/take_buffer.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,23 @@
+// -- take_buffer.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_TAKE_BUFFER_HPP_INCLUDED__
+#define CGI_TAKE_BUFFER_HPP_INCLUDED__
+
+namespace cgi {
+ namespace detail {
+
+ /// Take a buffer from t
+ template<typename T>
+ std::streambuf* take_buffer(T& t)
+ {}
+
+ } // namespace detail
+} // namespace cgi
+
+#endif // CGI_TAKE_BUFFER_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/boost/cgi/gateway.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/gateway.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/gateway.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -1,132 +1,155 @@
-#ifndef CGI_GATEWAY_HPP_INCLUDE__
-#define CGI_GATEWAY_HPP_INCLUDE__
+// -- gateway.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_GATEWAY_HPP_INCLUDED__
+#define CGI_GATEWAY_HPP_INCLUDED__
 
 #include <boost/bind.hpp>
 #include <boost/shared_ptr.hpp>
 
 namespace cgi {
 
-/// The gateway class manages connections
-/**
- * New connections are accepted through here, via a call to accept();
- * used/corrupted connections are closed via a call to stop(conn_ptr);
- * all connections are closed via a call to stop_all().
- *
- * If you want to use the gateway after a call to stop_all(), you must
- * call reset() and pass it the maximum number of connections the gateway
- * can take.
- */
-template< typename CommonGatewayService >
-class gateway
-{
-public:
- typedef CommonGatewayService service_type;
- typedef typename CommonGatewayService::protocol_type protocol_type;
- typedef connection<protocol_type> connection_type;
- typedef boost::shared_ptr<connection_type> conn_ptr;
-
- /// Constructor
- explicit gateway(service_type& service, int max_conns)
- : service_(service)
- , acceptor_(service.io_service())
- , available_slots_(max_conns)
- {
- //accept();
- }
-
- /// Destructor
- ~gateway()
- {
- stop_all();
- }
-
- /// Start an asychronous accept
+ /// The gateway class manages connections
   /**
- * This returns false unless the connection is already established. This is
- * true with standard CGI, for example, where the connection is simply a
- * wrapper over standard input/output.
+ * New connections are accepted through here, via a call to accept();
+ * used/corrupted connections are closed via a call to stop(conn_ptr);
+ * all connections are closed via a call to stop_all().
    *
- * If there is a need to differentiate between a fail and a 'waiting' accept
- * then a tribool could be returned from here.
+ * If you want to use the gateway after a call to stop_all(), you must
+ * call reset() and pass it the maximum number of connections the gateway
+ * can take.
    */
- bool accept()
+ template< typename CommonGatewayService >
+ class gateway
   {
- if( available_slots_ > 0 )
+ public:
+ typedef CommonGatewayService service_type;
+ typedef typename CommonGatewayService::protocol_type protocol_type;
+ typedef basic_protocol_service<protocol_type> protocol_service_type;
+ typedef connection<protocol_type> connection_type;
+ typedef boost::shared_ptr<connection_base> conn_ptr;
+
+ /// Constructor
+ explicit gateway(protocol_service_type& pservice)
+ : service_(pservice)
+ //, acceptor_(pservice.io_service())
     {
- conn_ptr nc(connection_type::create());
- acceptor_.async_accept( nc->socket()
- , boost::bind( &cgi::gateway::handle_accept
- , this, nc, boost::placeholders::error
- )
- );
+ //accept();
     }
- return false;
- }
 
- void handle_accept(conn_ptr conn, boost::system::error_code& error)
- {
- if( !error )
+ /// Destructor
+ ~gateway()
     {
- start(conn);
- //accept();
+ stop_all();
     }
- }
 
- /// Cleanly start the connection
- void start(conn_ptr cptr)
- {
- connections_.insert(cptr);
- --available_slots_;
- cptr->start();
- }
+ /// Start a sychronous accept
+ /**
+ * This returns false unless the connection is already established. This is
+ * true with standard CGI, for example, where the connection is simply a
+ * wrapper over standard input/output.
+ *
+ * If there is a need to differentiate between a fail and a 'waiting' accept
+ * then a tribool could be returned from here.
+ */
+ boost::system::error_code& accept(conn_ptr conn, boost::system::error_code& ec)
+ {
+ if( service_.accept(conn, ec) )
+ {
+ connections_.insert(conn);
+ }
+
+
+ conn_ptr new_conn(connection_type::create());
+ acceptor_.accept(new_conn->socket()
+ , boost::bind(&cgi::gateway::handle_accept
+ , this, new_conn
+ , boost::placeholders::error));
+ return false;
+ }
 
- /// Cleanly stop the connection
- void stop(conn_ptr cptr)
- {
- connections_.erase(cptr);
- ++available_slots_;
- cptr->stop();
- }
+ /// Start an asynchronous accept
+ template<typename Handler>
+ void async_accept(conn_ptr conn, Handler handler)
+ {
+ service_.async_accept(handler);
+ }
 
- /// Cleanly stop all connections
- void stop_all()
- {
- available_slots_ = 0; // make sure subsequent accept()s fail
- std::for_each( connection_.begin(), connections_.end()
- , boost::bind(&gateway::stop, _1)
- );
- available_slots_ = 0;
- connections_.clear();
- }
+ /// Cleanly start the connection
+ void start(conn_ptr cptr)
+ {
+ cptr->start();
+ connections_.insert(cptr);
+ }
 
- /// Reset the gateway
- /**
- * All connections are gracefully closed and then the gateway is set up for
- * reuse.
- *
- * @param max_connections the available slots is reset to this value
- */
- void reset(int max_connections)
- {
- stop_all();
- available_slots_ = max_connections;
- }
-
- /// Increment the number of allowed connection slots
- void incr_slots(int slots = 1) { available_slots_ += slots; }
- /// Decrement the number of allowed connection slots
- void decr_slots(int slots = 1) { available_slots_ -= slots; }
-
-private:
- service_type& service_;
- acceptor<service_type> acceptor_;
- int available_slots_;
- std::set<conn_ptr> connections_;
-};
+ /// Cleanly stop the connection
+ void stop(conn_ptr cptr)
+ {
+ cptr->stop();
+ connections_.erase(cptr);
+ }
+
+ /// Cleanly stop all connections
+ void stop_all()
+ {
+ std::for_each( connection_.begin(), connections_.end()
+ , boost::bind(&gateway::stop, _1)
+ );
+ connections_.clear();
+ }
+
+ /// Reset the gateway
+ /**
+ * All connections are gracefully closed and then the gateway is set up for
+ * reuse.
+ *
+ * @param max_connections the available slots is reset to this value
+ */
+ void reset(int max_connections)
+ {
+ stop_all();
+ available_slots_ = max_connections;
+ }
+
+ private:
+ service_type& service_;
+ std::set<conn_ptr> connections_;
+ };
+
+
+
+ template<>
+ class gateway<cgi_protocol_service>
+ {
+ public:
+ gateway()
+ {
+ }
+ private:
+
+ };
+
+ /*
+ template<>
+ class gateway::acceptor<tags::fastcgi>
+ {
+ public:
+ gateway::acceptor
+ {
+ }
+ private:
+ boost::asio::ip::tcp::acceptor<
+ };
+ */
 
 } // namespace cgi
 
-#endif // CGI_GATEWAY_HPP_INCLUDE__
+#endif // CGI_GATEWAY_HPP_INCLUDED__
 
 /*
  * Notes:

Modified: sandbox/SOC/2007/cgi/boost/cgi/http/status_code.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/http/status_code.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/http/status_code.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -6,73 +6,77 @@
 // http://www.boost.org/LICENSE_1_0.txt)
 //
 ////////////////////////////////////////////////////////////////
-#ifndef CGI_HTTP_STATUS_CODES_HPP__
-#define CGI_HTTP_STATUS_CODES_HPP__
+#ifndef CGI_HTTP_STATUS_CODE_HPP_INCLUDED__
+#define CGI_HTTP_STATUS_CODE_HPP_INCLUDED__
 
 namespace cgi {
  namespace http {
 
- enum status_code
- {
- /// Success codes
- ok = 200,
- created
- accepted,
- non_authorative_information,
- no_content,
- reset_content,
- partial_content,
- multi_status,
-
- /// Redirect codes
- multiple_choices = 300,
- moved_permanently,
- found,
- see_other,
- not_modified,
- use_proxy,
- switch_proxy,
- temporary_redirect,
-
- /// Domain error codes
- bad_request = 400,
- unauthorized,
- payment_required,
- forbidden,
- not_found,
- method_not_allowed,
- not_acceptable,
- proxy_authentication_required,
- request_timeout,
- conflict,
- gone,
- length_required,
- precondition_failed,
- request_entity_too_large,
- request_uri_too_long,
- unsupported_media_type,
- request_range_not_satisfiable,
- expectation_failed,
- unprocessable_entity = 422,
- locked,
- failed_dependency,
- unordered_collection,
- upgrade_required,
- retry_with = 449,
-
- /// Internal error codes
- internal_server_error = 500,
- not_implemented,
- bad_gateway,
- service_unavailable,
- gateway_timeout,
- http_version_not_supported,
- insufficient_storage,
- bandwidth_limit_exceeded = 509
- };
+ /// Standard HTTP status codes
+ /**
+ * See http://tools.ietf.org/html/rfc2616#section-10
+ */
+ enum status_code
+ {
+ /// Success codes
+ ok = 200,
+ created
+ accepted,
+ non_authorative_information,
+ no_content,
+ reset_content,
+ partial_content,
+ multi_status,
+
+ /// Redirect codes
+ multiple_choices = 300,
+ moved_permanently,
+ found,
+ see_other,
+ not_modified,
+ use_proxy,
+ switch_proxy,
+ temporary_redirect,
+
+ /// Domain error codes
+ bad_request = 400,
+ unauthorized,
+ payment_required,
+ forbidden,
+ not_found,
+ method_not_allowed,
+ not_acceptable,
+ proxy_authentication_required,
+ request_timeout,
+ conflict,
+ gone,
+ length_required,
+ precondition_failed,
+ request_entity_too_large,
+ request_uri_too_long,
+ unsupported_media_type,
+ request_range_not_satisfiable,
+ expectation_failed,
+ unprocessable_entity = 422,
+ locked,
+ failed_dependency,
+ unordered_collection,
+ upgrade_required,
+ retry_with = 449,
+
+ /// Internal error codes
+ internal_server_error = 500,
+ not_implemented,
+ bad_gateway,
+ service_unavailable,
+ gateway_timeout,
+ http_version_not_supported,
+ insufficient_storage,
+ bandwidth_limit_exceeded = 509
+ };
 
  } // namespace http
 } // namespace cgi
 
-#endif // CGI_HTTP_STATUS_CODES_HPP__
+#endif // CGI_HTTP_STATUS_CODE_INCLUDED_HPP__
 

Added: sandbox/SOC/2007/cgi/boost/cgi/logger.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/logger.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,62 @@
+// -- logger.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_LOGGER_HPP_INCLUDED__
+#define CGI_LOGGER_HPP_INCLUDED__
+
+namespace cgi {
+
+ /// The logger class: a helper class for writing to requests log streams
+ /**
+ * This simply initialises a cgi::ostream to write logging info to a request.
+ *
+ * The reply class is analogous to this except this works on the request's
+ * error output rather than the standard output.
+ */
+ class logger
+ : public ostream
+ {
+ public:
+ /// Default constructor
+ explicit logger()
+ {
+ }
+
+ /// Construct with a particular buffer
+ /**
+ * Takes a buffer and uses it internally, does nothing with it on
+ * destruction.
+ */
+ logger(std::streambuf* buf)
+ : ostream(buf)
+ {
+ }
+
+ /// Construct, taking a buffer from an external source
+ /**
+ * Gets a buffer from the request/protocol service held by the request.
+ *
+ * <strike>
+ * Takes a buffer from T (can be a model of ProtocolService or
+ * CommonGatewayRequest) to use internally.
+ * </strike>
+ */
+ template<typename CommonGatewayRequest>
+ logger(CommonGatewayRequest& req)
+ : ostream(req)
+ {
+ }
+
+ ~logger()
+ {
+ }
+ };
+
+} // namespace cgi
+
+#endif // CGI_LOGGER_HPP_INCLUDED__

Added: sandbox/SOC/2007/cgi/boost/cgi/ostream.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/ostream.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,304 @@
+// -- ostream.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_OSTREAM_HPP_INCLUDED__
+#define CGI_OSTREAM_HPP_INCLUDED__
+
+/*********************************
+ISSUES:
+-------
+* async_flush()
+The other flush() functions clear the buffer after flushing the data to the
+request. It's trickier with async_flush(), but for now the buffer is still
+cleared after the flush completes. This means you can't write to the ostream
+until an async_flush completes; that's probably true of any async operation
+however so it seems a reasonable restriction.
+
+* Is ostream the best name for this? request_ostream?
+
+* This class could do more: the functions basic_request<>::write() could write
+to the request unbuffered. ie. a write call would instantly wrap the supplied
+buffer in suitable headers and send it straight away, rather than buffering it
+first. That would also mean the ostream class is of more use than it is now.
+
+* This should probably derive from std::ostream, as users would probably expect
+that.
+*********************************/
+
+#include <ostream>
+
+#include "detail/take_buffer.hpp"
+
+namespace cgi {
+
+ /// The ostream class: a stream interface for writing to requests
+ /**
+ * This is simply a wrapper around an ostream with a few extra details that
+ * aid writing to a request's output or error sinks.
+ *
+ * This is a generalisation of the cgi::reply and cgi::logger classes.
+ */
+ class ostream
+ // derive from std::ostream? (yes, basically)
+ {
+ public:
+ /// Default constructor
+ explicit ostream(int destination = tags::stdout)
+ : request_(NULL)
+ , destination_(destination)
+ {
+ }
+
+ /// Construct with a particular buffer
+ /**
+ * Takes the buffer and uses it internally, does nothing with it on
+ * destruction.
+ */
+ ostream(std::streambuf* buf, int destination = tags::stdout)
+ : ostream_(buf)
+ , request_(NULL)
+ , destination_(destination)
+ {
+ }
+
+ /// Construct, taking a buffer from an external source
+ /**
+ * Gets a buffer from the request/protocol service held by the request.
+ * <strike>
+ * Takes a buffer from T (can be a model of ProtocolService or
+ * CommonGatewayRequest) to use internally.
+ * </strike>
+ */
+ template<typename CommonGatewayRequest>
+ ostream(CommonGatewayRequest& req, int destination = tags::stdout)
+ : ostream_(detail::take_buffer(req))
+ , request_(&req)
+ , destination_(destination)
+ {
+ }
+
+ ~ostream()
+ {
+ if( request_ ) send();
+ }
+
+ void clear()
+ {
+ ostream_.clear();
+ }
+
+ // provide this too?
+ std::size_t write(const char* str, std::size_t len)
+ {
+ return ostream_.write(str, len);
+ }
+
+ std::size_t write(const std::string& str)
+ {
+ return ostream_.write(str);
+ }
+
+ template<typename MutableBufferSequence>
+ std::size_t write(MutableBufferSequence& buf)
+ {
+ return ostream_.write(buf.data(), buf.size());
+ }
+
+ /// Synchronously flush the data to the current request
+ /**
+ * If there is no error, the buffer is cleared.
+ */
+ void flush()
+ {
+ BOOST_ASSERT(request_ != NULL);
+ flush(*request_);
+ }
+
+ /// Synchronously flush the data to the supplied request
+ /**
+ * This call uses throwing semantics. ie. an exception will be thrown on
+ * any failure.
+ * If there is no error, the buffer is cleared.
+ */
+ template<typename CommonGatewayRequest>
+ void flush(CommonGatewayRequest& req)
+ {
+ req.write(ostream_.rdbuf());
+ clear();
+ }
+
+ /// Synchronously flush the data via the supplied request
+ /**
+ * This call uses error_code semantics. ie. ec is set if an error occurs.
+ * If there is no error, the buffer is cleared.
+ */
+ template<typename CommonGatewayRequest>
+ boost::system::error_code& flush(CommonGatewayRequest& req
+ , boost::system::error_code& ec)
+ {
+ if(!req.write(ostream_.rdbuf(), ec))
+ clear();
+ return ec;
+ }
+
+ template<typename Handler>
+ class flush_handler
+ {
+ public:
+ flush_handler(ostream& os, Handler handler)
+ : ostream_(os)
+ , handler_(handler)
+ {
+ }
+
+ void operator()(boost::system::error_code& ec)
+ {
+ if( !ec )
+ ostream_.clear();
+ handler(ec);
+ }
+ private:
+ ostream& ostream_;
+ Handler handler_;
+ };
+
+ /// Asynchronously flush the data through the supplied request
+ /**
+ * If there is no error, the buffer is cleared *after* the write has
+ * finished.
+ */
+ template<typename CommonGatewayRequest, typename Handler>
+ void async_flush(CommonGatewayRequest& req, Handler handler)
+ {
+ req.async_write(ostream_.rdbuf()
+ , flush_handler<Handler>(*this, handler
+ , boost::arg<1>)));
+ }
+
+
+
+ /// Synchronously send the reply to the default request
+ /**
+ * Note: The data in the stream isn't cleared after this call, but the
+ * request held in the ostream is removed. ie. send() can't be called
+ * twice without an arguement (unless you add another request - something
+ * not possible yet).
+ */
+ void send()
+ {
+ BOOST_ASSERT(request_ != NULL);
+ send(*request_);
+ request_ = NULL;
+ }
+
+ /// Synchronously send the reply to the default request
+ /**
+ * Note: The data in the stream isn't cleared after this call. If the send
+ * is sucessful, the request held in the ostream is removed. ie. send()
+ * can't be called twice without an arguement (unless you add another
+ * request - something not possible yet).
+ */
+ boost::system::error_code& send(boost::system::error_code& ec)
+ {
+ BOOST_ASSERT(request_ != NULL);
+ if(!send(*request_, destination_, ec))
+ request_ = NULL;
+ return ec;
+ }
+
+ /// Synchronously send the data via the supplied request
+ /**
+ * This call uses throwing semantics. ie. an exception will be thrown on
+ * any failure.
+ * Note: The data in the stream isn't cleared after this call.
+ */
+ template<typename CommonGatewayRequest>
+ void send(CommonGatewayRequest& req)
+ {
+ req.write(ostream_.rdbuf(), destination_);
+ req.set_status(http_status_);
+ }
+
+ /// Synchronously send the data via the supplied request
+ /**
+ * This call uses error_code semantics. ie. ec is set if an error occurs.
+ * Note: The data in the stream isn't cleared after this call.
+ */
+ template<typename CommonGatewayRequest>
+ boost::system::error_code& send(CommonGatewayRequest& req
+ , boost::system::error_code& ec)
+ {
+ req.write(ostream_.rdbuf(), destination_, ec);
+ req.set_status(http_status_);
+ }
+
+ template<typename CommonGatewayRequest, typename Handler>
+ class send_handler
+ {
+ public:
+ send_handler(CommonGatewayRequest& req, http::status_code status
+ , Handler handler)
+ : request_(req)
+ , http_status_(status)
+ , handler_(handler)
+ {
+ }
+
+ void operator()(boost::system::error_code ec)
+ {
+ if( !ec )
+ {
+ request_.set_status(http_status_);
+
+ }
+ private:
+ CommonGatewayRequest& request_;
+ int http_status_;
+ Handler handler_;
+ };
+
+ /// Asynchronously send the data through the supplied request
+ /**
+ * Note: The data in the stream isn't cleared after this call.
+ */
+ template<typename CommonGatewayRequest, typename Handler>
+ void async_send(CommonGatewayRequest& req, Handler handler)
+ {
+ req.async_write(ostream_.rdbuf(), destination_
+ , send_handler<CommonGatewayRequest
+ , Handler>(req, http_status_, handler));
+ }
+
+ /// Get the buffer associated with the
+ std::streambuf* rdbuf() const { return ostream_.rdbuf(); }
+
+ void set_status(http::status_code& num) { http_status_ = num; }
+ http::status_code& get_status() const { return http_status_; }
+
+ private:
+ http::status_code http_status_;
+ std::ostream ostream_;
+ int destination_;
+
+ /// The request associated with the ostream; can be NULL
+ request_base* request_;
+
+ friend template<typename T> ostream& operator<<(ostream&, const T&);
+ };
+
+ /// Operator<< overload for basic outputting ability
+ template<typename T>
+ ostream& operator<<(ostream& rep, const T& t)
+ {
+ ostream_<< t;
+ return rep;
+ }
+
+} // namespace cgi
+
+#endif // CGI_OSTREAM_HPP_INCLUDED__

Added: sandbox/SOC/2007/cgi/boost/cgi/protocol_traits.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/protocol_traits.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,18 @@
+#ifndef CGI_PROTOCOL_TRAITS_HPP_INCLUDED__
+#define CGI_PROTOCOL_TRAITS_HPP_INCLUDED__
+
+namespace cgi {
+
+ template<Protocol>
+ struct protocol_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
+ };
+
+} // namespace cgi
+
+#endif // CGI_PROTOCOL_TRAITS_HPP_INCLUDED__

Added: sandbox/SOC/2007/cgi/boost/cgi/protocols.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/protocols.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,23 @@
+// -- protocols.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_PROTOCOLS_HPP_INCLUDED__
+#define CGI_PROTOCOLS_HPP_INCLUDED__
+
+namespace cgi {
+ namespace protocols {
+
+ struct cgi;
+ struct async_cgi; // acgi?
+ struct fcgi;
+ struct scgi;
+
+ } // namespace protocols
+} // namespace cgi
+
+#endif // CGI_PROTOCOLS_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/boost/cgi/reply.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/reply.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/reply.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -15,162 +15,50 @@
 
 namespace cgi {
 
+ /// The reply class: a helper for replying to requests
+ /**
+ * This simply initialises a cgi::ostream to write replies to a request.
+ *
+ * The logger class is analogous to this except this works on the request's
+ * standard output rather than the error output.
+ */
   class reply
+ : public ostream
   {
   public:
     /// Default constructor
- /**
- * Creates a shared pointer of a buffer to use internally.
- */
     explicit reply()
- : ostream_(detail::make_buffer())
     {
     }
 
     /// Construct with a particular buffer
     /**
- * Takes the buffer and uses it internally, does nothing with it on
+ * Takes a buffer and uses it internally, does nothing with it on
      * destruction.
      */
     reply(std::streambuf* buf)
- : ostream_(buf)
+ : ostream(buf)
     {
     }
 
     /// Construct, taking a buffer from an external source
     /**
- * Takes a buffer from T (can be a model of ProtocolService or CGI_Request)
- * to use internally.
- */
- template<typename T>
- reply(T& t)
- : ostream_(t.make_buffer())
+ * Gets a buffer from the request/protocol service held by the request.
+ *
+ * <strike>
+ * Takes a buffer from T (can be a model of ProtocolService or
+ * CommonGatewayRequest) to use internally.
+ * </strike>
+ */
+ template<typename CommonGatewayRequest>
+ reply(CommonGatewayRequest& req)
+ : ostream(req)
     {
     }
 
     ~reply()
     {
     }
-
- std::size_t write(
-
- template<typename MutableBufferSequence>
- std::size_t write(MutableBufferSequence& buf)
- {
- return ostream_.write(buf.data(), buf.size());
- }
-
-
- /// Synchronously flush the reply via the supplied request
- /**
- * This call uses throwing semantics. ie. an exception will be thrown on
- * any failure.
- */
- template<typename CGI_Request>
- void flush(CGI_Request& req)
- {
- req.write(ostream_.rdbuf());
- }
-
- /// Synchronously flush the reply via the supplied request
- /**
- * This call uses error_code semantics. ie. ec is set if an error occurs.
- */
- template<typename CGI_Request>
- boost::system::error_code& flush(CGI_Request& req
- , boost::system::error_code& ec)
- {
- return req.write(ostream_.rdbuf(), ec);
- }
-
- /// Asynchronously flush the reply through the supplied request
- template<typename CGI_Request, typename Handler>
- void async_flush(CGI_Request& req, Handler handler)
- {
- req.async_write(ostream_.rdbuf(), handler));
- }
-
- /// Synchronously send the reply via the supplied request
- /**
- * This call uses throwing semantics. ie. an exception will be thrown on
- * any failure.
- */
- template<typename CGI_Request>
- void send(CGI_Request& req)
- {
- req.write(ostream_.rdbuf());
- req.end(
- }
-
- /// Synchronously send the reply via the supplied request
- /**
- * This call uses error_code semantics. ie. ec is set if an error occurs.
- */
- template<typename CGI_Request>
- boost::system::error_code& send(CGI_Request& req
- , boost::system::error_code& ec)
- {
- req.write(ostream_.rdbuf(), ec);
- req.end(status_
- }
-
- template<typename CGI_Request, typename Handler>
- class send_handler
- {
- public:
- send_handler(CGI_Request& req, int status, Handler handler)
- : request_(req)
- , status_(status)
- , handler_(handler)
- {
- }
-
- void operator()(boost::system::error_code ec)
- {
- if( !ec )
- {
- request_.close(
-
- }
- private:
- CGI_Request& request_;
- int status_;
- Handler handler_;
- };
-
- /// Asynchronously send the reply through the supplied request
- template<typename CGI_Request, typename Handler>
- void async_send(CGI_Request& req, Handler handler)
- {
- req.async_write(ostream_.rdbuf()
- , send_handler<CGI_Request
- , Handler>(req, status_, handler));
- }
-
- /// Operator<< overload for basic outputting ability
- template<typename T>
- reply& operator<<(reply& rep, const T& t)
- {
- ostream_<< t;
- return rep;
- }
-
- std::streambuf* rdbuf() const { return ostream_.rdbuf(); }
-
- void status(int num)
- {
- status_ = num;
- //data_.set_status(num);
- }
-
- int status() const { return status_; }//data_.get_status(); }
-
- private:
- int status_;
- std::ostream ostream_;
-
- //template<typename T>
- //friend reply& operator<<(reply&, const T&);
   };
 
 } // namespace cgi

Modified: sandbox/SOC/2007/cgi/boost/cgi/request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/boost/cgi/request.hpp (original)
+++ sandbox/SOC/2007/cgi/boost/cgi/request.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -1,3 +1,104 @@
+<<<<<<< .mine
+//
+// request.hpp
+// -----------
+//
+// Copyright (c) 2007 Darren Garvey
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef CGI_REQUEST_HPP_INCLUDED__
+#define CGI_REQUEST_HPP_INCLUDED__
+
+#include <boost/noncopyable.hpp>
+#include "request_base.hpp"
+#include "basic_cgi_service_fwd.hpp"
+#include "basic_cgi_request_fwd.hpp"
+
+namespace cgi {
+
+/// The 'request' class that is the user's main entry point into this library
+/**
+ * By default the class will work with 'any' service type to provide uniform
+ * access to requests handled by any cgi::service type. If no service is
+ * provided to the constructor, the object is assumed to be a standard cgi
+ * object.
+ *
+ * @par Example
+ * @code
+ * void f()
+ * {
+ * cgi::request r; // standard cgi object
+ * }
+ *
+ * void g()
+ * {
+ * cgi::fcgi_service service; // fastcgi service
+ * cgi::request(service); // fastcgi request
+ * }
+ * @endcode
+ *
+ * If runtime linkage is insufficient, a macro can be defined to instead use
+ * compile-time linking. Available macros:
+ *
+ * - @code BOOST_CGI_IMPLICIT_CGI @endcode -> standard cgi
+ * - @code BOOST_CGI_IMPLICIT_FCGI @endcode -> fastcgi
+ *
+ * {{can modern compilers optimize away the runtime element of the general
+ * version of request?}}
+ */
+
+#if defined(BOOST_CGI_IMPLICIT_CGI)
+ typedef basic_cgi_request<protocol::cgi> request;
+#elif defined(BOOST_CGI_IMPLICIT_FCGI)
+ typedef basic_cgi_request<protocol::fcgi> request;
+#elif defined(BOOST_CGI_IMPLICIT_SCGI)
+# error "SCGI driver not implemented yet"
+#else
+
+ // Below is the 'general' request class
+ class request
+ : private boost::noncopyable
+ {
+ boost::shared_ptr<request_base> impl_;
+ public:
+ template< typename Protocol, typename Allocator = std::allocator() >
+ explicit request(basic_cgi_service<Protocol, Allocator>& service)
+ : impl_(&service.get_request())
+ {
+ }
+
+ template< typename ServiceType, typename Allocator = std::allocator() >
+ request(basic_cgi_request<ServiceType, Allocator>& request)
+ : impl_(&request)
+ {
+ }
+
+ template< typename Allocator = std::allocator() >
+ request()
+ : impl_(new basic_cgi_request< basic_cgi_service<protocol::cgi, Allocator>
+ , Allocator
+ > request
+ )
+ {
+ }
+
+ void end( int return_code )
+ {
+ impl_->end(return_code);
+ }
+
+ // more functions
+ };
+
+} // namespace cgi
+
+#endif // CGI_REQUEST_HPP_INCLUDED__
+
+=======
 //
 // request.hpp
 // -----------
@@ -97,3 +198,4 @@
 
 #endif // __CGI_REQUEST_HPP_INCLUDE_
 
+>>>>>>> .r7365

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-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -27,8 +27,8 @@
      * Check if there is a waiting request in the queue. If not, accept a
      * connection, and associate it with the request.
      */
- template<typename CGI_Request> boost::system::error_code&
- accept(CGI_Request& request, boost::system::error_code& ec)
+ template<typename CommonGatewayRequest> boost::system::error_code&
+ accept(CommonGatewayRequest& request, boost::system::error_code& ec)
     {
       boost::thread::mutex::scoped_lock lk(io_service_.mutex_);
       if( !io_service_.request_queue_.empty() )

Added: sandbox/SOC/2007/cgi/boost/cgi/request_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/boost/cgi/request_type.hpp 2007-07-05 20:17:22 EDT (Thu, 05 Jul 2007)
@@ -0,0 +1,14 @@
+#ifndef CGI_REQUEST_TYPE_HPP_INCLUDED__
+#define CGI_REQUEST_TYPE_HPP_INCLUDED__
+
+namespace cgi {
+
+ enum request_type
+ { responder
+ , authorizer
+ , filter
+ };
+
+} // namespace cgi
+
+#endif // CGI_REQUEST_TYPE_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