|
Boost-Commit : |
From: lists.drrngrvy_at_[hidden]
Date: 2008-03-31 23:32:21
Author: drrngrvy
Date: 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
New Revision: 43980
URL: http://svn.boost.org/trac/boost/changeset/43980
Log:
Merged revisions 43976-43979 via svnmerge from
https://svn.boost.org/svn/boost/sandbox/SOC/2007/cgi/trunk
........
r43977 | drrngrvy | 2008-04-01 04:23:32 +0100 (Tue, 01 Apr 2008) | 1 line
basic_request<>::boundary_marker() is gone now.
........
r43978 | drrngrvy | 2008-04-01 04:24:30 +0100 (Tue, 01 Apr 2008) | 1 line
Cosmetic updates.
........
r43979 | drrngrvy | 2008-04-01 04:29:41 +0100 (Tue, 01 Apr 2008) | 7 lines
* Moved multipart/form-data parsing into separate form_parser class. It's only a crude start, but it works as well as before (maybe very slightly better).
* Emptied request_ostream.hpp (should be gone soon).
* Fixed connections/stdio.hpp - the last updates didn't actually use it properly so the problems with it didn't show up... Should work fine now, slightly better than when using std::cin functions.
........
Properties modified:
sandbox/SOC/2007/cgi/branches/release/ (props changed)
Text files modified:
sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_client.hpp | 18 +
sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_request.hpp | 10
sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_sync_io_object.hpp | 1
sandbox/SOC/2007/cgi/branches/release/boost/cgi/common/form_parser.hpp | 407 ++++++++++++++++++++++++++++++++++++++-
sandbox/SOC/2007/cgi/branches/release/boost/cgi/connections/stdio.hpp | 44 ++--
sandbox/SOC/2007/cgi/branches/release/boost/cgi/detail/cgi_service_impl_base.hpp | 184 ++++++-----------
sandbox/SOC/2007/cgi/branches/release/boost/cgi/fcgi/request_service.hpp | 16
sandbox/SOC/2007/cgi/branches/release/boost/cgi/request_ostream.hpp | 7
sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/cookie_game/main.cpp | 4
sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/echo/main.cpp | 3
sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/Jamfile.v2 | 10
sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/echo/Jamfile.v2 | 4
sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/hello_world/main.cpp | 3
13 files changed, 520 insertions(+), 191 deletions(-)
Modified: sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_client.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_client.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_client.hpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -17,6 +17,7 @@
#include "boost/cgi/http/status_code.hpp"
#include "boost/cgi/connections/tcp_socket.hpp"
+
namespace cgi {
namespace common {
@@ -110,9 +111,20 @@
std::size_t read_some(const MutableBufferSequence& buf
, boost::system::error_code& ec)
{
- std::size_t bytes_read = connection_->read_some(buf, ec);
- bytes_left_ -= bytes_read;
- return bytes_left_ > 0 ? bytes_read : (bytes_read + bytes_left_);
+ //if (boost::asio::buffer_size(buf) > bytes_left_)
+ //{
+ std::size_t bytes_read = connection_->read_some(buf, ec);
+ bytes_left_ -= bytes_read;
+ if (ec == boost::asio::error::eof)
+ ec = boost::system::error_code();
+ return bytes_left_ > 0 ? bytes_read : (bytes_read + bytes_left_);
+ //}
+ //else
+ //{
+ //
+ // ec = boost::asio::error::eof;
+ // return 0;
+ //}
}
/// Asynchronously write some data to the client.
Modified: sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_request.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_request.hpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -642,12 +642,6 @@
this->service.set_status(this->implementation, status);
}
- // The boundary marker for multipart forms (this is likely a transient function).
- std::string boundary_marker()
- {
- return this->implementation.boundary_marker;
- }
-
map_type& operator[](common::data_source source)
{
switch(source)
@@ -657,9 +651,11 @@
case cookie_data: return this->implementation.cookie_vars_;
case env_data: return this->implementation.env_vars_;
case form_data:
+ default:
std::string rm( request_method() );
- if (rm == "GET") return this->implementation.get_vars_;
+ if (rm == "GET") return this->implementation.get_vars_;
else if (rm == "POST") return this->implementation.post_vars_;
+ else return this->implementation.env_vars_;
}
}
};
Modified: sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_sync_io_object.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_sync_io_object.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/boost/cgi/basic_sync_io_object.hpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -26,7 +26,6 @@
protected:
explicit basic_sync_io_object()
{
- std::cerr<< "Hello";
service.construct(implementation);
}
Modified: sandbox/SOC/2007/cgi/branches/release/boost/cgi/common/form_parser.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/boost/cgi/common/form_parser.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/boost/cgi/common/form_parser.hpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -6,39 +6,420 @@
#include <set>
#include <vector>
#include <string>
+#include <boost/regex.hpp>
#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
#include <boost/function.hpp>
+#include <boost/system/error_code.hpp>
#include "boost/cgi/common/form_part.hpp"
+#include "boost/cgi/basic_client.hpp"
namespace cgi {
namespace detail {
- /// Destined for greater things than an implementation detail.
+ /// Destined for better things than an implementation detail (hopefully).
+ template<typename RequestImplType>
class form_parser
{
public:
- typedef
- boost::function<
- std::size_t (
- const boost::asio::mutable_buffer&
- , boost::system::error_code& )
- >
- callback_type;
+ //typedef
+ // boost::function<
+ // std::size_t (
+ // const mutable_buffers_type&
+ // , boost::system::error_code& )
+ // >
+ //callback_type;
- typedef std::vector<char> buffer_type;
+ typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
+ typedef std::vector<char> buffer_type;
+ typedef ::cgi::common::map map_type;
- form_parser()
+ typedef RequestImplType implementation_type;
+
+ implementation_type& impl_;
+ std::size_t& bytes_left_;
+ buffer_type::iterator pos_;
+ bool& stdin_data_read_;
+ std::size_t offset_;
+
+ std::string boundary_marker;
+ std::list<std::string> boundary_markers;
+ std::vector<common::form_part> form_parts_;
+
+ form_parser(implementation_type& impl)
+ : impl_(impl)
+ , bytes_left_(impl.characters_left_)
+ , stdin_data_read_(impl.stdin_data_read_)
+ , offset_(0)
+ {
+ }
+ /*
+ form_parser(std::size_t& cl, buffer_type& buf, map_type& m
+ , unsigned int& client_bytes, bool& sp, bool& sdr
+ , std::string ct, callback_type const & cb)
+ : bytes_left_(cl)
+ , buf_(buf)
+ , map_(m)
+ , client_bytes_left_(client_bytes)
+ , stdin_parsed_flag_(sp)
+ , stdin_data_read_(sdr)
+ , offset_(0)
+ , content_type_(ct)
+ //, client_(c)
+ , callback_(cb)
{
}
+ */
+
+ mutable_buffers_type prepare(std::size_t size)
+ {
+ std::size_t bufsz(impl_.buf_.size());
+ impl_.buf_.resize(bufsz + size);
+ return boost::asio::buffer(&impl_.buf_[bufsz], size);
+ }
+
+ std::string buffer_string()
+ {
+ return std::string(impl_.buf_.begin() + offset_, impl_.buf_.end());
+ }
+ boost::system::error_code
+ parse(boost::system::error_code& ec)
+ {
+ parse_boundary_marker(ec);
+ //parse_one_form_part(impl, ec);
+
+ move_to_start_of_first_part(ec);
+
+ if (ec == boost::asio::error::eof) {
+ return boost::system::error_code();
+ }else
+ if (ec)
+ return ec;
+
+ do {
+ parse_form_part(ec);
+ }while( !impl_.stdin_parsed_
+ && impl_.client_.bytes_left() != 0
+ );//&& ec != boost::asio::error::eof );
+
+ return ec;
+ }
+
+ boost::system::error_code
+ parse_form_part(boost::system::error_code& ec)
+ {
+ if (!parse_form_part_meta_data(ec)
+ && !parse_form_part_data(ec))
+ return ec;
+
+ return ec;
+ }
+
+ boost::system::error_code
+ parse_form_part_data(boost::system::error_code& ec)
+ {
+ std::string regex("^(.*?)" // the data
+ "\\x0D\\x0A" // CR LF
+ "--" "(");
+ if (boundary_markers.size() > 1)
+ {
+ std::list<std::string>::iterator i(boundary_markers.begin());
+ regex = regex + "(?:" + *i + ")";
+ ++i;
+ for(; i != boundary_markers.end(); ++i)
+ {
+ regex = regex + "|(?:" + *i + ")";
+ }
+ }
+ else
+ {
+ regex += *boundary_markers.begin();
+ }
+
+ regex += ")(--)?[ ]*\\x0D\\x0A";
+ boost::regex re(regex);
+
+ typedef buffer_type::iterator buffer_iter;
+
+ boost::match_results<buffer_iter> matches;
+
+ std::size_t offset = offset_;
+
+ //int runs = 0;
+ buffer_iter begin(impl_.buf_.begin() + offset);
+ buffer_iter end(impl_.buf_.end());
+
+ for(;;)
+ {
+ if (!boost::regex_search(begin, end, matches, re
+ , boost::match_default
+ | boost::match_partial))
+ {
+ return boost::system::error_code(345, boost::system::system_category);
+ }
+ else
+ {
+ if (matches[1].matched)
+ {
+ form_parts_.back().buffer_
+ // = boost::range_iterator<;
+ = std::make_pair(matches[1].first, matches[1].second);
+ impl_.post_vars_[form_parts_.back().name] = matches[1];
+ offset_ = offset + matches[0].length();
+ pos_ = matches[0].second;
+
+ if (matches[3].matched)
+ impl_.stdin_parsed_ = true;
+ return ec;
+ }
+ else
+ {
+ std::size_t bytes_read = impl_.client_.read_some(prepare(64), ec);
+
+ if (bytes_read == 0)
+ {
+ stdin_data_read_ = true;
+ return ec;
+ }
+
+ begin = impl_.buf_.begin() + offset;
+ end = impl_.buf_.end();
+
+ if (ec)
+ return ec;
+ }
+ }
+ }
+
+ return ec;
+ }
+
+ boost::system::error_code
+ parse_form_part_meta_data(boost::system::error_code& ec)
+ {
+ // Oh dear this is ugly. The move to Boost.Spirit will have to be sooner than planned.
+ // (it's a nested, recursive pattern, which regexes don't suit, apparently)
+ boost::regex re( "(?:" // [IGNORE] the line may be empty, as meta-data is optional
+ "^"
+ "([-\\w]+)" // name
+ ":[ ^]*" // separator
+ "([-/\\w]+)" // optional(?) value
+ ""
+ "(?:"
+ ";"
+ "[ ]*" // additional name/value pairs (don't capture)
+ "([-\\w]+)" // name
+ "[ \\x0D\\x0A]*=[ \\x0D\\x0A]*" // separator
+ "(?:\"?([-.\\w]*)\"?)" // value may be empty
+ ")?"
+ "(?:"
+ ";"
+ "[ ]*" // additional name/value pairs (don't capture)
+ "([-\\w]+)" // name
+ "[ \\x0D\\x0A]*=[ \\x0D\\x0A]*" // separator
+ "(?:\"?([-.\\w]*)\"?)" // value may be empty
+ ")?" // mark the extra n/v pairs optional
+ "\\x0D\\x0A"
+ ")"
+ "(?:"
+ "([-\\w]+)" // name
+ ":[ ^]*" // separator
+ "([-/\\w]+)" // optional(?) value
+ ""
+ "(?:"
+ ";"
+ "[ ]*" // additional name/value pairs (don't capture)
+ "([-\\w]+)" // name
+ "[ \\x0D\\x0A]*=[ \\x0D\\x0A]*" // separator
+ "(?:\"?([-.\\w]*)\"?)" // value may be empty
+ ")?"
+ "(?:"
+ ";"
+ "[ ]*" // additional name/value pairs (don't capture)
+ "([-\\w]+)" // name
+ "[ \\x0D\\x0A]*=[ \\x0D\\x0A]*" // separator
+ "(?:\"?([-.\\w]*)\"?)" // value may be empty
+ ")?" // mark the extra n/v pairs optional
+ "\\x0D\\x0A" // followed by the end of the line
+ ")?"
+ "(\\x0D\\x0A)"); // followed by the 'header termination' line
+
+ typedef buffer_type::iterator buffer_iter;
+
+ boost::match_results<buffer_iter> matches;
+
+ std::size_t offset = offset_;
+ pos_ = impl_.buf_.begin();
+ int runs = 0;
+
+ std::size_t bytes_read = 0;
+ for(;;)
+ {
+ buffer_iter begin(impl_.buf_.begin() + offset);
+ buffer_iter end(impl_.buf_.end());
+
+ if (!boost::regex_search(begin, end, matches, re
+ , boost::match_default | boost::match_partial))
+ {
+ impl_.stdin_parsed_ = true;
+ return ec;
+ }
+ if (matches[0].matched)
+ {
+ common::form_part part;
+ for ( unsigned int i = 1
+ ; i < matches.size()
+ && matches[i].matched
+ && !matches[i].str().empty()
+ ; i+=2)
+ {
+ if (matches[i].str() == "name")
+ {
+ part.name = matches[i+1];
+ }
+ else
+ {
+ part.meta_data_[matches[i]]
+ = std::make_pair(matches[i+1].first, matches[i+1].second);
+ }
+ form_parts_.push_back(part);
+ }
+
+ if (matches[13].str() == "\r\n")
+ {
+ offset_ = offset + matches[0].length();
+ offset += matches[0].length();
+ pos_ = matches[0].second;
+
+ return ec;
+ }
+ else
+ {
+ throw std::runtime_error("Invalid POST data (header wasn't terminated as expected)");
+ }
+
+ }else{
+ bytes_read = impl_.client_.read_some(prepare(64), ec);
+ if (ec)
+ return ec;
+ if (++runs > 40)
+ {
+ std::cerr<< "Done 40 runs; bailing out" << std::endl;
+ break;
+ }
+ }
+ }
+
+ return ec;
+ }
+
+ boost::system::error_code
+ move_to_start_of_first_part(boost::system::error_code& ec)
+ {
+ boost::regex re("((?:.*)?" // optional leading characters
+ //"(?:\\x0D\\x0A)|^" // start of line
+ "[\\x0D\\x0A^]*?"
+ "("
+ "--" + boundary_markers.front() + // two dashes and our marker
+ ")"
+ "(--)?" // optional two dashes (not sure if this is allowed)
+ " *\\x0D\\x0A)");
+ // on the first marker.
+
+ typedef buffer_type::iterator buffer_iter;
+ //std::cerr<< "Regex := " << re << std::endl;
+
+ boost::match_results<buffer_iter> matches;
+
+ // get data into our buffer until we reach the first boundary marker.
+ int runs = 0;
+ std::size_t offset = 0;
+ std::size_t bytes_read = 0;
+ for(;;)
+ {
+ bytes_read = impl_.client_.read_some(prepare(32), ec);
+ if (ec || (bytes_read == 0))
+ return ec;
+ buffer_iter begin(impl_.buf_.begin());// + offset);
+ buffer_iter end(impl_.buf_.end());
+ if (!boost::regex_search(begin, end //impl.buf_.begin(), impl.buf_.end()
+ , matches, re, boost::match_default | boost::match_partial))
+ {
+ offset = impl_.buf_.size();
+ continue;
+ }
+ else
+ {
+ if (matches[2].matched)
+ {
+ impl_.buf_.erase(impl_.buf_.begin(), matches[0].second);
+ offset_ = 0;
+ pos_ = impl_.buf_.begin();
+ return ec;
+ }
+ else
+ {
+ if (++runs > 10)
+ return ec;
+ continue;
+ }
+ }
+ }
+ // skip that line and then erase the buffer
+ return ec;
+ }
+
+ boost::system::error_code
+ parse_one_form_part(boost::system::error_code& ec)
+ {
+ // continuously read data while parsing it until one complete form part has
+ // been read.
+ // Note, this may mean recursing into embedded sub-parts if necessary, but
+ // still only the first *complete* part/sub-part would be read.
+ //boost::regex re("\r\n--" + boundary_marker + " +
+
+ for(;;)
+ {
+ //if (impl.client_->read_some(impl.prepare(1024), ec))
+ // return ec;
+ //boost::asio::read_until(impl.client_-> impl.buffer_, boundary_marker, ec);
+ break;
+
+
+ }
+
+ return ec;
+ }
+
+ /// Get the boundary marker from the CONTENT_TYPE header.
+ boost::system::error_code
+ parse_boundary_marker(boost::system::error_code& ec)
+ {
+ // get the meta-data appended to the content_type
+ std::string content_type_(impl_.env_vars_["CONTENT_TYPE"]);
+ //BOOST_ASSERT(!content_type.empty());
+
+ boost::regex re("; ?boundary=\"?([^\"\n\r]+)\"?");
+ boost::smatch match_results;
+ if (!boost::regex_search(content_type_, match_results, re))
+ return boost::system::error_code(666, boost::system::system_category);
+
+ boundary_marker = match_results[1].str();
+ // New boundary markers are added to the front of the list.
+ boundary_markers.push_front(match_results[1].str());
+
+ return ec;
+ }
+
private:
- std::set<std::string> boundary_markers_;
- std::vector<common::form_part> form_parts_;
+ //std::set<std::string> boundary_markers_;
+ //std::vector<common::form_part> form_parts_;
//buffer_type& buffer_;
- callback_type callback_;
+ //callback_type callback_;
};
} // namespace detail
Modified: sandbox/SOC/2007/cgi/branches/release/boost/cgi/connections/stdio.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/boost/cgi/connections/stdio.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/boost/cgi/connections/stdio.hpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -60,11 +60,11 @@
std::size_t read_some(MutableBufferSequence buf
, boost::system::error_code& ec)
{
- if (std::cin.eof())
- {
+ //if (std::cin.eof())
+ //{
//ec = boost::asio::error::eof;
- return boost::asio::error::eof;
- }
+ // return boost::asio::error::eof;
+ //}
//if( buf.data() != in_.rdbuf() )
// return in_.read(buf.begin(), buf.size());
//return buf.size();
@@ -81,29 +81,27 @@
ec = boost::system::error_code(654, boost::system::system_category);
return 0;
}
- //std::cerr<< "Read data" << std::endl
- // << "after = {" << std::endl
+ */
+ //std::cerr<< "before = {" << std::endl
// << std::string(boost::asio::buffer_cast<char *>(buf), boost::asio::buffer_size(buf)) << std::endl
// << "}" << std::endl;
- return std::cin.gcount();
- */
- if (!std::fgets(boost::asio::buffer_cast<char *>(buf)
- , boost::asio::buffer_size(buf)
- , stdin))
+
+ if (std::fread(boost::asio::buffer_cast<void *>(buf)
+ , boost::asio::buffer_size(buf)
+ , 1, stdin))
{
- return ::cgi::error::bad_read;
+ return strlen(boost::asio::buffer_cast<char *>(buf));
}
- int len( strlen(boost::asio::buffer_cast<char *>(buf)) );
- // Not sure what to do about EOF yet.
- //if (len < boost::asio::buffer_size(buf))
- //{
- // return ::cgi::error::eof;
- //}
- std::cerr<< "Read data" << std::endl
- << "after = {" << std::endl
- << std::string(boost::asio::buffer_cast<char *>(buf), boost::asio::buffer_size(buf)) << std::endl
- << "}" << std::endl;
- return len;
+
+ if (std::feof(stdin))
+ ec = boost::asio::error::eof;
+ else
+ if (std::ferror(stdin))
+ ec = ::cgi::error::bad_read;
+ else
+ ec = ::cgi::error::broken_pipe;
+
+ return 0;
}
template<typename ConstBufferSequence>
Modified: sandbox/SOC/2007/cgi/branches/release/boost/cgi/detail/cgi_service_impl_base.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/boost/cgi/detail/cgi_service_impl_base.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/boost/cgi/detail/cgi_service_impl_base.hpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -50,105 +50,28 @@
struct implementation_type
: RequestImplType
{
- typedef boost::asio::const_buffers_1 const_buffers_type;
- typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
- typedef typename RequestImplType::client_type client_type;
- typedef std::vector<char> buffer_type;
- //typedef std::list<std::string>::iterator marker_list_type;
+ typedef boost::asio::const_buffers_1 const_buffers_type;
+ typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
+ typedef typename RequestImplType::client_type client_type;
+ typedef std::vector<char> buffer_type;
+ typedef detail::form_parser<implementation_type> form_parser_type;
implementation_type()
- : //buffer_()
- //, istream_(&buffer_)
- pos_()
- , offset_(0)
- , fp_(NULL)
+ : fp_(NULL)
{
}
client_type client_;
- std::string boundary_marker;
- std::list<std::string> boundary_markers;
- //std::vector<char> data_buffer_;
// The number of characters left to read (ie. "content_length - bytes_read")
std::size_t characters_left_;
- //std::vector<char>::iterator read_pos_;
- //boost::asio::streambuf buffer_;
- //std::istream istream_;
-
buffer_type buf_;
- typename buffer_type::iterator pos_;
- std::size_t offset_;
- //boost::sub_match<typename buffer_type::iterator> offset_;
+
std::vector<common::form_part> form_parts_;
- detail::form_parser* fp_;
-
- /*
- mutable_buffers_type prepare(typename buffer_type::iterator& pos, std::size_t size)
- {
- std::size_t bufsz( buf_.size() );
-
- // Reserve more space if it's needed.
- // (this could be safer, referencing this against CONTENT_LENGTH)
- if ( (bufsz + size) >= buf_.capacity() )
- {
- buf_.resize(bufsz + size);
- }
-
- return boost::asio::buffer(&(buf_.begin()), size);
- // return boost::asio::buffer(&buf_[bufsz], size);
- }
- */
-
- mutable_buffers_type prepare(std::size_t size)
- {
-
- std::size_t bufsz( buf_.size() );
- //cerr<< "bufsz = " << bufsz << endl;
-
- // Reserve more space if it's needed.
- // (this could be safer, referencing this against CONTENT_LENGTH)
- //if ( (bufsz + size) >= buf_.capacity() )
- //{
- buf_.resize(bufsz + size);
- //}
-
- //cerr<< "Pre-read buffer (size: " << buf_.size()
- // << "|capacity: " << buf_.capacity() << ") == {" << endl
- // << std::string(buf_.begin() + offset_, buf_.end()) << endl
- // << "-----end buffer-----" << endl
- // << "-------buffer-------" << endl
- // << std::string(&buf_[0], &buf_[buf_.size()]) << endl
- // << "}" << endl;
- ;
- //return boost::asio::buffer(&(*(buf_.end())), size);
- // return boost::asio::buffer(&(*(buf_.begin())) + bufsz, size);
- return boost::asio::buffer(&buf_[bufsz], size);
- }
-
- std::string buffer_string()
- {
- return std::string(buf_.begin() + offset_, buf_.end());
- //return std::string(pos_, buf_.size());//buf_.end());
- }
- /*
- // Silently ignore a request to grow the buffer greater than the
- // content-length allows.
- // Note: this will break if the contents of the buffer are ever changed
- // (such as if data is url-decoded and inserted back into the buffer).
- if (size >= characters_left_)
- {
- size = characters_left_;
- }
+ boost::scoped_ptr<form_parser_type> fp_;
- data_buffer_.reserve(bufsz + size);
- return boost::asio::buffer(data_buffer_.begin() + bufsz
- , data_buffer_.capacity() - bufsz);
- }
- */
- //boost::acgi::form_entry form_;
};
/// Return if the request is still open
@@ -419,39 +342,57 @@
parse_url_encoded_form(implementation_type& impl
, boost::system::error_code& ec)
{
- std::istream& is(std::cin);
- char ch;
std::string name;
std::string str;
map_type& post_map(impl.post_vars());
-
- while( is.get(ch) && impl.characters_left_-- )
+
+ char ch;
+ char ch1;
+ while( impl.characters_left_ )
{
- //std::cerr<< "; ch=" << ch << "; ";
- switch(ch)
+ ch = getchar();
+ --impl.characters_left_;
+
+ switch(ch)
+ {
+ case '%': // unencode a hex character sequence
+ if (impl.characters_left_ >= 2)
{
- case '%': // unencode a hex character sequence
- // note: function params are resolved in an undefined order!
- str += detail::url_decode(is);
- impl.characters_left_ -= 2; // this is dodgy **FIXME**
- break;
- case '+':
- str.append(1, ' ');
- break;
- case ' ':
- continue;
- case '=': // the name is complete, now get the corresponding value
- name = str;
- str.clear();
- break;
- case '&': // we now have the name/value pair, so save it
- post_map[name] = str;
- str.clear();
- name.clear();
- break;
- default:
- str.append(1, ch);
+ ch = getchar();
+ ch1 = getchar();
+ if (std::isxdigit(ch) && std::isxdigit(ch1))
+ {
+ str.append(1, detail::hex_to_char(ch, ch1));
+ }
+ else // we don't have a hex sequence
+ {
+ str.append(1, '%').append(1, ch).append(1, ch1);
+ }
+ impl.characters_left_ -= 2;
+ }
+ else // There aren't enough characters to make a hex sequence
+ {
+ str.append(1, '%');
+ --impl.characters_left_;
}
+ break;
+ case '+':
+ str.append(1, ' ');
+ break;
+ case ' ':
+ continue;
+ case '=': // the name is complete, now get the corresponding value
+ name = str;
+ str.clear();
+ break;
+ case '&': // we now have the name/value pair, so save it
+ post_map[name] = str;
+ str.clear();
+ name.clear();
+ break;
+ default:
+ str.append(1, ch);
+ }
}
// save the last param (it won't have a trailing &)
if( !name.empty() )
@@ -465,6 +406,15 @@
boost::system::error_code
parse_multipart_form(implementation_type& impl, boost::system::error_code& ec)
{
+ impl.fp_.reset
+ (
+ new typename implementation_type::form_parser_type
+ ( impl )
+ );
+ impl.fp_->parse(ec);
+ return ec;
+ }
+ /*
parse_boundary_marker(impl, ec);
//parse_one_form_part(impl, ec);
move_to_start_of_first_part(impl, ec);
@@ -756,7 +706,7 @@
// << impl.buffer_string() << endl
// << "} or {" << endl;
//<< std::string(impl.pos_, ;
- /*
+ / *
for (unsigned int i = 0; i < matches.size(); ++i)
{
if (matches[i].length())
@@ -769,7 +719,7 @@
cerr<< "-------buf------" << endl
<< std::string(begin, end) << endl
<< "----------------" << endl;
- */
+ * /
//offset = impl.buf_.end();
if (++runs > 40)
{
@@ -934,17 +884,17 @@
// New boundary markers are added to the front of the list.
impl.boundary_markers.push_front(match_results[1].str());
- /*
+ / *
cerr<< "full = " << content_type << endl
<< "full search string = " << match_results[0] << endl
<< "marker length = " << match_results[1].length() << endl
<< "marker = " << impl.boundary_marker << endl
<< "_[2] = " << match_results[2] << endl;
- */
+ * /
return ec;
}
-
+*/
/// Read and parse a single cgi POST meta variable (greedily)
template<typename RequestImpl>
boost::system::error_code
Modified: sandbox/SOC/2007/cgi/branches/release/boost/cgi/fcgi/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/boost/cgi/fcgi/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/boost/cgi/fcgi/request_service.hpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -547,15 +547,15 @@
// **FIXME**
void handle_admin_request(implementation_type& impl)
{
- std::cerr<< std::endl << "**FIXME** " << __FILE__ << ":" << __LINE__
- << " handle_admin_request()" << std::endl;
+ //std::cerr<< std::endl << "**FIXME** " << __FILE__ << ":" << __LINE__
+ // << " handle_admin_request()" << std::endl;
}
// **FIXME**
void handle_other_request_header(implementation_type& impl)
{
- std::cerr<< std::endl << "**FIXME** " << __FILE__ << ":" << __LINE__
- << " handle_other_request_header()" << std::endl;
+ //std::cerr<< std::endl << "**FIXME** " << __FILE__ << ":" << __LINE__
+ // << " handle_other_request_header()" << std::endl;
}
// **FIXME**
@@ -575,8 +575,8 @@
return ec;
}
try {
- std::cerr<< "**FIXME** request aborted (id = " << id
- << ") but request not notified." << std::endl;
+ //std::cerr<< "**FIXME** request aborted (id = " << id
+ // << ") but request not notified." << std::endl;
//impl.client_.connection_->requests_.at(id - 1)->abort();
}catch(...){
ec = error::abort_request_record_recieved_for_invalid_request;
@@ -725,8 +725,8 @@
}else
if (!state)
{ // The header is confusing; something's wrong. Abort.
- std::cerr<< "Bad header received (this isn't implemented properly yet"
- << std::endl;
+ //std::cerr<< "Bad header received (this isn't implemented properly yet"
+ // << std::endl;
return error::bad_header_type;
}
// else route (ie. state == boost::indeterminate)
Modified: sandbox/SOC/2007/cgi/branches/release/boost/cgi/request_ostream.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/boost/cgi/request_ostream.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/boost/cgi/request_ostream.hpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -9,6 +9,11 @@
#ifndef CGI_REQUEST_OSTREAM_HPP_INCLUDED__
#define CGI_REQUEST_OSTREAM_HPP_INCLUDED__
+#if 0
+
+// THIS FILE ISN'T USED!
+// **FIXME**
+
/*********************************
ISSUES:
-------
@@ -358,4 +363,6 @@
#include "boost/cgi/detail/pop_options.hpp"
+#endif
+
#endif // CGI_REQUEST_OSTREAM_HPP_INCLUDED__
Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/cookie_game/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/cookie_game/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/cookie_game/main.cpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -1,6 +1,5 @@
#include <boost/cgi/acgi.hpp>
#include <boost/cgi/response.hpp>
-#include <iostream>
#define SCRIPT_NAME "acgi_cookie_game"
@@ -88,9 +87,6 @@
<< "Hello there, Universe.<p />"
<< "What's your name?<br />";
- std::cerr<< std::endl << "name = " << req.POST("name") << std::endl;
- std::cerr.flush();
-
resp<< "<form method='POST'>"
"<input name='name' type='text' value='" << req[form_data]["name"] << "'>"
"</input>"
Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/echo/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/echo/main.cpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -71,8 +71,7 @@
"<input type=hidden name=cmd value=multipart_test />"
"<br />"
"<input type=submit value=submit />"
- "</form><p />"
- "boundary marker = " << req.boundary_marker() << "<p />";
+ "</form><p />";
show_map_contents(resp, req[get_data], "GET Variables");
show_map_contents(resp, req[post_data], "POST Variables");
Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/Jamfile.v2 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -4,19 +4,9 @@
# (See accompanying file LICENSE_1_0.txt or copy
# at http://www.boost.org/LICENSE_1_0.txt)
-project boost/cgi/example/cgi
- ;
-
# By default, just build the examples
build-project hello_world ;
build-project echo ;
-#install stage
-# :
-# hello_world
-# echo
-# :
-# <location>$(bin-dir)
-# ;
# If the user explicitly passes "install" on the command line, build the
# CGI examples and copy them to $(cgi-bin)
Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/echo/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/echo/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/cgi/echo/Jamfile.v2 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -15,10 +15,10 @@
# Our install rule (builds binaries and copies them to <location>)
install install
- : cgi_echo
:
+ cgi_echo
:
- <location>$(LOCATION)
+ <location>$(cgi-bin)
;
# Only install example if you use `bjam install' or equivalent
Modified: sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/hello_world/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/hello_world/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/fcgi/hello_world/main.cpp 2008-03-31 23:32:19 EDT (Mon, 31 Mar 2008)
@@ -25,7 +25,8 @@
acceptor a(s); // This is used to accept requests from the server.
request req(s); // Our request.
- for (int i(50); i != 0; --i) // Handle 50 requests then exit.
+ for (;;) // Handle requests until something goes wrong
+ // (an exception will be thrown).
{
a.accept(req);
response resp; // A response object to make our lives easier.
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