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