Boost logo

Boost-Commit :

From: lists.drrngrvy_at_[hidden]
Date: 2008-03-21 16:33:10


Author: drrngrvy
Date: 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
New Revision: 43773
URL: http://svn.boost.org/trac/boost/changeset/43773

Log:
Merged revisions 40142-43769 via svnmerge from
https://svn.boost.org/svn/boost/sandbox/SOC/2007/cgi/branches/acceptor_work

........
  r40142 | drrngrvy | 2007-10-18 00:40:30 +0100 (Thu, 18 Oct 2007) | 1 line
  
  Merge from SF.net finished, finally. Gadzooks! Ike! It did not have to be that fiddly...
........
  r40493 | drrngrvy | 2007-10-27 04:15:02 +0100 (Sat, 27 Oct 2007) | 1 line
  
  Trying SCGI stuff with a compiler (!) - it's really messy at the moment, unfortunately.
........
  r40899 | drrngrvy | 2007-11-07 18:08:24 +0000 (Wed, 07 Nov 2007) | 18 lines
  
  Commit to bridge the gap since the last. The included updates are many and scattered, mostly incomplete (see below).
  
  * Removed gateway_* files, since they're not needed (although changing basic_client -> basic_gateway might be a future possibility; it depends how the Client concept develops).
  
  * Working on a more rigorous testing environment (not yet included here). For this we need an 'executor' that can generate fake requests and launch the programs compiled using this library in the way they're supposed to be. I avoided doing this before now because it seemed like a monumental task, but thanks to the (not-done-yet) Boost.Process, it isn't.
  
  The separate testing environment provides more than just the ability to test the library independently of an HTTP server.
   
   Required features:
   - Allow one to easily debug their program.
   - Allow basic benchmarking facilities.
   - Allow testing of CGI, SCGI and FastCGI programs.
   - Allow loading of 'requests' from file or command line
  
  In short, the lack of tests is hindering progress. Dropping the *need* for an HTTP server layer should help immensely. Obviously they will still be needed, just not at every step of the way.
........
  r40915 | drrngrvy | 2007-11-08 01:24:05 +0000 (Thu, 08 Nov 2007) | 1 line
  
  Working with cgi::response. It now separates the headers and the body, which can be reset at any time. The send() functions also should now work. The flush() and async_*() functions haven't been done yet. Streaming header and cookie classes to a response work now and can be sent in any order. A default-constructed header now stops any more headers being appended (BOOST_ASSERT is used for this), unless the ugly `unterminate_headers` function is called (that might be 'beyond ugly' though, it may have to change).
........
  r41171 | drrngrvy | 2007-11-17 17:50:26 +0000 (Sat, 17 Nov 2007) | 1 line
  
  Disorganised commit, but makes the previous revision slightly less so.
........
  r41245 | drrngrvy | 2007-11-20 03:00:40 +0000 (Tue, 20 Nov 2007) | 8 lines
  
  Again, not a particularly atomic commit, but:
  * Added some examples;
  * Allow use of boost::cgi, boost::acgi, boost::fcgi, boost::scgi;
  * Added listen(), bind(), assign() and open() functions to acceptor classes (at least, to the SCGI ones);
  * Fixed tcp_connection static create() function;
  * other minor changes.
........
  r43172 | drrngrvy | 2008-02-08 14:43:13 +0000 (Fri, 08 Feb 2008) | 13 lines
  
  This is a backup commit, it may be less functional than the last revision!
  
  Contents:
  
  * Some work towards SCGI support. This was partly abandoned to work on FastCGI support (which is merely a copy of the scgi directory + modifications).
  
  * FastCGI support has begun to be added. On linux, with apache (mod_fastcgi or mod_fcgid) it can accept multiple connections and read/parse packets. PARAM packets can be parsed correctly, as can STDIN and BEGIN_REQUEST packets. They lack proper handling because I'm not sure if introducing a circular dependency is absolutely necessary - ie. the basic_client<> reads/parses packets but in order to do so must have access to the basic_request<> associated with it (to store variables in). The basic_request<> *has* a basic_client<> so that dependency exists too. There are several ways around it, not sure which is best.
  
  * FastCGI outputting hasn't been addressed yet, will do that after important uni work is done.
  
  * The beginnings of multipart form data handling was added, but only using Boost.Regex. The idea is that 'eventually' this should be a seperate form_parser class that takes a function object for reading more data and a map to store saved data into, so the class is generally useful outside this library. This separation has the advantage of allowing a Boost.Spirit, Boost.Regex and Boost.Xpressive implementation. I'm starting with regex because it won't get done otherwise. It's not finished yet, surprise surprise.
........
  r43183 | drrngrvy | 2008-02-09 04:48:28 +0000 (Sat, 09 Feb 2008) | 1 line
  
  Worked on getting fcgi::client able to write data: fcgi::client::write_some can write packets now. Also fcgi_request_service knows when it has finished loading now.
........
  r43195 | drrngrvy | 2008-02-09 14:34:21 +0000 (Sat, 09 Feb 2008) | 13 lines
  
  Refactored functions related to reading from fcgi::client to fcgi_request_service to remove the need for any circular dependency. Now you have the client as an AsyncWriteStream and the request as an AsyncReadStream: so you read into the request and write to the client... Seems natural.
  
  I haven't updated the relevant bits for the other protocols, I'm going to leave that in case this turns out to be a bad way (it should be OK).
  
  Note:
  
  * read_some isn't implemented yet.
  
  * the process_* functions work to varying degrees, but don't finish their jobs yet: that was due to the circular dependency issue mentioned above.
  
  * Only tested on linux/apache
........
  r43197 | drrngrvy | 2008-02-09 17:18:35 +0000 (Sat, 09 Feb 2008) | 3 lines
  
  FastCGI environment variables are stored now. The fcgi/hello_world example displays them (will move this to fcgi/echo when things settle a bit).
........
  r43208 | drrngrvy | 2008-02-10 14:35:42 +0000 (Sun, 10 Feb 2008) | 3 lines
  
  Adding return_() macro to make closing requests nicer-looking. (just a thought)
........
  r43224 | drrngrvy | 2008-02-11 19:44:28 +0000 (Mon, 11 Feb 2008) | 1 line
  
  Adding FastCGI echo example.
........
  r43225 | drrngrvy | 2008-02-11 20:00:54 +0000 (Mon, 11 Feb 2008) | 1 line
  
  Cleaned up return_ macro.
........
  r43578 | drrngrvy | 2008-03-12 17:06:00 +0000 (Wed, 12 Mar 2008) | 3 lines
  
  Adding amortization calculator example, which uses Google cTemplate to handle HTML output.
........
  r43579 | drrngrvy | 2008-03-12 17:07:00 +0000 (Wed, 12 Mar 2008) | 1 line
  
  Minor cosmetic update for hello world example.
........
  r43580 | drrngrvy | 2008-03-12 17:43:11 +0000 (Wed, 12 Mar 2008) | 1 line
  
  Cleaning up example a bit.
........
  r43581 | drrngrvy | 2008-03-12 18:02:50 +0000 (Wed, 12 Mar 2008) | 1 line
  
  Cleaned up template file a bit.
........
  r43582 | drrngrvy | 2008-03-13 00:42:37 +0000 (Thu, 13 Mar 2008) | 1 line
  
  Another minor cleanup to main.cpp.
........
  r43583 | drrngrvy | 2008-03-13 00:45:41 +0000 (Thu, 13 Mar 2008) | 1 line
  
  Try last commit again.
........
  r43584 | drrngrvy | 2008-03-13 00:47:08 +0000 (Thu, 13 Mar 2008) | 1 line
  
  And again (it's late).
........
  r43585 | drrngrvy | 2008-03-13 00:59:35 +0000 (Thu, 13 Mar 2008) | 1 line
  
  Various fixes, mostly to FastCGI parts; one or two small changes to aCGI/CGI files.
........
  r43745 | drrngrvy | 2008-03-21 16:24:14 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Updated project-root.jam that allows users to install examples straight into their cgi-bin / fcgi-bin / etc. directory using either the command line or environment variables.
........
  r43746 | drrngrvy | 2008-03-21 16:30:08 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Importing cgi::common namespace into boost::*cgi namespaces when including that protocol's header
........
  r43749 | drrngrvy | 2008-03-21 16:49:08 +0000 (Fri, 21 Mar 2008) | 36 lines
  
  * all-files
    - Moved common bits into namespace ::cgi::common
    - Updated references to things that were moved over
  
  * basic_request.hpp
    - adding close() overload that takes an error_code;
    - adding a clear() function so a request can be safely reused.
  
  * basic_request_acceptor.hpp
    - an acceptor now initialises itself by default (using default_init())
    - added protocol_service() function to get the underlying basic_protocol_service
    - accept() calls now use the endpoint, like Boost.Asio.
  
  * basic_sync_io_object.hpp
    - s/impl/implementation
  
  * common/form_parser.hpp
    - added name member, because every form part has a name (saves looking it up in a map every time)
  
  * connections/stdio.hpp
    - simplified write_some() a little.
  
  * detail/cgi_*_impl_base.hpp
    - cosmetic changes, removed old fluff (see source)
  
  * error.hpp
    - added a couple of new errors
  
  * fcgi/acceptor_service_impl.hpp
    - added default_init() function, which only works on linux for now.
  
  * fcgi/client.hpp
    - added close() overload that doesn't take an error_code
  
  * response.hpp
    - added resend() function, which sends the header+body regardless of the value of `headers_terminated_`
........
  r43751 | drrngrvy | 2008-03-21 16:54:26 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Fixed url_decode() and added hex_to_char(), which should be used instead of url_decode(char, char) - it's more portable too.
........
  r43753 | drrngrvy | 2008-03-21 16:57:07 +0000 (Fri, 21 Mar 2008) | 4 lines
  
  * Commented out some of the error logging used for testing (makes such a difference to speed).
  * Added clear() function so requests can be reused safely.
  * Added close() overload that takes an error_code
  * Cleaned up some old fluff
........
  r43754 | drrngrvy | 2008-03-21 16:57:34 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Updated README
........
  r43755 | drrngrvy | 2008-03-21 17:02:02 +0000 (Fri, 21 Mar 2008) | 2 lines
  
  * Added some compile tests and fixed the (two!) run tests.
  * Tried setting up tests using wget to verify the whole program (by checking its output when it's behind a server)
........
  r43756 | drrngrvy | 2008-03-21 17:07:31 +0000 (Fri, 21 Mar 2008) | 2 lines
  
  * Added fcgi/amortization example
  * Modified fcgi/echo example to make it a bit cleaner
........
  r43757 | drrngrvy | 2008-03-21 17:09:13 +0000 (Fri, 21 Mar 2008) | 2 lines
  
  * Added cgi/echo example
  * Modified/fixed/cleaned up amortization example
........
  r43759 | drrngrvy | 2008-03-21 18:14:29 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Resolved conflict
........
  r43760 | drrngrvy | 2008-03-21 18:17:06 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Adding basic example testing multipart forms.
........
  r43761 | drrngrvy | 2008-03-21 18:18:07 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Remove reference to google/ctemplate jamfile.
........
  r43762 | drrngrvy | 2008-03-21 18:20:32 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Adding build directory (trying to simplify generating requirements for examples/tests)
........
  r43763 | drrngrvy | 2008-03-21 18:29:21 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Add common/form_parser.hpp (which isn't used for anything real yet, but is referenced in detail/.cgi_service_impl_base.hpp)
........
  r43764 | drrngrvy | 2008-03-21 18:31:06 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Move header class into namespace ::cgi::common (other changes backed out)
........
  r43765 | drrngrvy | 2008-03-21 18:43:08 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Fix cookie.cpp
........

Added:
   sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/acceptor.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/acgi/acceptor.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_client_fwd.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_client_fwd.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/form_parser.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_parser.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/common/form_part.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_part.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/error.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/error.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/acceptor.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/acceptor.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/acceptor_service_impl.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/acceptor_service_impl.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/client.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/client.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/request.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/request.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/request_acceptor_service.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/request_acceptor_service.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/request_fwd.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/request_fwd.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/request_service.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/request_service.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/service.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/service.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/return.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/return.hpp
   sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/acceptor.hpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/scgi/acceptor.hpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/build/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/build/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/build/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/library_organisation.qbk
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/library_organisation.qbk
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/responses.qbk
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/responses.qbk
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/amortization/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/amortization/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/amortization/acgi_amort.css
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/acgi_amort.css
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/amortization/acgi_amort.js
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/acgi_amort.js
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/amortization/acgi_amort.tpl
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/acgi_amort.tpl
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/amortization/main.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/main.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/cookie_game/ (props changed)
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/cookie_game/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/cookie_game/main.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/main.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/echo/ (props changed)
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/echo/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/echo/main.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/main.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/hello_world/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/hello_world/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/hello_world/main.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/main.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/login/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/login/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/login/CheckCookie.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/login/CheckCookie.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/login/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/login/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/login/Login.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/login/Login.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/login/Logout.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/login/Logout.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/main.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/main.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/README
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/README
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/amortization.css
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.css
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/amortization.js
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.js
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/amortization.tpl
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.tpl
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/main.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/main.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/echo/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/echo/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/echo/main.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/main.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/scgi/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/scgi/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/scgi/hello_world/
      - copied from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/scgi/hello_world/
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/scgi/hello_world/Jamfile.v2
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/scgi/hello_world/Jamfile.v2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/scgi/hello_world/main.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/scgi/hello_world/main.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/acgi_acceptor.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/compile/acgi_acceptor.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/fcgi_acceptor.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/compile/fcgi_acceptor.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/fcgi_request.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/compile/fcgi_request.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/scgi_acceptor.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/compile/scgi_acceptor.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/scgi_request.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/compile/scgi_request.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/scgi_service.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/compile/scgi_service.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/shareable_tcp_connection.cpp
      - copied unchanged from r43765, /sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/compile/shareable_tcp_connection.cpp
Removed:
   sandbox/SOC/2007/cgi/trunk/boost/cgi/gateway_impl/
   sandbox/SOC/2007/cgi/trunk/boost/cgi/gateway_service/
   sandbox/SOC/2007/cgi/trunk/boost/cgi/gateway_service.hpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/cgi.qbk
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/main.cpp
   sandbox/SOC/2007/cgi/trunk/libs/cgi/util/system/
Properties modified:
   sandbox/SOC/2007/cgi/trunk/ (props changed)
Text files modified:
   sandbox/SOC/2007/cgi/trunk/README | 9
   sandbox/SOC/2007/cgi/trunk/boost/cgi.hpp | 15
   sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi.hpp | 10
   sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request.hpp | 18
   sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request_impl.hpp | 15
   sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request_service.hpp | 17
   sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/service.hpp | 4
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_connection.hpp | 13
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_connection_fwd.hpp | 2
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_io_object.hpp | 19
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_protocol_service.hpp | 9
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_protocol_service_fwd.hpp | 6
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request.hpp | 353 +++++++++-------
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request_acceptor.hpp | 247 +++++++++++
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request_fwd.hpp | 2
   sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_sync_io_object.hpp | 12
   sandbox/SOC/2007/cgi/trunk/boost/cgi/buffer.hpp | 5
   sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi.hpp | 13
   sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request.hpp | 6
   sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request_impl.hpp | 6
   sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request_service.hpp | 14
   sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/service.hpp | 4
   sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/async_stdio.hpp | 24
   sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/stdio.hpp | 76 ++-
   sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/tcp_socket.hpp | 51 +
   sandbox/SOC/2007/cgi/trunk/boost/cgi/cookie.hpp | 28
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/cgi_request_impl_base.hpp | 49 -
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/cgi_service_impl_base.hpp | 799 ++++++++++++++++++++++++++++++++++++---
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/common_headers.hpp | 2
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/protocol_traits.hpp | 130 ++++--
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/save_environment.hpp | 13
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/throw_error.hpp | 11
   sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/url_decode.hpp | 47 ++
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi.hpp | 21 +
   sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/specification.hpp | 374 +++++++++++++++---
   sandbox/SOC/2007/cgi/trunk/boost/cgi/header.hpp | 102 ++++
   sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service.hpp | 12
   sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service_provider.hpp | 22
   sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service_provider_fwd.hpp | 4
   sandbox/SOC/2007/cgi/trunk/boost/cgi/map.hpp | 2
   sandbox/SOC/2007/cgi/trunk/boost/cgi/read.hpp | 2
   sandbox/SOC/2007/cgi/trunk/boost/cgi/request_ostream.hpp | 39 +
   sandbox/SOC/2007/cgi/trunk/boost/cgi/request_service.hpp | 64 +-
   sandbox/SOC/2007/cgi/trunk/boost/cgi/response.hpp | 429 +++++++++++++++++++-
   sandbox/SOC/2007/cgi/trunk/boost/cgi/role_type.hpp | 3
   sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi.hpp | 21
   sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/acceptor_service_impl.hpp | 272 +++++++++++++
   sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request.hpp | 20
   sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_acceptor_service.hpp | 132 +++++-
   sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_impl.hpp | 33 +
   sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_service.hpp | 150 +++++-
   sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/service.hpp | 12
   sandbox/SOC/2007/cgi/trunk/boost/cgi/status_type.hpp | 3
   sandbox/SOC/2007/cgi/trunk/boost/cgi/streambuf.hpp | 5
   sandbox/SOC/2007/cgi/trunk/boost/cgi/tags.hpp | 10
   sandbox/SOC/2007/cgi/trunk/boost/cgi/write.hpp | 6
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/Jamfile.v2 | 4
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/building.qbk | 6
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/future_development.qbk | 10
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/introduction.qbk | 57 ++
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/preface.qbk | 12
   sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/user_guide/async_ops.qbk | 6
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/Jamfile.v2 | 33 +
   sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/Jamfile.v2 | 4
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/Jamfile.v2 | 63 ++
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/async_stdio_connection.cpp | 4
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/cgi_request.cpp | 2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/fcgi_service.cpp | 4
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/response.cpp | 2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/stdio_connection.cpp | 2
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/tcp_connection.cpp | 4
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/Jamfile.v2 | 23 +
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/cookie.cpp | 25
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/response.cpp | 83 ++++
   sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/stdio_connection.cpp | 2
   sandbox/SOC/2007/cgi/trunk/project-root.jam | 62 +++
   76 files changed, 3371 insertions(+), 804 deletions(-)

Modified: sandbox/SOC/2007/cgi/trunk/README
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/README (original)
+++ sandbox/SOC/2007/cgi/trunk/README 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -1,14 +1,9 @@
-Development has moved to cgi.sf.net for now (on the cgi/branches directory):
-
- http://cgi.svn.sourceforge.net/viewvc/cgi/
-
-'Stable' updates will be uploaded to here, as and when available.
-
 Pre-built docs can be found at http://cgi.sf.net
+(out of date at the moment @21/03/2008)
 
 Comments/critique are welcome and can be directed to one of:
 
   cgi-devel @ cgi dot sourceforge dot net
   lists dot drrngrvy @ gmail dot com
 
-You can expect SCGI and FastCGI support this side of Chrismas!
+FastCGI support on Linux now included!

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,16 +9,11 @@
 #ifndef CGI_HPP_INCLUDED__
 #define CGI_HPP_INCLUDED__
 
-// #include all headers except for cgi/cgi.hpp, cgi/fcgi.hpp, cgi/scgi.hpp
+// #include all headers
 
-#include "cgi/basic_request.hpp"
-#include "cgi/response.hpp"
-#include "cgi/map.hpp"
-#include "cgi/basic_protocol_service.hpp"
-#include "cgi/cookie.hpp"
-#include "cgi/header.hpp"
-#include "cgi/io_service.hpp"
-#include "cgi/basic_connection.hpp"
-#include "cgi/io_service_provider.hpp"
+#include "boost/cgi/cgi.hpp"
+#include "boost/cgi/acgi.hpp"
+#include "boost/cgi/fcgi.hpp"
+#include "boost/cgi/scgi.hpp"
 
 #endif // CGI_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -29,9 +29,17 @@
    typedef acgi_request request;
    //typedef acgi_service service;
    //typedef acgi_acceptor acceptor;
- using namespace cgi;
+ using namespace ::cgi; // **FIXME** this line must go.
+ using namespace ::cgi::common; // import common namespace elements.
 
  } // namespace acgi
 } // namespace cgi
 
+/// Dump acgi stuff into the boost namespace
+namespace boost {
+ namespace acgi {
+ using namespace ::cgi::acgi;
+ } // namespace acgi
+} // namespace boost
+
 #endif // CGI_ACGI_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,9 +9,9 @@
 #ifndef CGI_ACGI_REQUEST_HPP_INCLUDED__
 #define CGI_ACGI_REQUEST_HPP_INCLUDED__
 
-#include "service.hpp"
-#include "request_impl.hpp"
-#include "request_service.hpp"
+#include "boost/cgi/acgi/service.hpp"
+#include "boost/cgi/acgi/request_impl.hpp"
+#include "boost/cgi/acgi/request_service.hpp"
 #include "boost/cgi/tags.hpp"
 #include "boost/cgi/basic_request_fwd.hpp"
 #include "boost/cgi/acgi/request_impl.hpp"
@@ -20,10 +20,18 @@
 
   class acgi_request_service;
 
- typedef basic_request<acgi_request_service, acgi_service> acgi_request;
+ typedef
+ common::basic_request<
+ acgi_request_service, acgi_service
+ >
+ acgi_request;
 
 } // namespace cgi
 
-#include "../basic_request.hpp"
+//namespace boost { namespace acgi {
+// typedef ::cgi::basic_request< cgi::acgi_request_service, cgi::acgi_service> request;
+//} }
+
+#include "boost/cgi/basic_request.hpp"
 
 #endif // CGI_ACGI_REQUEST_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request_impl.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request_impl.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request_impl.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,7 +9,8 @@
 #ifndef CGI_ACGI_REQUEST_IMPL_HPP_INCLUDED__
 #define CGI_ACGI_REQUEST_IMPL_HPP_INCLUDED__
 
-#include "service.hpp"
+#include "boost/cgi/acgi/service.hpp"
+#include "boost/cgi/basic_client.hpp"
 #include "boost/cgi/detail/cgi_request_impl_base.hpp"
 #include "boost/cgi/connections/async_stdio.hpp"
 
@@ -21,16 +22,24 @@
   class acgi_service_impl;
 
   class acgi_request_impl
- : public cgi_request_impl_base<async_stdio_connection>
+ : public cgi_request_impl_base<common::async_stdio_connection>
   {
   public:
     typedef acgi_service protocol_service_type;
+ typedef common::async_stdio_connection connection_type;
+ typedef
+ ::cgi::common::basic_client<
+ connection_type, tags::acgi
+ >
+ client_type;
+ //typedef async_stdio_connection client_type;
 
     acgi_request_impl()
- : cgi_request_impl_base<async_stdio_connection>()
+ : cgi_request_impl_base<connection_type>()
     {
     }
 
+ protocol_service_type* service_;
   protected:
     //acgi_request_impl(); // private default constructor
     friend class acgi_service_impl;

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/request_service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,7 +9,7 @@
 #ifndef CGI_ACGI_SERVICE_IMPL_HPP_INCLUDED__
 #define CGI_ACGI_SERVICE_IMPL_HPP_INCLUDED__
 
-#include "request_impl.hpp"
+#include "boost/cgi/acgi/request_impl.hpp"
 #include "boost/cgi/tags.hpp"
 #include "boost/cgi/io_service.hpp"
 #include "boost/cgi/map.hpp"
@@ -29,14 +29,14 @@
   public:
     typedef acgi_request_service type;
     typedef acgi_request_impl impl_type;
- typedef cgi::map map_type;
+ typedef ::cgi::common::map map_type;
     typedef tags::acgi protocol_type;
     typedef acgi_service protocol_service_type;
 
     /// The unique service identifier
     // static boost::asio::io_service::id id;
 
- acgi_request_service(cgi::io_service& ios)
+ acgi_request_service(::cgi::io_service& ios)
       : detail::service_base<acgi_request_service>(ios)
     {
     }
@@ -44,15 +44,22 @@
     void shutdown_service()
     {
     }
+
     void construct(implementation_type& impl)
     {
- impl.connection() = async_stdio_connection::create(io_service());
+ impl.client_.set_connection(
+ implementation_type::connection_type::create(this->io_service())
+ );
     }
 
     void destroy(implementation_type& impl)
     {
     }
-
+
+ void set_service(implementation_type& impl, protocol_service_type& ps)
+ {
+ impl.service_ = &ps;
+ }
   };
 
 } // namespace cgi

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/acgi/service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -20,10 +20,10 @@
   /**
    * Works with both cgi_request and acgi_request.
    */
- typedef basic_protocol_service<tags::acgi> acgi_service;
+ typedef common::basic_protocol_service<tags::acgi> acgi_service;
 
   namespace acgi {
- typedef basic_protocol_service<tags::acgi> service;
+ typedef common::basic_protocol_service<tags::acgi> service;
   }
 
   /// A service 'owned' by a single user-supplied io_service

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_connection.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_connection.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_connection.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,15 +9,16 @@
 #ifndef CGI_BASIC_CONNECTION_HPP_INCLUDED__
 #define CGI_BASIC_CONNECTION_HPP_INCLUDED__
 
-#include <istream>
-#include <ostream>
-#include <boost/asio.hpp>
+//#include <istream>
+//#include <ostream>
+//#include <boost/asio.hpp>
 
-#include "tags.hpp"
-#include "connection_base.hpp"
+//#include "boost/cgi/tags.hpp"
+//#include "boost/cgi/connection_base.hpp"
 //#include "connections/async_stdio_connection_impl.hpp"
 
 namespace cgi {
+ namespace common {
 
   template<typename ConnectionType>
   class basic_connection;
@@ -79,7 +80,7 @@
 //#include "connections/async_stdio_connection.hpp"
 //#include "connections/tcp_connection.hpp"
 
-
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_BASIC_CONNECTION_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_connection_fwd.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_connection_fwd.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_connection_fwd.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -10,10 +10,12 @@
 #define CGI_BASIC_CONNECTION_FWD_HPP_INCLUDED__
 
 namespace cgi {
+ namespace common {
 
   template<typename ConnectionType>
   class basic_connection;
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_BASIC_CONNECTION_FWD_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_io_object.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_io_object.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_io_object.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -21,33 +21,35 @@
   public:
     typedef Service service_type;
 
- cgi::io_service& io_service()
+ ::cgi::io_service&
+ io_service()
     {
       return service.io_service();
     }
 
   private:
- typedef typename Service::impl_type impl_type;
+ typedef typename Service::implementation_type impl_type;
+ typedef typename Service::implementation_type implementation_type;
 
   protected:
- explicit basic_io_object(boost::asio::io_service& ios)
+ explicit basic_io_object(::cgi::io_service& ios)
       : service(boost::asio::use_service<Service>(ios))
     {
- service.construct(impl);
+ service.construct(implementation);
     }
 
     ~basic_io_object()
     {
- service.destroy(impl);
+ service.destroy(implementation);
     }
 
- impl_type impl;
+ implementation_type implementation;
     service_type& service;
   };
 
   /*
- template<typename Service>
- class basic_io_object<Service, false>
+ template<>
+ class basic_io_object< ::cgi::request>
     : private boost::noncopyable
   {
   public:
@@ -67,6 +69,7 @@
 
     impl_type impl;
     service_type service;
+ boost::asio::io_service io_service;
   };
   */
 

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_protocol_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_protocol_service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_protocol_service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -19,8 +19,10 @@
 #include "boost/cgi/io_service_provider.hpp"
 #include "boost/cgi/basic_request_fwd.hpp"
 #include "boost/cgi/detail/protocol_traits.hpp"
+#include "boost/cgi/basic_protocol_service_fwd.hpp"
 
 namespace cgi {
+ namespace common {
 
   /// Basic Protocol Service
   /**
@@ -131,13 +133,11 @@
     /// A strand is used for guaranteeing handlers are dispatched sequentially
     //boost::asio::strand strand_;
 
+ /// A std::set of all the requests.
     set_type request_set_;
+ /// A std::queue of the waiting (ie. not-being-handled) requests.
     queue_type request_queue_;
 
- //gateway_type gateway_;
-
- //friend class basic_gateway<protocol_type>;//gateway_type;
- //friend class basic_acceptor<protocol_type>;//class acceptor_type;
 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400))
     friend typename traits::request_type;//typename request_type;
 #else
@@ -146,6 +146,7 @@
     //friend class request_type;
   };
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_BASIC_PROTOCOL_SERVICE_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_protocol_service_fwd.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_protocol_service_fwd.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_protocol_service_fwd.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,9 +9,14 @@
 #ifndef CGI_BASIC_PROTOCOL_SERVICE_FWD_HPP_INCLUDED__
 #define CGI_BASIC_PROTOCOL_SERVICE_FWD_HPP_INCLUDED__
 
+#if _MSC_VER > 1020
+#pragma once
+#endif
+
 #include "boost/cgi/io_service_provider.hpp"
 
 namespace cgi {
+ namespace common {
 
   template<
     typename Protocol,
@@ -19,6 +24,7 @@
>
   class basic_protocol_service;
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_BASIC_PROTOCOL_SERVICE_FWD_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -6,6 +6,11 @@
 // 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__
 
@@ -37,6 +42,7 @@
 #include "boost/cgi/map.hpp"
 
 namespace cgi {
+ namespace common {
 
   /// The basic_request class, primary entry point to the library
   /**
@@ -75,80 +81,91 @@
   {
   public:
     typedef basic_request<RequestService, ProtocolService
- , Role, Allocator > type;
+ , Role, Allocator > type;
+ typedef ::cgi::common::map map_type;
     typedef RequestService service_type;
     typedef typename service_type::protocol_type protocol_type;
     typedef ProtocolService protocol_service_type;
     typedef boost::shared_ptr<type> pointer;
     typedef typename RequestService::implementation_type implementation_type;
+ typedef typename implementation_type::client_type client_type;
 
 
     // Throws
     basic_request(bool load_now = true, bool parse_post = true)
       : basic_sync_io_object<service_type>()
     {
- if (load_now) load(parse_post);//this->service.load(this->impl, true, ec);
+ if (load_now) load(parse_post);//this->service.load(this->implementation, true, ec);
     }
 
+ // Won't throw
     basic_request(boost::system::error_code& ec
                  , const bool load_now = true
                  , const bool parse_post = true)
       : basic_sync_io_object<service_type>()
     {
- if (load_now) load(ec, parse_post);//this->service.load(this->impl, true, ec);
+ if (load_now) load(ec, parse_post);//this->service.load(this->implementation, true, ec);
     }
 
+ // Throws
     basic_request(protocol_service_type& s, const bool load_now = false
                  , const bool parse_post = false)
       : basic_io_object<service_type>(s.io_service())
     {
- if (load_now) load(parse_post);//this->service.load(this->impl, false, ec);
+ set_protocol_service(s);
+ if (load_now) load(parse_post);//this->service.load(this->implementation, false, ec);
     }
 
+ // Won't throw
     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())
     {
- if(load_now) load(ec, parse_post);//this->service.load(this->impl, false, ec);
+ set_protocol_service(s);
+ if(load_now) load(ec, parse_post);//this->service.load(this->implementation, false, ec);
     }
 
- ~basic_request()
+ /// Make a new mutiplexed request from an existing connection.
+ basic_request(implementation_type& impl)
+ : basic_io_object<service_type>(impl.service_->io_service())
     {
- if (is_open())
- close(http::internal_server_error, 0);
+ 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);
     }
 
- /// Return `true` if the request is still open (ie. not aborted or closed)
- bool is_open()
- {
- return this->service.is_open(this->impl);
+ /// Make a new mutiplexed request from an existing connection.
+ 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);
     }
-
- /// Set a header
- void set_header(const std::string& name, const std::string& val
- , const std::string& expires)
+
+ ~basic_request()
     {
- this->service.set_header(this->impl, name, val, expires);
+ //if (is_open())
+ // close(http::internal_server_error, 0);
     }
 
- /// Set a cookie
- void set_cookie(const std::string& name, const std::string& val
- , const std::string& expires = "")
+ static pointer create(protocol_service_type& ps)
     {
- this->service.set_cookie(this->impl, name, val, expires);
+ return pointer(new type(ps));
     }
 
- /// Delete a cookie
- void del_cookie(const std::string& name)
+ void set_protocol_service(protocol_service_type& ps)
     {
- this->service.del_cookie(this->impl, name);
+ this->service.set_service(this->implementation, ps);
     }
 
- /// Delete all cookies
- void del_cookies()
+ /// Return `true` if the request is still open (ie. not aborted or closed)
+ bool is_open()
     {
- this->service.del_cookies();
+ return this->service.is_open(this->implementation);
     }
 
     /// Synchronously read/parse the request meta-data
@@ -159,15 +176,15 @@
     void load(bool parse_stdin = false)
     {
       boost::system::error_code ec;
- this->service.load(this->impl, parse_stdin, ec);
+ this->service.load(this->implementation, parse_stdin, ec);
       detail::throw_error(ec);
     }
 
     // Error-code semantics
- boost::system::error_code& load(boost::system::error_code& ec
- , bool parse_stdin = false)
+ boost::system::error_code&
+ load(boost::system::error_code& ec, bool parse_stdin = false)
     {
- return this->service.load(this->impl, parse_stdin, ec);
+ return this->service.load(this->implementation, parse_stdin, ec);
     }
 
 
@@ -178,7 +195,8 @@
     template<typename Handler>
     void async_load(Handler handler, bool parse_stdin = false)
     {
- this->service.async_load(this->impl, parse_stdin, handler);
+ this->service.async_load(this->implementation, parse_stdin
+ , handler);
     }
 
     /// Notify the server the request has finished being handled
@@ -194,38 +212,53 @@
      *
      * @returns The value of program_status
      */
- int close(http::status_code http_status, int program_status)
+ int close(http::status_code http_status = http::ok
+ , int program_status = 0)
     {
       //BOOST_ASSERT( request_status_ != status_type::ended );
 
- //this->service.set_status(this->impl, http_status);
- return this->service.close(this->impl, http_status, program_status);
+ //this->service.set_status(this->implementation, http_status);
+ return this->service.close(this->implementation, http_status
+ , program_status);
+ }
+
+ int close(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->impl, aborted);
- return this->service.close(this->impl, http::internal_server_error);
+ 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->impl, aborted);
+ this->service.set_status(this->implementation, aborted);
     }
 
- /// Set the output for the request
+ /// 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
     /**
- * Not Implemented Yet ******************
- *
- * Set the output sink as `stdout_`, `stderr_`, or `stdout_ | stderr_`
- */
- void set_output(cgi::sink dest = stdout_)
+ * You use the client for read/write calls. Y
+ */
+ client_type& client()
     {
- boost::system::error_code ec;
- this->service(this->impl, dest, ec);
- detail::throw_error(ec);
+ return this->service.client(this->implementation);
     }
 
     /// Set the output for the request
@@ -234,59 +267,61 @@
      *
      * Set the output sink as `stdout_`, `stderr_`, or `stdout_ | stderr_`
      */
- void set_output(cgi::sink dest, boost::system::error_code& ec)
+ /*
+ void set_output(cgi::sink dest = stdout_)
     {
- this->service(this->impl, dest, ec);
+ boost::system::error_code ec;
+ this->service(this->implementation, dest, ec);
+ detail::throw_error(ec);
     }
-
- /// Read some data from the client
- template<typename MutableBufferSequence/*, typename Source*/>
- std::size_t read_some(const MutableBufferSequence& buf)
+ */
+/*
+ void read_some()
     {
       boost::system::error_code ec;
- std::size_t s = this->service.read_some(this->impl, buf, ec);
+ this->service.read_some(this->implementationementation,ec);
       detail::throw_error(ec);
- return s;
     }
 
- /// Read some data from the client
- template<typename MutableBufferSequence/*, typename Source*/>
- std::size_t read_some(const MutableBufferSequence& buf
- , boost::system::error_code& ec)
+ boost::system::error_code
+ read_some(boost::system::error_code& ec)
     {
- return this->service.read_some(this->impl, buf, ec);
+ return this->service.read_some(this->implementationementation, ec);
     }
-
- /// Write some data to the client
- /**
- * Note: on the first write, the header block is closed (with a blank
- * line).
- */
- template<typename ConstBufferSequence/*, typename Sink*/>
- std::size_t write_some(const ConstBufferSequence& buf)
+*/
+ template<typename MutableBufferSequence>
+ void read_some(const MutableBufferSequence& buf)
     {
       boost::system::error_code ec;
- std::size_t s = this->service.write_some(this->impl, buf, ec);
+ this->service.read_some(this->implementation, buf, ec);
       detail::throw_error(ec);
- return s;
     }
 
- /// Write some data to the client
+ template<typename MutableBufferSequence>
+ boost::system::error_code
+ 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
     /**
- * Note: on the first write, the header block is closed (with a blank
- * line).
+ * Not Implemented Yet ******************
+ *
+ * Set the output sink as `stdout_`, `stderr_`, or `stdout_ | stderr_`
      */
- template<typename ConstBufferSequence/*, typename Sink*/>
- std::size_t write_some(const ConstBufferSequence& buf
- , boost::system::error_code& ec)
+ /*
+ void set_output(cgi::sink dest, boost::system::error_code& ec)
     {
- return this->service.write_some(this->impl, buf, ec);
+ this->service(this->implementation, dest, ec);
     }
+ */
 
     /// Get a `cgi::map&` corresponding to all of the GET variables
- cgi::map& get_()
+ map_type& GET()
     {
- return this->service.meta_get(this->impl);
+ return this->service.GET(this->implementation);
     }
 
     /// Find the get meta-variable matching name
@@ -295,10 +330,10 @@
      * fail with `cgi::error::request_aborted` if the request has been aborted
      * by the client.
      */
- std::string get_(const std::string& name)
+ std::string GET(const std::string& name)
     {
       boost::system::error_code ec;
- std::string ret = this->service.meta_get(this->impl, name, ec);
+ std::string ret = this->service.GET(this->implementation, name, ec);
       detail::throw_error(ec);
       return ret;
     }
@@ -309,15 +344,15 @@
      * fail with `ec == cgi::error::request_aborted` if the request has been
      * aborted by the client.
      */
- std::string get_(const std::string& name, boost::system::error_code& ec)
+ std::string GET(const std::string& name, boost::system::error_code& ec)
     {
- return this->service.meta_get(this->impl, name, ec);
+ return this->service.GET(this->implementation, name, ec);
     }
 
     /// Get a `cgi::map&` corresponding to all of the POST variables
- cgi::map& post_()
+ map_type& POST()
     {
- return this->service.meta_post(this->impl);
+ return this->service.POST(this->implementation);
     }
 
     /// Find the post meta-variable matching name
@@ -330,10 +365,11 @@
      * fail with `cgi::error::request_aborted` if the request has been aborted
      * by the client.
      */
- std::string post_(const std::string& name, bool greedy = true)
+ std::string POST(const std::string& name, bool greedy = true)
     {
       boost::system::error_code ec;
- std::string ret = this->service.meta_post(this->impl, name, ec, greedy);
+ std::string ret
+ = this->service.POST(this->implementation, name, ec, greedy);
       detail::throw_error(ec);
       return ret;
     }
@@ -343,16 +379,19 @@
      * fail with `ec == cgi::error::request_aborted` if the request has been
      * aborted by the client.
      */
- std::string post_(const std::string& name, boost::system::error_code& ec
+ std::string POST(const std::string& name, boost::system::error_code& ec
                           , bool greedy = true)
     {
- return this->service.meta_post(this->impl, name, ec, greedy);
+ return this->service.POST(this->implementation, name, ec, greedy);
     }
 
     /// Get a `cgi::map&` corresponding to all of the form variables
- cgi::map& form_()
+ map_type& form(bool greedy = true)
     {
- return this->service.meta_form(this->impl);
+ boost::system::error_code ec;
+ map_type& data = this->service.form(this->implementation, ec, greedy);
+ detail::throw_error(ec);
+ return data;
     }
 
     /// Find the form variable matching name
@@ -364,10 +403,10 @@
      * fail with `cgi::error::request_aborted` if the request has been aborted
      * by the client.
      */
- std::string form_(const std::string& name, bool greedy = true)
+ std::string form(const std::string& name, bool greedy = true)
     {
       boost::system::error_code ec;
- std::string ret = form_(name, ec, greedy);
+ std::string ret = form(name, ec, greedy);
       detail::throw_error(ec);
       return ret;
     }
@@ -377,23 +416,23 @@
      * fail with `ec == cgi::error::request_aborted` if the request has been
      * aborted by the client.
      */
- std::string form_(const std::string& name, boost::system::error_code& ec
+ std::string form(const std::string& name, boost::system::error_code& ec
                          , bool greedy = true)
     {
       std::string rm(request_method());
       if (rm == "GET")
- return this->service.meta_get(this->impl, name, ec);
+ return this->service.GET(this->implementation, name, ec);
       else
       if (rm == "POST")
- return this->service.meta_post(this->impl, name, ec, greedy);
+ return this->service.POST(this->implementation, name, ec, greedy);
       else
         return "";
     }
 
     /// Get a `cgi::map&` corresponding to all of the HTTP_COOKIE variables
- cgi::map& cookie_()
+ map_type& cookie()
     {
- return this->service.meta_cookie(this->impl);
+ return this->service.cookie(this->implementation);
     }
 
     /// Find the cookie meta-variable matching name
@@ -402,10 +441,11 @@
      * fail with `cgi::error::request_aborted` if the request has been aborted
      * by the client.
      */
- std::string cookie_(const std::string& name)
+ std::string cookie(const std::string& name)
     {
       boost::system::error_code ec;
- std::string ret = this->service.cookie(this->impl, name, ec);
+ std::string ret
+ = this->service.cookie(this->implementation, name, ec);
       detail::throw_error(ec);
       return ret;
     }
@@ -416,15 +456,15 @@
      * fail with `ec == cgi::error::request_aborted` if the request has been
      * aborted by the client.
      */
- std::string cookie_(const std::string& name, boost::system::error_code& ec)
+ std::string cookie(const std::string& name, boost::system::error_code& ec)
     {
- return this->service.cookie(this->impl, name, ec);
+ return this->service.cookie(this->implementation, name, ec);
     }
 
     /// Get a `cgi::map&` corresponding to all of the environment variables
- cgi::map& env_()
+ map_type& env()
     {
- return this->service.meta_env(this->impl);
+ return this->service.env(this->implementation);
     }
 
     /// Find the environment meta-variable matching name
@@ -433,10 +473,10 @@
      * fail with `cgi::error::request_aborted` if the request has been aborted
      * by the client.
      */
- std::string env_(const std::string& name)
+ std::string env(const std::string& name)
     {
       boost::system::error_code ec;
- std::string ret = this->service.meta_env(this->impl, name, ec);
+ std::string ret = this->service.env(this->implementation, name, ec);
       detail::throw_error(ec);
       return ret;
     }
@@ -447,9 +487,9 @@
      * fail with `ec == cgi::error::request_aborted` if the request has been
      * aborted by the client.
      */
- std::string env_(const std::string& name, boost::system::error_code& ec)
+ std::string env(const std::string& name, boost::system::error_code& ec)
     {
- return this->service.meta_env(this->impl, name, ec);
+ return this->service.env(this->implementation, name, ec);
     }
 
     /// Search through all meta vars for the meta-variable matching name
@@ -466,94 +506,106 @@
      * provide a meta_var_all() function which is greedy; the
      * ugly/long name there to discourage use.
      */
- std::string var_(const std::string& name, bool greedy = false)
+ std::string var(const std::string& name, bool greedy = false)
     {
       boost::system::error_code ec;
- std::string ret = var_(name, ec, greedy);
- return this->service.meta_var(this->impl, name, greedy);
- std::string request_method( env_("REQUEST_METHOD") );
+ std::string ret = var(name, ec, greedy);
+ return this->service.var(this->implementation, name, greedy);
+ std::string request_method( env("REQUEST_METHOD") );
 
       std::string tmp;
 
       // If it's not a POST request search meta_get first (to save time)
       if (request_method.empty() || request_method == "GET")
       {
- tmp = get_(name);
+ tmp = GET(name);
         if (!tmp.empty())
           return tmp;
       }
 
- tmp = cookie_(name);
+ tmp = cookie(name);
       if (!tmp.empty())
               return tmp;
 
- tmp = env_(name);
+ tmp = env(name);
       if (!tmp.empty())
               return tmp;
 
       if (!request_method.empty() && request_method == "POST")
       {
- tmp = post_(name);
+ tmp = POST(name);
         if (!tmp.empty())
           return tmp;
       }
 
- tmp = get_(name);
+ tmp = GET(name);
       return tmp.empty() ? "" : tmp;
     }
 
- // Some helper functions for the basic CGI 1.1 meta-variables
+ // [helper-functions for the basic CGI 1.1 meta-variables.
     std::string auth_type()
- { return env_("AUTH_TYPE"); }
+ { return env("AUTH_TYPE"); }
 
     std::string content_length()
- { return env_("CONTENT_LENGTH"); }
+ { return env("CONTENT_LENGTH"); }
 
     std::string content_type()
- { return env_("CONTENT_TYPE"); }
+ { return env("CONTENT_TYPE"); }
 
     std::string gateway_interface()
- { return env_("GATEWAY_INTERFACE"); }
+ { return env("GATEWAY_INTERFACE"); }
 
     std::string path_info()
- { return env_("PATH_INFO"); }
+ { return env("PATH_INFO"); }
 
     std::string path_translated()
- { return env_("PATH_TRANSLATED"); }
+ { return env("PATH_TRANSLATED"); }
 
     std::string query_string()
- { return env_("QUERY_STRING"); }
+ { return env("QUERY_STRING"); }
 
     std::string remote_addr()
- { return env_("REMOTE_ADDR"); }
+ { return env("REMOTE_ADDR"); }
 
     std::string remote_host()
- { return env_("REMOTE_HOST"); }
+ { return env("REMOTE_HOST"); }
 
     std::string remote_ident()
- { return env_("REMOTE_IDENT"); }
+ { return env("REMOTE_IDENT"); }
 
     std::string remote_user()
- { return env_("REMOTE_USER"); }
+ { return env("REMOTE_USER"); }
 
     std::string request_method()
- { return env_("REQUEST_METHOD"); }
+ { return env("REQUEST_METHOD"); }
 
     std::string script_name()
- { return env_("SCRIPT_NAME"); }
+ { return env("SCRIPT_NAME"); }
 
     std::string server_name()
- { return env_("SERVER_NAME"); }
+ { return env("SERVER_NAME"); }
 
     std::string server_port()
- { return env_("SERVER_PORT"); }
+ { return env("SERVER_PORT"); }
 
     std::string server_protocol()
- { return env_("SERVER_PROTOCOL"); }
+ { return env("SERVER_PROTOCOL"); }
 
     std::string server_software()
- { return env_("SERVER_SOFTWARE"); }
+ { return env("SERVER_SOFTWARE"); }
+ // -- end helper-functions]
 
+ /// Get the charset from the CONTENT_TYPE header
+ std::string 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
     /**
@@ -565,7 +617,7 @@
      */
     role_type& role()
     {
- return this->service.get_role(this->impl);
+ return this->service.get_role(this->implementation);
     }
 
     /// Get the strand associated with the request (if any)
@@ -575,41 +627,29 @@
     // and there would be no need for protocol-specific code in user programs.
       /* boost::asio::strand* strand()
     {
- return this->impl.strand();
+ return this->implementation.strand();
     }
       */
 
     /// Get the implementation type for the request
- //impl_type& impl() const
+ //implementation_type* impl()
     //{
- // return this->impl;
+ // return &(this->implementation);
     //}
 
     void set_status(http::status_code status)
     {
- this->service.set_status(this->impl, status);
- }
-
- /// Get the client connection associated with the request
- typename implementation_type::connection_type&
- client()
- {
- return this->service.client(this->impl);
+ this->service.set_status(this->implementation, status);
     }
 
- /// Set a user cookie
- /**
- * Note: this must be called before you have finished outputting
- * the reply headers or it will just appear as normal data
- *
- * ** Is this actually necessary? **
- */
- void set_cookie(const std::string& name, const std::string& value)
+ // The boundary marker for multipart forms (this is likely a transient function).
+ std::string boundary_marker()
     {
- return this->service.set_cookie(this->impl, name, value);
+ return this->implementation.boundary_marker;
     }
   };
 
+ } // namespace common
 } // namespace cgi
 
 #include "boost/cgi/detail/pop_options.hpp"
@@ -623,3 +663,4 @@
   - 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/basic_request_acceptor.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request_acceptor.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request_acceptor.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -13,50 +13,275 @@
 #include <boost/system/error_code.hpp>
 
 #include <boost/asio/basic_io_object.hpp>
-#include "detail/throw_error.hpp"
+#include <boost/asio/ip/basic_endpoint.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/cgi/basic_protocol_service.hpp>
+#include "boost/cgi/detail/throw_error.hpp"
 
 namespace cgi {
+ namespace common {
 
+ /// The interface class for any *cgi::acceptor.
   template<typename RequestAcceptorService>
   class basic_request_acceptor
- : private boost::noncopyable
- , public boost::asio::basic_io_object<RequestAcceptorService>
+ : public boost::asio::basic_io_object<RequestAcceptorService>
+ //, private boost::noncopyable
   {
   public:
     // typedef impl_type;
- typedef RequestAcceptorService service_type;
- typedef service_type::protocol_type protocol_type;
+ typedef RequestAcceptorService service_type;
+ typedef typename service_type::protocol_type protocol_type;
+ typedef
+ typename service_type::implementation_type::port_number_type
+ port_number_type;
+ typedef
+ typename service_type::implementation_type::acceptor_service_type
+ next_layer_type;
+ typedef
+ typename service_type::endpoint_type
+ endpoint_type;
+ typedef typename service_type::native_type native_type;
+ typedef
+ typename service_type::service_impl_type::protocol_service_type
+ protocol_service_type;
+
 
- explicit basic_request_acceptor(basic_protocol_service<protocol_type>& s)
- : boost::asio::basic_io_object<RequestAcceptorService>(s.io_service())
+ //template<typename IoServiceProvider>
+ //explicit basic_request_acceptor(
+ // basic_protocol_service<protocol_type, IoServiceProvider>& ps)
+ // : boost::asio::basic_io_object<RequestAcceptorService>(ps.io_service())
+ //{
+ // this->service.set_protocol_service(this->implementation, ps);
+ //}
+
+ template<typename IoServiceProvider>
+ explicit basic_request_acceptor
+ (
+ common::basic_protocol_service<protocol_type, IoServiceProvider>& ps
+ , bool default_init = true
+ )
+ : boost::asio::basic_io_object<RequestAcceptorService>(ps.io_service())
+ {
+ this->service.set_protocol_service(this->implementation, ps);
+ if (default_init)
+ {
+ boost::system::error_code ec;
+ this->service.default_init(this->implementation, ec);
+ if (ec)
+ {
+ boost::system::system_error err(ec, "Problem constructing acceptor");
+ boost::throw_exception(err);
+ }
+ }
+ }
+
+ template<typename IoServiceProvider>
+ explicit basic_request_acceptor(
+ common::basic_protocol_service<protocol_type, IoServiceProvider>& ps,
+ port_number_type port_num)
+ : boost::asio::basic_io_object<RequestAcceptorService>(ps.io_service())
+ {
+ this->service.set_protocol_service(this->implementation, ps);
+ this->implementation.port_num_ = port_num;
+
+ this->implementation.endpoint_.port(port_num);
+ //std::cerr<< "___________ protocol := " <<
+ //(this->implementation.endpoint_.protocol() == boost::asio::ip::tcp::v4()) << std::endl;
+ using boost::asio::ip::tcp;
+ // This strange-looking conditional checks there's no error at each
+ // stage of preparation.
+ boost::system::error_code ec;
+ //if (//this->service.open(this->implementation, tcp::v4(), ec)
+ //||
+ //this->service.bind(this->implementation
+ // , tcp::endpoint(tcp::v4(), port_num), ec)
+ //|| this->service.listen(this->implementation, ec))
+
+ {
+ detail::throw_error(ec);
+ }
+ }
+
+ template<typename IoServiceProvider, typename InternetProtocol>
+ explicit basic_request_acceptor(
+ common::basic_protocol_service<protocol_type, IoServiceProvider>& ps,
+ const boost::asio::ip::basic_endpoint<InternetProtocol>& endpoint,
+ bool reuse_addr = true)
+ : boost::asio::basic_io_object<RequestAcceptorService>(ps.io_service())
     {
+ this->service.set_protocol_service(this->implementation, ps);
+
+ // This strange-looking conditional checks there's no error at each
+ // stage of preparation.
+ boost::system::error_code ec;
+ if (this->service.open(this->implementation, endpoint.protocol(), ec)
+ || this->service.bind(this->implementation, endpoint, ec)
+ || this->service.listen(this->implementation, ec))
+ {
+ detail::throw_error(ec);
+ }
+ }
+
+ template<typename IoServiceProvider, typename InternetProtocol>
+ explicit basic_request_acceptor(
+ common::basic_protocol_service<protocol_type, IoServiceProvider>& ps,
+ const InternetProtocol& ip,
+ const native_type& native_acceptor)
+ : boost::asio::basic_io_object<RequestAcceptorService>(ps.io_service())
+ {
+ this->service.set_protocol_service(this->implementation, ps);
+ boost::system::error_code ec;
+ this->service.assign(this->implementation, ip, native_acceptor, ec);
+ detail::throw_error(ec);
     }
 
     ~basic_request_acceptor()
     {
     }
 
+ protocol_service_type& protocol_service() const
+ {
+ return this->service.protocol_service(this->implementation);
+ }
+
+ /// Check if the acceptor is open
+ bool is_open()
+ {
+ return this->service.is_open(this->implementation);
+ }
+
+ /// Open the acceptor
+ template<typename Protocol>
+ void open(const Protocol& protocol)
+ {
+ boost::system::error_code ec;
+ this->service.open(this->implementation, protocol, ec);
+ detail::throw_error(ec);
+ }
+
+ /// Open the acceptor
+ template<typename Protocol>
+ boost::system::error_code
+ open(const Protocol& protocol, boost::system::error_code& ec)
+ {
+ return this->service.open(this->implementation, protocol, ec);
+ }
+
+ /// Set the acceptor to listen
+ void listen(int backlog = boost::asio::socket_base::max_connections)
+ {
+ boost::system::error_code ec;
+ this->service.listen(this->implementation, backlog, ec);
+ detail::throw_error(ec);
+ }
+
+ /// Set the acceptor to listen
+ boost::system::error_code
+ listen(int backlog, boost::system::error_code& ec)
+ {
+ return this->service.listen(this->implementation, backlog, ec);
+ }
+
+ template<typename Endpoint>
+ boost::system::error_code
+ bind(Endpoint& ep, boost::system::error_code& ec)
+ {
+ return this->service.bind(this->implementation, ep, ec);
+ }
+
+ /// Cancel all asynchronous operations associated with the acceptor.
+ boost::system::error_code
+ cancel()
+ {
+ return this->service.cancel(this->implementation);
+ }
+
+ /// Close the acceptor
+ void close()
+ {
+ boost::system::error_code ec;
+ this->service.close(this->implementation, ec);
+ detail::throw_error(ec);
+ }
+
+ /// Close the acceptor
+ boost::system::error_code
+ close(boost::system::error_code& ec)
+ {
+ return this->service.close(this->implementation, ec);
+ }
+
+ template<typename Protocol>
+ void assign(Protocol protocol, const native_type& native_acceptor)
+ {
+ boost::system::error_code ec;
+ this->service.assign(this->implementation, protocol, native_acceptor, ec);
+ detail::throw_error(ec);
+ }
+
+ template<typename Protocol>
+ boost::system::error_code
+ assign(Protocol protocol, const native_type& native_acceptor
+ , boost::system::error_code& ec)
+ {
+ return this->service.assign(this->implementation, protocol
+ , native_acceptor, ec);
+ }
+
+ /// Accept one request
     template<typename CommonGatewayRequest>
     void accept(CommonGatewayRequest& request)
     {
       boost::system::error_code ec;
- this->service.accept(this->implementation, request, ec);
+ this->service.accept(this->implementation, request, 0, ec);
       detail::throw_error(ec);
     }
 
- template<typename CommonGatewayRequest> boost::system::error_code&
- accept(CommonGatewayRequest& request, boost::system::error_code& ec)
+ /// Accept one request
+ template<typename CommonGatewayRequest>
+ boost::system::error_code
+ accept(CommonGatewayRequest& request, boost::system::error_code& ec)
     {
- return this->service.accept(this->implementation, request, ec);
+ //std::cerr<< "mine:::: endpoint.port := " << this->implementation.endpoint_.port() << std::endl;
+ return this->service.accept(this->implementation, request, 0, ec);
     }
 
+ template<typename CommonGatewayRequest>
+ boost::system::error_code
+ accept(CommonGatewayRequest& request, endpoint_type& ep
+ , boost::system::error_code& ec)
+ {
+ return this->service.accept(this->implementation, request, &ep, ec);
+ }
+
+ //template<typename CommonGatewayRequest, typename Endpoint>
+ //boost::system::error_code
+
+ /// Asynchronously accept one request
     template<typename CommonGatewayRequest, typename Handler>
     void async_accept(CommonGatewayRequest& request, Handler handler)
     {
       this->service.async_accept(this->implementation, request, handler);
     }
+
+ endpoint_type
+ local_endpoint()
+ {
+ boost::system::error_code ec;
+ endpoint_type ep(this->service.local_endpoint(this->implementation, ec));
+ detail::throw_error(ec);
+ return ep;
+ }
+
+ endpoint_type
+ local_endpoint(boost::system::error_code& ec) const
+ {
+ return this->service.local_endpoint(this->implementation, ec);
+ }
   };
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_BASIC_REQUEST_ACCEPTOR_HPP_INCLUDED__
+

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request_fwd.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request_fwd.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_request_fwd.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -16,6 +16,7 @@
 #include "basic_protocol_service_fwd.hpp"
 
 namespace cgi {
+ namespace common {
 
   template<typename RequestService
           , typename ProtocolService
@@ -23,6 +24,7 @@
           , typename Allocator = std::allocator<char> >
   class basic_request;
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_BASIC_REQUEST_FWD_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_sync_io_object.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_sync_io_object.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/basic_sync_io_object.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -12,6 +12,7 @@
 #include <boost/noncopyable.hpp>
 
 namespace cgi {
+ namespace common {
 
   /// basic_io_object alternative when an io_service isn't used
   template<typename Service>
@@ -19,25 +20,26 @@
     : private boost::noncopyable
   {
   public:
- typedef Service service_type;
- typedef typename Service::impl_type impl_type;
+ typedef Service service_type;
+ typedef typename Service::implementation_type implementation_type;
 
   protected:
     explicit basic_sync_io_object()
     {
       std::cerr<< "Hello";
- service.construct(impl);
+ service.construct(implementation);
     }
 
     ~basic_sync_io_object()
     {
- service.destroy(impl);
+ service.destroy(implementation);
     }
 
     service_type service;
- impl_type impl;
+ implementation_type implementation;
   };
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_BASIC_SYNC_IO_OBJECT_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/buffer.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/buffer.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/buffer.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -12,9 +12,14 @@
 #include <boost/asio/buffer.hpp>
 
 namespace cgi {
+ namespace common {
 
   using boost::asio::buffer;
 
+ } // namespace common
+
+ using common::buffer;
+
 } // namespace cgi
 
 #endif // CGI_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -10,8 +10,8 @@
 #define CGI_CGI_HPP_INCLUDED__
 
 // Include all cgi-related headers only.
-#include "boost/cgi/request.hpp"
-#include "boost/cgi/service.hpp"
+#include "boost/cgi/cgi/request.hpp"
+#include "boost/cgi/cgi/service.hpp"
 
 // Include headers common to all protocols
 #include "boost/cgi/detail/common_headers.hpp"
@@ -23,4 +23,13 @@
   
 } // namespace cgi
 
+/// Dump acgi stuff into the boost namespace
+namespace boost {
+ namespace cgi {
+ using namespace ::cgi::cgi;
+ using namespace ::cgi;
+ using namespace ::cgi::common;
+ } // namespace acgi
+} // namespace boost
+
 #endif // CGI_CGI_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -20,8 +20,12 @@
 
   class cgi_service_impl;
 
- typedef basic_request<cgi_request_service, cgi_service> cgi_request;
+ typedef common::basic_request<cgi_request_service, cgi_service> cgi_request;
+ typedef cgi_request request;
 
+ //namespace cgi {
+ // typedef cgi_request request;
+ //} // namespace cgi
 } // namespace cgi
 
 #endif // CGI_CGI_REQUEST_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request_impl.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request_impl.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request_impl.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -15,6 +15,7 @@
 #include <boost/shared_ptr.hpp>
 
 #include "boost/cgi/http/status_code.hpp"
+#include "boost/cgi/basic_client.hpp"
 #include "boost/cgi/connections/stdio.hpp"
 #include "boost/cgi/role_type.hpp"
 #include "boost/cgi/status_type.hpp"
@@ -37,9 +38,12 @@
    * restricted but if someone really wants to copy the data, then they can.
    */
   class cgi_request_impl
- : public cgi_request_impl_base<stdio_connection>
+ : public cgi_request_impl_base<common::stdio_connection>
   {
   public:
+ //typedef stdio_connection client_type;
+ typedef ::cgi::common::basic_client<common::stdio_connection, tags::cgi> client_type;
+
     /// Constructor
     /**
      * Since this request type is synchronous, there is no need for an

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/request_service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -13,10 +13,10 @@
 #include <map>
 #include <boost/system/error_code.hpp>
 
-#include "request_impl.hpp"
-#include "../detail/cgi_service_impl_base.hpp"
-#include "../detail/extract_params.hpp"
-#include "../connections/stdio.hpp"
+#include "boost/cgi/cgi/request_impl.hpp"
+#include "boost/cgi/detail/cgi_service_impl_base.hpp"
+#include "boost/cgi/detail/extract_params.hpp"
+#include "boost/cgi/connections/stdio.hpp"
 
 namespace cgi {
 
@@ -26,7 +26,7 @@
   class cgi_request_service
    : public cgi_service_impl_base<cgi_request_impl>
   {
- typedef ::cgi::map map_type;
+ typedef ::cgi::common::map map_type;
   public:
     typedef cgi_request_impl impl_type;
     typedef tags::cgi protocol_type;
@@ -45,7 +45,9 @@
 
     void construct(implementation_type& impl)
     {
- impl.connection() = implementation_type::connection_type::create();
+ impl.client_.set_connection(
+ implementation_type::connection_type::create()
+ );
     }
 
     void destroy(implementation_type& impl)

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/cgi/service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -13,8 +13,6 @@
 #include "boost/cgi/connections/stdio.hpp"
 #include "boost/cgi/connections/async_stdio.hpp"
 #include "boost/cgi/basic_protocol_service_fwd.hpp"
-#include "boost/cgi/gateway_impl/acgi_gateway_impl.hpp"
-#include "boost/cgi/gateway_service/acgi_gateway_service.hpp"
 
 namespace cgi {
 
@@ -22,7 +20,7 @@
   /**
    * Works with both cgi_request and acgi_request.
    */
- typedef basic_protocol_service<tags::acgi> cgi_service;
+ typedef common::basic_protocol_service<tags::acgi> cgi_service;
 
   /// A service 'owned' by a single user-supplied io_service
   //typedef basic_protocol_service<tags::acgi> cgi_sub_service;

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/async_stdio.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/async_stdio.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/async_stdio.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -14,11 +14,12 @@
 #include <boost/system/error_code.hpp>
 #include <boost/enable_shared_from_this.hpp>
 
-#include "stdio.hpp"
-#include "../io_service.hpp"
-#include "../tags.hpp"
+#include "boost/cgi/connections/stdio.hpp"
+#include "boost/cgi/io_service.hpp"
+#include "boost/cgi/tags.hpp"
 
 namespace cgi {
+ namespace common {
 
   // Asynchronous access to stdio
   template<>
@@ -30,13 +31,23 @@
     typedef basic_connection<tags::async_stdio> type;
     typedef boost::shared_ptr<type> pointer;
 
- basic_connection(io_service& ios)
+ basic_connection(::cgi::io_service& ios)
       : basic_connection<tags::stdio>()
       , io_service_(ios)
     {
     }
 
- static pointer create(cgi::io_service& ios)
+ bool is_open() const
+ {
+ return is_open_;
+ }
+
+ void close()
+ {
+ is_open_ = false;
+ }
+
+ static pointer create(::cgi::io_service& ios)
     {
       return pointer(new basic_connection<tags::async_stdio>(ios));
     }
@@ -108,7 +119,7 @@
     }
 
   private:
- io_service& io_service_;
+ ::cgi::io_service& io_service_;
   };
 
   typedef basic_connection<tags::async_stdio> async_stdio_connection;
@@ -120,6 +131,7 @@
   // typedef basic_connection<tags::async_cgi, ProtocolService> type;
   //};
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_ASYNC_STDIO_HPP_INCLUDED__

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-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -16,13 +16,14 @@
 #include <boost/system/error_code.hpp>
 #include <boost/asio.hpp>
 
-#include "../basic_connection_fwd.hpp"
-#include "../tags.hpp"
-#include "../connection_base.hpp"
-#include "../data_sink.hpp"
-//#include "../io_service.hpp"
+#include "boost/cgi/basic_connection_fwd.hpp"
+#include "boost/cgi/tags.hpp"
+#include "boost/cgi/connection_base.hpp"
+#include "boost/cgi/data_sink.hpp"
+//#include "boost/cgi/io_service.hpp"
 
 namespace cgi {
+ namespace common {
 
   template<>
   class basic_connection<tags::stdio>
@@ -32,20 +33,26 @@
     typedef boost::shared_ptr<basic_connection<tags::stdio> > pointer;
 
     basic_connection()
- : in_(std::cin)
- , out_(std::cout)
- , err_(std::cerr)
+ : is_open_(true)
     {
     }
 
     template<typename T>
     basic_connection(T&)
- : in_(std::cin)
- , out_(std::cout)
- , err_(std::cerr)
+ : is_open_(true)
     {
     }
 
+ bool is_open() const
+ {
+ return is_open_;
+ }
+
+ void close()
+ {
+ is_open_ = false;
+ }
+
     static pointer create()
     {
       return pointer(new basic_connection<tags::stdio>());
@@ -53,12 +60,33 @@
 
     template<typename MutableBufferSequence>
     std::size_t read_some(MutableBufferSequence buf
- , boost::system::error_code& ec
- , cgi::sink origin)
+ , boost::system::error_code& ec)
     {
- if( buf.data() != in_.rdbuf() )
- return in_.read(buf.begin(), buf.size());
- return buf.size();
+ if (std::cin.eof())
+ {
+ //ec = boost::asio::error::eof;
+ return boost::asio::error::eof;
+ }
+ //if( buf.data() != in_.rdbuf() )
+ // return in_.read(buf.begin(), buf.size());
+ //return buf.size();
+
+ //std::cerr<< "In stdio::read_some()" << std::endl
+ // << "before = {" << std::endl
+ // << std::string(boost::asio::buffer_cast<char *>(buf), boost::asio::buffer_size(buf)) << std::endl
+ // << "}" << std::endl;
+ std::cin.read(boost::asio::buffer_cast<char *>(buf)
+ , boost::asio::buffer_size(buf));
+ if (std::cin.fail() && !std::cin.eof())
+ {
+ ec = boost::system::error_code(654, boost::system::system_category);
+ return 0;
+ }
+ //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 std::cin.gcount();
     }
 
     template<typename ConstBufferSequence>
@@ -70,20 +98,23 @@
          ; i != buf.end(); ++i)
       {
         std::size_t buf_len = boost::asio::buffer_size(*i);
- std::string s(boost::asio::buffer_cast<const char*>(*i)
- , buf_len);
         bytes_transferred += buf_len;
- out_.write(s.c_str(), buf_len);
+ std::cout.write(boost::asio::buffer_cast<const char*>(*i), buf_len);
       }
       return bytes_transferred;
     }
 
   protected:
- std::istream& in_;
- std::ostream& out_;
- std::ostream& err_;
+ bool is_open_;
   };
 
+ namespace connection {
+
+ typedef basic_connection<tags::stdio> stdio;
+
+ } // namespace connection
+
+ // Deprecated
   typedef basic_connection<tags::stdio> stdio_connection;
 
   // template<typename ProtocolService = detail::cgi_service>
@@ -92,6 +123,7 @@
   // typedef basic_connection<tags::stdio, ProtocolService> type;
   //};
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/tcp_socket.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/tcp_socket.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/connections/tcp_socket.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -10,31 +10,44 @@
 #define CGI_CONNECTIONS_TCP_SOCKET_HPP_INCLUDED__
 
 #include <boost/shared_ptr.hpp>
+#include <boost/asio/ip/tcp.hpp>
 
-#include "../tags.hpp"
-#include "../io_service.hpp"
-#include "../connection_base.hpp"
-#include "../basic_connection.hpp"
-#include "../detail/push_options.hpp"
+#include "boost/cgi/tags.hpp"
+#include "boost/cgi/io_service.hpp"
+#include "boost/cgi/connection_base.hpp"
+#include "boost/cgi/basic_connection.hpp"
+#include "boost/cgi/detail/push_options.hpp"
 
 namespace cgi {
+ namespace common {
 
   template<>
   class basic_connection<tags::tcp_socket>
     : public connection_base
   {
   public:
- typedef boost::shared_ptr<basic_connection<tags::tcp_socket> >
- pointer;
+ typedef basic_connection<tags::tcp_socket> type;
+ typedef boost::shared_ptr<type> pointer;
+ typedef boost::asio::ip::tcp::socket next_layer_type;
 
     basic_connection(io_service& ios)
       : sock_(ios)
     {
     }
 
+ bool is_open() const
+ {
+ return sock_.is_open();
+ }
+
+ void close()
+ {
+ sock_.close();
+ }
+
     static pointer create(io_service& ios)
     {
- return static_cast<pointer>(new basic_connection<tags::tcp_socket>(ios));
+ return pointer(new basic_connection<tags::tcp_socket>(ios));
     }
 
     template<typename MutableBufferSequence>
@@ -75,26 +88,26 @@
       sock_.async_write_some(buf, handler);
     }
 
- void stop()
+ next_layer_type& next_layer()
     {
- sock_.close();
+ return sock_;
     }
-
   private:
- boost::asio::ip::tcp::socket sock_;
+ next_layer_type sock_;
   };
 
- typedef basic_connection<tags::tcp_socket> tcp_connection;
+ namespace connection {
+
+ typedef basic_connection<tags::tcp_socket> tcp;
 
+ } // namespace connection
 
- //template<typename ProtocolService = detail::fcgi_service>
- //struct tcp_connection
- //{
- // typedef basic_connection<tags::tcp_socket, ProtocolService> type;
- //};
+ // Deprecated
+ typedef basic_connection<tags::tcp_socket> tcp_connection;
 
+ } // namespace common
 } // namespace cgi
 
-#include "../detail/pop_options.hpp"
+#include "boost/cgi/detail/pop_options.hpp"
 
 #endif // CGI_CONNECTIONS_TCP_SOCKET_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/cookie.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/cookie.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/cookie.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -30,7 +30,7 @@
    * TODO
    * - Data should be URL-encoded, or maybe provide an overload for url_decode
    * that takes an HttpCookie?
- * - Add to_string() ?
+ * - Add from_string() ?
    */
   template<typename String>
   struct basic_cookie
@@ -41,7 +41,7 @@
 
     /// Delete the cookie named `_name`.
     basic_cookie(const string_type& _name)
- : content(_name)
+ : name(_name)
       , value()
       , expires("Fri, 05-Jun-1989 15:30:00 GMT")
       , path("/")
@@ -57,7 +57,7 @@
                 , const string_type& _domain = ""
                 , bool _secure = false
                 , bool HttpOnly = false)
- : content(_name)
+ : name(_name)
       , value(_val)
       , expires(_expires)
       , path(_path)
@@ -83,7 +83,7 @@
      * - Parts of the cookie are delimited by '; '. ie. if there is no space,
      * or multiple spaces after the semi-colon, this function won't work...
      */
- /* Actually, I'm omitting these functions for now, just had a though...
+ /* Actually, I'm omitting these functions for now, just had a thought...
     static basic_cookie<string_type>
       from_string(const char* str, boost::system::error_code& ec)
     {
@@ -121,22 +121,24 @@
     /// Make a string out of the cookie
     std::string to_string()
     {
- std::string str(ck.name + "=" + ck.value);
- if (!ck.expires.empty()) str += "; expires=" += ck.expires;
- if (!ck.path.empty() ) str += "; path=" += ck.path;
- if (!ck.domain.empty() ) str += "; domain=" += ck.domain;
- if ( secure ) str += "; secure";
- if ( ck.http_only ) str += "; HttpOnly";
+ std::string str(name + "=" + value);
+ if (!expires.empty()) str += ("; expires=" + expires);
+ if (!path.empty() ) str += ("; path=" + path);
+ if (!domain.empty() ) str += ("; domain=" + domain);
+ if ( secure ) str += "; secure";
+ if ( http_only ) str += "; HttpOnly";
       return str;
     }
   };
 
- template<typename OutStream, typename Cookie>
- OutStream& operator<<(OutStream& os, Cookie ck)
+ template<typename OutStream, typename T>
+ OutStream& operator<<(OutStream& os, basic_cookie<T>& ck)
   {
- return os<< ck.to_string();
+ os<< ck.to_string();
+ return os;
   }
 
 } // namespace cgi
 
 #endif // CGI_COOKIE_HPP_INCLUDED__
+

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/cgi_request_impl_base.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/cgi_request_impl_base.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/cgi_request_impl_base.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -40,13 +40,17 @@
   class cgi_request_impl_base
   {
   public:
- typedef ::cgi::map map_type;
+ typedef ::cgi::common::map map_type;
     typedef Connection connection_type;
+ typedef
+ common::basic_client<Connection, tags::acgi> client_type;
     typedef typename connection_type::pointer conn_ptr;
 
     /// Constructor
     cgi_request_impl_base()
       : stdin_parsed_(false)
+ , stdin_data_read_(false)
+ , stdin_bytes_left_(-1)
       , http_status_(http::ok)
       , request_status_(unloaded)
     {
@@ -57,12 +61,12 @@
     map_type& post_vars() { return post_vars_; }
     map_type& cookie_vars() { return cookie_vars_; }
 
- bool& stdin_parsed() { return stdin_parsed_; }
+ bool stdin_parsed() { return stdin_parsed_; }
     http::status_code& http_status() { return http_status_; }
     status_type& status() { return request_status_; }
 
     conn_ptr& connection() { return connection_; }
- std::string& null_str() { return null_str_; }
+ //std::string& null_str() { return null_str_; }
 
   protected:
     //conn_ptr connection() { return connection_; }
@@ -74,49 +78,18 @@
     map_type post_vars_;
     map_type cookie_vars_;
 
+ public:
     bool stdin_parsed_;
+ bool stdin_data_read_;
+ std::size_t stdin_bytes_left_;
+ protected:
 
     http::status_code http_status_;
     status_type request_status_;
 
     conn_ptr connection_;
-
- std::string null_str_;
   };
 
- //template<> inline const std::string&
- //cgi_request_impl::var<tags::ENV>(const std::string& name)
- //{
- // return ::getenv(name.c_str());
- //}
-
- /// Get a request map of all the environment meta-variables (slow)
- /**
- * -- NOT IMPLEMENTED FOR NOW --
- *
- * In the case of a CGI request, the environment meta-data is usually stored
- * in the process environment, which means there is no direct access to all
- * of them as a map_type&. In other words, this function call will have to
- * load all of the variables into memory and then return the map
- */
- //template<> inline cgi_request_impl::map_type&
- //cgi_request_impl::var<tags::ENV>()
- //{
- // throw std::logic_error("Can't get all environment vars as a map_type&");
- //}
-
- //template<> inline cgi_request_impl::map_type&
- //cgi_request_impl::var<tags::HTTP>() { return http_map_; }
-
- //template<> inline cgi_request_impl::map_type&
- //cgi_request_impl::var<tags::COOKIE>() { return cookie_map_; }
-
- //template<> inline cgi_request_impl::map_type&
- //cgi_request_impl::var<tags::GET>() { return get_map_; }
-
- //template<> inline cgi_request_impl::map_type&
- //cgi_request_impl::var<tags::POST>() { return post_map_; }
-
 } // namespace cgi
 
 #endif // CGI_CGI_REQUEST_IMPL_BASE_HPP_INCLUDED__

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-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -1,21 +1,28 @@
 #ifndef CGI_CGI_SERVICE_IMPL_BASE_HPP_INCLUDED__
 #define CGI_CGI_SERVICE_IMPL_BASE_HPP_INCLUDED__
 
-#include "../detail/push_options.hpp"
+#include "boost/cgi/detail/push_options.hpp"
 
 #include <string>
 #include <cstdlib>
 #include <iostream>
 #include <boost/assert.hpp>
+#include <boost/regex.hpp>
 #include <boost/tokenizer.hpp>
+#include <boost/lexical_cast.hpp>
 #include <boost/system/error_code.hpp>
+#include <boost/algorithm/string/find.hpp>
 
 #include "boost/cgi/map.hpp"
+#include "boost/cgi/basic_client.hpp"
 #include "boost/cgi/role_type.hpp"
 #include "boost/cgi/status_type.hpp"
 #include "boost/cgi/detail/extract_params.hpp"
 #include "boost/cgi/detail/save_environment.hpp"
-//#include "../connections/stdio.hpp"
+#include "boost/cgi/common/form_part.hpp"
+#include "boost/cgi/detail/throw_error.hpp"
+
+#include "boost/cgi/common/form_parser.hpp"
 
 namespace cgi {
 
@@ -24,16 +31,16 @@
 
  } // namespace detail
 
- using std::cerr;
- using std::endl;
+ using std::cerr; // **FIXME**
+ using std::endl; // **FIXME**
 
 
   template<typename RequestImplType>
   class cgi_service_impl_base
   {
   public:
- typedef RequestImplType implementation_type;
- typedef cgi::map map_type;
+ //typedef RequestImplType implementation_type;
+ typedef ::cgi::common::map map_type;
 
     cgi_service_impl_base()
     {
@@ -44,6 +51,110 @@
     {
     }
 
+ 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;
+
+ implementation_type()
+ : //buffer_()
+ //, istream_(&buffer_)
+ pos_()
+ , offset_(0)
+ , 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_;
+ }
+
+ 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
     /**
      * For CGI, this always returns true. However, in the case that a
@@ -56,10 +167,10 @@
     }
 
     /// Return the connection associated with the request
- typename implementation_type::connection_type&
- client(implementation_type& impl)
+ typename implementation_type::client_type&
+ client(implementation_type& impl)
     {
- return *impl.connection();
+ return impl.client_;
     }
 
     int close(implementation_type& impl, http::status_code& http_s, int status)
@@ -74,11 +185,15 @@
      * @param parse_stdin if true then STDIN data is also read/parsed
      */
     boost::system::error_code&
- load(implementation_type& impl, bool parse_stdin
- , boost::system::error_code& ec)
+ load(implementation_type& impl, bool parse_stdin
+ , boost::system::error_code& ec)
     {
       detail::save_environment(impl.env_vars());
- const std::string& request_method = impl.env_vars()["REQUEST_METHOD"];
+ const std::string& cl = var(impl.env_vars(), "CONTENT_LENGTH", ec);
+ impl.characters_left_ = cl.empty() ? 0 : boost::lexical_cast<std::size_t>(cl);
+ impl.client_.bytes_left() = impl.characters_left_;
+
+ const std::string& request_method = var(impl.env_vars(), "REQUEST_METHOD", ec);
       if (request_method == "GET")
         parse_get_vars(impl, ec);
       else
@@ -89,44 +204,31 @@
 
       parse_cookie_vars(impl, ec);
       impl.status() = loaded;
- BOOST_ASSERT(impl.status() >= loaded);
-
- return ec;
- }
 
- template<typename MutableBufferSequence>
- std::size_t read_some(implementation_type& impl
- , const MutableBufferSequence& buf
- , boost::system::error_code& ec)
- {
- std::size_t s = impl.connection()->read_some(buf, ec);
- return s;
- }
+ //BOOST_ASSERT(impl.status() >= loaded);
 
- template<typename ConstBufferSequence>
- std::size_t write_some(implementation_type& impl
- , const ConstBufferSequence& buf
- , boost::system::error_code& ec)
- {
- return impl.connection()->write_some(buf, ec);
+ return ec;
     }
 
- std::string& var(map_type& meta_data, const std::string& name
- , boost::system::error_code& ec)
+ std::string&
+ var(map_type& meta_data, const std::string& name
+ , boost::system::error_code& ec)
     {
       return meta_data[name];
     }
 
- std::string meta_get(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
+ std::string
+ GET(implementation_type& impl, const std::string& name
+ , boost::system::error_code& ec)
     {
- BOOST_ASSERT(impl.status() >= loaded);
+ //BOOST_ASSERT(impl.status() >= loaded);
       return var(impl.get_vars(), name, ec);
     }
 
- map_type& meta_get(implementation_type& impl)
+ map_type&
+ GET(implementation_type& impl)
     {
- BOOST_ASSERT(impl.status() >= loaded);
+ //BOOST_ASSERT(impl.status() >= loaded);
       return impl.get_vars();
     }
 
@@ -142,11 +244,11 @@
      -----------------------------------------------
 
      */
- std::string meta_post(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec
- , bool greedy = true)
+ std::string
+ POST(implementation_type& impl, const std::string& name
+ , boost::system::error_code& ec, bool greedy = true)
     {
- BOOST_ASSERT(impl.status() >= loaded);
+ //BOOST_ASSERT(impl.status() >= loaded);
       const std::string& val = var(impl.post_vars(), name, ec);
       if (val.empty() && greedy && !ec)
       {
@@ -156,45 +258,88 @@
       return val;
     }
 
- map_type& meta_post(implementation_type& impl)
+ map_type&
+ POST(implementation_type& impl)
     {
- BOOST_ASSERT(impl.status() >= loaded);
+ //BOOST_ASSERT(impl.status() >= loaded);
       return impl.post_vars();
     }
 
+ // prefer this to the above
+ map_type&
+ POST(implementation_type& impl, boost::system::error_code& ec)
+ {
+ //BOOST_ASSERT(impl.status() >= loaded);
+ return impl.post_vars();
+ }
+
+ // TODO: use `greedy`
+ std::string
+ form(implementation_type& impl, const std::string& name
+ , boost::system::error_code& ec, bool greedy)
+ {
+ std::string rm(env(impl, "REQUEST_METHOD", ec));
+ //BOOST_ASSERT(!ec && !rm.empty());
+ if (rm == "GET")
+ return GET(impl, name, ec);
+ else
+ if (rm == "POST")
+ return POST(impl, name, ec);
+ else
+ return "***BOOST_CGI_ERROR_INVALID_REQUEST_METHOD***";
+ }
+
+ // TODO: use `greedy`
+ map_type&
+ form(implementation_type& impl, boost::system::error_code& ec
+ , bool greedy)
+ {
+ std::string rm(env(impl, "REQUEST_METHOD", ec));
+ //BOOST_ASSERT(!ec && !rm.empty());
+ if (rm == "GET")
+ return GET(impl);
+ else
+ if (rm == "POST")
+ return POST(impl, ec);
+ }
 
     /// Find the cookie meta-variable matching name
- std::string cookie(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
+ std::string
+ cookie(implementation_type& impl, const std::string& name
+ , boost::system::error_code& ec)
     {
- BOOST_ASSERT(impl.status() >= loaded);
+ //BOOST_ASSERT(impl.status() >= loaded);
       return var(impl.cookie_vars(), name, ec);
     }
 
- map_type& meta_cookie(implementation_type& impl)
+ map_type&
+ cookie(implementation_type& impl)
     {
- BOOST_ASSERT(impl.status() >= loaded);
+ //BOOST_ASSERT(impl.status() >= loaded);
       return impl.cookie_vars();
     }
 
 
     /// Find the environment meta-variable matching name
- std::string meta_env(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
+ std::string
+ env(implementation_type& impl, const std::string& name
+ , boost::system::error_code& ec)
     {
- BOOST_ASSERT(impl.status() >= loaded);
+ //BOOST_ASSERT(impl.status() >= loaded);
       const char* c = ::getenv(name.c_str());
- return c ? c : impl.null_str();
+ return c ? c : std::string();
     }
 
- map_type& meta_env(implementation_type& impl)
+ map_type&
+ env(implementation_type& impl)
     {
- BOOST_ASSERT(impl.status() >= loaded);
+ //BOOST_ASSERT(impl.status() >= loaded);
       return impl.env_vars();
     }
 
 
- role_type get_role(implementation_type& impl)
+ role_type
+ get_role(implementation_type& impl)
     {
       return responder;
     }
@@ -207,11 +352,11 @@
   protected:
     /// Read and parse the cgi GET meta variables
     template<typename RequestImpl>
- boost::system::error_code&
+ boost::system::error_code
     parse_get_vars(RequestImpl& impl, boost::system::error_code& ec)
     {
       // Make sure the request is in a pre-loaded state
- BOOST_ASSERT (impl.status() <= unloaded);
+ //BOOST_ASSERT (impl.status() <= unloaded);
 
       std::string& vars = impl.env_vars()["QUERY_STRING"];
       if (vars.empty())
@@ -227,11 +372,11 @@
 
     /// Read and parse the HTTP_COOKIE meta variable
     template<typename RequestImpl>
- boost::system::error_code&
+ boost::system::error_code
     parse_cookie_vars(RequestImpl& impl, boost::system::error_code& ec)
     {
       // Make sure the request is in a pre-loaded state
- BOOST_ASSERT (impl.status() <= unloaded);
+ //BOOST_ASSERT (impl.status() <= unloaded);
 
       std::string& vars(impl.env_vars()["HTTP_COOKIE"]);
       if (vars.empty())
@@ -247,37 +392,55 @@
 
     /// Read and parse the cgi POST meta variables (greedily)
     template<typename RequestImpl>
- boost::system::error_code&
+ boost::system::error_code
     parse_post_vars(RequestImpl& impl, boost::system::error_code& ec)
     {
       // Make sure this function hasn't already been called
- BOOST_ASSERT (!impl.stdin_parsed());
+ //BOOST_ASSERT (!impl.stdin_parsed());
+
+ std::string content_type (var(impl.env_vars(), "CONTENT_TYPE", ec));
+
+ BOOST_ASSERT(!content_type.empty());
+
+ if (boost::algorithm::ifind_first(content_type,
+ "application/x-www-form-urlencoded"))
+ {
+ detail::throw_error(
+ parse_url_encoded_form(impl, ec)
+ );
+ }
+ else
+ {
+ detail::throw_error(
+ parse_multipart_form(impl, ec)
+ );
+ }
+
+ return ec;
+ }
 
+ boost::system::error_code
+ 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;
- cgi::map& post_map(impl.post_vars());
-
- const char* a = ::getenv("content_length");
- if (a) str = a;
- else std::cerr<< "no content-length";
-
- std::cerr<< "content length = ";
- //var(impl.get_vars(), "CONTENT_LENGTH", ec);
- std::cerr.flush();
+ map_type& post_map(impl.post_vars());
 
- while( is.get(ch) )
+ while( is.get(ch) && impl.characters_left_-- )
       {
- std::cerr<< "; ch=" << ch << "; ";
+ //std::cerr<< "; ch=" << ch << "; ";
           switch(ch)
           {
           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 += ' ';
+ str.append(1, ' ');
               break;
           case ' ':
               continue;
@@ -291,21 +454,504 @@
               name.clear();
              break;
           default:
- str += ch;
+ str.append(1, ch);
           }
       }
       // save the last param (it won't have a trailing &)
       if( !name.empty() )
           post_map[name] = str;//.empty() ? "" : str;
+
+
+ return ec;
+ }
+
+ /// Parse a multipart form.
+ boost::system::error_code
+ parse_multipart_form(implementation_type& impl, boost::system::error_code& ec)
+ {
+ parse_boundary_marker(impl, ec);
+ //parse_one_form_part(impl, ec);
+ move_to_start_of_first_part(impl, ec);
+ if (ec == boost::asio::error::eof) {
+ cerr<< " -- Parsing done -- " << endl;
+ //return ec.clear();
+ return boost::system::error_code();
+ }
+
+ do {
+ parse_form_part(impl, ec);
+ }while( !impl.stdin_parsed_ && impl.client_.bytes_left() != 0 );
+
+ // Do this just for now, for debugging
+ parse_url_encoded_form(impl, ec);
+ return ec;
+ }
+
+ boost::system::error_code
+ parse_form_part(implementation_type& impl, boost::system::error_code& ec)
+ {
+ if (!parse_form_part_meta_data(impl, ec)
+ && !parse_form_part_data(impl, ec))
+ return ec;
 
+ return ec;
+ }
 
+ boost::system::error_code
+ parse_form_part_data(implementation_type& impl, boost::system::error_code& ec)
+ {
+ std::string regex("^(.*?)" // the data
+ "\\x0D\\x0A" // CR LF
+ "--" "(");
+ if (impl.boundary_markers.size() > 1)
+ {
+ std::list<std::string>::iterator i(impl.boundary_markers.begin());
+ regex = regex + "(?:" + *i + ")";
+ ++i;
+ for(; i != impl.boundary_markers.end(); ++i)
+ {
+ regex = regex + "|(?:" + *i + ")";
+ }
+ }
+ else
+ {
+ regex += *impl.boundary_markers.begin();
+ }
+
+ regex += ")(--)?[ ]*\\x0D\\x0A";
+ cerr<< "Regex: " << regex << endl;
+ boost::regex re(regex);
+
+ typedef typename
+ implementation_type::buffer_type::iterator
+ buffer_iter;
+
+ boost::match_results<buffer_iter> matches;
+
+ std::size_t offset = impl.offset_;
+ cerr<< "offset = " << offset << endl;
+
+ //int runs = 0;
+ buffer_iter begin(impl.buf_.begin() + offset);
+ buffer_iter end(impl.buf_.end());
+
+ for(;;)
+ {
+ cerr<< "Starting regex_search" << endl;
+ if (!boost::regex_search(begin, end, matches, re
+ , boost::match_default
+ | boost::match_partial))
+ {
+ cerr<< "Can't match any of this. {" << endl
+ << std::string(begin, end) << endl
+ << "}" << endl;
+ return boost::system::error_code(345, boost::system::system_category);
+ }
+ else
+ {
+ for (unsigned int i = 0; i < matches.size(); ++i)
+ {
+ if (matches[i].length())
+ {
+ cerr<< "[" << i << "] == {" << endl
+ << matches[i] << endl
+ << "}" << endl;
+ }
+ }
+ // cerr<< "matches[0] = {" << endl
+ // << matches[0].str() << endl
+ // << "}" << endl;
+ if (matches[1].matched)
+ {
+ impl.form_parts_.back().buffer_
+ // = boost::range_iterator<;
+ = std::make_pair(matches[1].first, matches[1].second);
+ cerr<< "Saved buffer (size: "
+ << std::distance(matches[1].first, matches[1].second)
+ << ") := { " << impl.form_parts_.back().name << ", " << matches[1] << " }" << endl;
+ impl.post_vars()[impl.form_parts_.back().name] = matches[1];
+ impl.offset_ = offset + matches[0].length();
+ //offset += matches[0].length();
+ impl.pos_ = matches[0].second;
+ cerr<< "offset := " << offset << endl
+ << "impl.offset_ := " << impl.offset_ << endl;
+
+ if (matches[3].matched)
+ impl.stdin_parsed_ = true;
+ //if (impl.client_.bytes_left() == 0)
+ //{
+ // cerr<< "Read all the bytes up." << endl;
+ //impl.stdin_parsed_ = true;
+ return ec;
+ //}
+ }
+ else
+ {
+ cerr<< "Reading more data." << endl;
+ std::size_t bytes_read = impl.client_.read_some(impl.prepare(64), ec);
+ //impl.stdin_bytes_read_ += bytes_read;
+
+ if (bytes_read == 0)
+ {
+ impl.stdin_data_read_ = true;
+ return ec;
+ }
+
+ begin = impl.buf_.begin() + offset;
+ end = impl.buf_.end();
+ cerr<< "Buffer (+" << bytes_read << ") == {" << endl
+ << std::string(begin, end) << endl
+ << "}" << endl;
+
+ if (ec)
+ {
+ cerr<< "Error in parse_form_part_data()." << endl;
+ return ec;
+ }
+
+ }
+ }
+
+ }
+
 
       return ec;
     }
 
+ boost::system::error_code
+ parse_form_part_meta_data(implementation_type& impl, 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 typename
+ implementation_type::buffer_type::iterator
+ buffer_iter;
+
+ boost::match_results<
+ typename
+ implementation_type::buffer_type::iterator
+ > matches;
+
+ std::size_t offset = impl.offset_;
+ cerr.flush();
+ impl.pos_ = impl.buf_.begin();
+ int runs = 0;
+ cerr<< "Entering for() loop." << endl;
+ 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))
+ {
+ cerr<< "No chance of a match, quitting." << endl;
+ impl.stdin_parsed_ = true;
+ return ec;
+ }
+ cerr<< "matches.str() == {" << endl
+ << matches.str() << endl
+ << "}" << endl
+ << matches.size() << " submatches" << endl;
+ for (unsigned i = matches.size(); i != 0; --i)
+ {
+ cerr<< "match[" << i << "] := { " << matches[i] << " }" << endl;
+ }
+ 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];
+ cerr<< "Saved name" << endl;
+ }
+ else
+ {
+ part.meta_data_[matches[i]]
+ = std::make_pair(matches[i+1].first, matches[i+1].second);
+ cerr<< "Part := { " << matches[i] << ", " << matches[i+1] << " }" << endl;
+ //= boost::iterator_range<buffer_iter>(matches[3].first, matches[3].second);
+ }
+ impl.form_parts_.push_back(part);
+
+
+ }
+
+ if (matches[13].str() == "\r\n")
+ {
+ impl.offset_ = offset + matches[0].length();
+ offset += matches[0].length();
+ impl.pos_ = matches[0].second;
+
+ //cerr<< "Current buffer == {" << endl
+ // << impl.buffer_string() << endl
+ // << "}" << endl;
+ cerr<< "Leaving parse_form_part_meta_data()" << endl;
+ return ec;
+ }
+ else
+ {
+ throw std::runtime_error("Invalid POST data (header wasn't terminated as expected)");
+ }
+
+ }else{
+ cerr<< "Not read enough data yet, reading more." << endl;
+ bytes_read = impl.client_.read_some(impl.prepare(64), ec);
+ if (ec)
+ {
+ cerr<< "Error reading data: " << ec.message() << endl;
+ cerr<< "Leaving parse_form_part_meta_data()" << endl;
+ return ec;
+ }
+ cerr<< "Read " << bytes_read << " bytes." << endl;
+ cerr<< "buffer = {" << endl
+ << impl.buffer_string() << endl
+ << "} or {" << endl;
+ //<< std::string(impl.pos_, ;
+ /*
+ for (unsigned int i = 0; i < matches.size(); ++i)
+ {
+ if (matches[i].length())
+ {
+ cerr<< "[" << i << "] == {" << endl
+ << matches[i] << endl
+ << "}" << endl;
+ }
+ }
+ cerr<< "-------buf------" << endl
+ << std::string(begin, end) << endl
+ << "----------------" << endl;
+ */
+ //offset = impl.buf_.end();
+ if (++runs > 40)
+ {
+ cerr<< "Run 40 times; bailing out." << endl;
+ break;
+ }
+ cerr<< "Waiting buffer (unparsed) == {" << endl << std::flush
+ << impl.buffer_string() << endl
+ << "}" << endl
+ << "offset = " << offset << endl;
+ //if (bytes_read == 0)
+ // break;
+ }
+ }
+
+ //cerr<< "impl.part
+
+ cerr<< "Leaving parse_form_part_meta_data()" << endl;
+ return ec;
+ }
+
+ boost::system::error_code
+ move_to_start_of_first_part(implementation_type& impl, boost::system::error_code& ec)
+ {
+ //cerr<< "Marker = " << impl.boundary_markers.front() << endl
+ // << "blah" << "--" + impl.boundary_markers.front() + ")" << endl;
+ boost::regex re("((?:.*)?" // optional leading characters
+ //"(?:\\x0D\\x0A)|^" // start of line
+ "[\\x0D\\x0A^]*?"
+ "("
+ "--" + impl.boundary_markers.front() + // two dashes and our marker
+ ")"
+ "(--)?" // optional two dashes (not sure if this is allowed)
+ " *\\x0D\\x0A)");
+ // on the first marker.
+
+ typedef typename
+ implementation_type::buffer_type::iterator
+ buffer_iter;
+
+ boost::match_results<
+ typename
+ implementation_type::buffer_type::iterator
+ > matches;
+ //cerr<< "Boundary marker == {" << endl
+ // << impl.boundary_marker << endl
+ // << "}" << endl;
+
+ // 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 = impl.client_.read_some(impl.prepare(32), ec);
+// if (ec || (bytes_read == 0))
+// return ec;
+ std::size_t bytes_read = 0;
+ for(;;)
+ {
+ bytes_read = impl.client_.read_some(impl.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))
+ {
+ // No chance of matching input with expected, so erase it and start again.
+ //std::cerr<< " == buffer = " << std::string(impl.buf_.begin(), impl.buf_.end())
+ // << " == capacity = " << impl.buf_.capacity() << " ======= ";
+ //impl.buf_.clear();
+ cerr<< "No chance of matching." << endl;
+ offset = impl.buf_.size();
+ //std::cerr<< "Buffer cleared." << endl;
+ continue;
+ }
+ else
+ {
+ //std::cerr<< "regex_search == true" << std::endl
+ // << "matches[0] =={{ " << matches[0] << " }}=== " << std::endl
+ // << "matches[1] =={{ " << matches[1] << " }}=== " << std::endl
+ // << "matches[2] =={{ " << matches[2] << " }}=== " << std::endl;
+ if (matches[2].matched){
+ cerr<< "Found boundary marker... OK!!" << endl;
+ //cerr<< "[0] = " << matches[0].str() << endl;
+ //cerr<< "[1] = " << matches[1].str() << endl;
+ //impl.offset_ = matches[1].length();
+ //impl.pos_ = matches[0].second;
+ //cerr<< "setting pos_ to < " << std::string(impl.pos_, impl.pos_ + 5) << "... >" << endl
+ // << "setting offset_ = " << impl.offset_ << endl;
+ // << std::string(matches[1].first, matches[1].second) << endl;
+ //impl.pos_ = matches[1].second;
+ //cerr<< "deleting {" << endl
+ // << std::string(impl.buf_.begin(), matches[0].second) << endl
+ // << "} leaving {" << endl
+ // << std::string(matches[0].second, impl.buf_.end()) << endl
+ // << "}" << endl;
+ //cerr<< "bufsize = " << impl.buf_.size() << endl;
+ //cerr<< "bufsize = " << impl.buf_.size() << endl;
+ cerr<< "buffer now (before erase) == {" << endl
+ << std::string(impl.buf_.begin(), impl.buf_.end()) << endl
+ << "}" << endl;
+ impl.buf_.erase(impl.buf_.begin(), matches[0].second);
+ impl.offset_ = 0;
+ impl.pos_ = impl.buf_.begin();
+ return ec;
+ } else {
+ cerr<< "not read enough data" << std::endl;
+ //std::cerr<< "; bytes_read = " << bytes_read
+ // << "; bufsize = " << impl.buf_.size()
+ // << "; capacity = " << impl.buf_.capacity() << std::flush
+ // << "; data = {{" << std::string(impl.buf_.begin(), impl.buf_.end()) << "}}";
+
+ if (++runs > 10)
+ return ec;
+ continue;
+ }
+ }
+ }
+
+
+ // skip that line and then erase the buffer
+ return ec;
+ }
+
+ boost::system::error_code
+ parse_one_form_part(implementation_type& impl, 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--" + impl.boundary_marker + " +
+
+ for(;;)
+ {
+ //if (impl.client_.read_some(impl.prepare(1024), ec))
+ // return ec;
+ //boost::asio::read_until(impl.client_, impl.buffer_, impl.boundary_marker, ec);
+ break;
+
+
+ }
+
+ return ec;
+ }
+
+ /// Get the boundary marker from the CONTENT_TYPE header.
+ boost::system::error_code
+ parse_boundary_marker(implementation_type& impl, boost::system::error_code& ec)
+ {
+ // get the meta-data appended to the content_type
+ std::string content_type(var(impl.env_vars(), "CONTENT_TYPE", ec));
+ //BOOST_ASSERT(!content_type.empty());
+
+ //boost::algorithm::ifind(var(impl, "CONTENT_TYPE"), "bounday="
+
+ 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);
+
+ impl.boundary_marker = match_results[1].str();
+ // 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&
+ boost::system::error_code
     parse_one_post_var(RequestImpl& impl, boost::system::error_code& ec)
     {
       //# error "Not implemented"
@@ -315,6 +961,7 @@
 
 } // namespace cgi
 
-#include "../detail/pop_options.hpp"
+#include "boost/cgi/detail/pop_options.hpp"
 
 #endif // CGI_CGI_SERVICE_IMPL_HPP_INCLUDED__
+

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/common_headers.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/common_headers.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/common_headers.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -22,5 +22,7 @@
 //#include "boost/cgi/logger.hpp"
 #include "boost/cgi/read.hpp"
 #include "boost/cgi/write.hpp"
+#include "boost/cgi/header.hpp"
+#include "boost/cgi/return.hpp"
 
 #endif // CGI_CGI_CGI_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/protocol_traits.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/protocol_traits.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/protocol_traits.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -6,9 +6,17 @@
 // http://www.boost.org/LICENSE_1_0.txt)
 //
 ////////////////////////////////////////////////////////////////
+//
+// Wow this is messy. It's not expected to last though; it's
+// merely here to make things more separated than they need to
+// be, so everything can be meshed together slowly.
+// (or something like that)
+//
+/////////////////////////////////////////////////////////////////
 #ifndef CGI_REQUEST_TRAITS_HPP_INCLUDED__
 #define CGI_REQUEST_TRAITS_HPP_INCLUDED__
 
+#include <boost/shared_ptr.hpp>
 #include "boost/cgi/tags.hpp"
 #include "boost/cgi/basic_request_fwd.hpp"
 #include "boost/cgi/basic_connection_fwd.hpp"
@@ -16,42 +24,57 @@
 
 namespace cgi {
 
+ namespace cgi {}
+ namespace acgi {}
+ namespace fcgi
+ {
+ class fcgi_request_impl;
+ class fcgi_service_impl;
+ class fcgi_gateway_impl;
+ class fcgi_gateway_service;
+ class fcgi_request_service;
+ class fcgi_acceptor_service;
+ }
+ namespace scgi
+ {
+ class scgi_request_impl;
+ class scgi_service_impl;
+ class scgi_gateway_impl;
+ class scgi_gateway_service;
+ class scgi_request_service;
+ class scgi_acceptor_service;
+ }
+
   // Forward declarations
 
   class cgi_request_impl;
   class acgi_request_impl;
   class async_cgi_request_impl;
   class fcgi_request_impl;
- class scgi_request_impl;
 
   //template<typename>
   class cgi_service_impl;
   class acgi_service_impl;
   class async_cgi_service_impl;
   class fcgi_service_impl;
- class scgi_service_impl;
 
   class cgi_gateway_impl;
   class acgi_gateway_impl;
   class async_cgi_gateway_impl;
   class fcgi_gateway_impl;
- class scgi_gateway_impl;
 
   class cgi_gateway_service;
   class acgi_gateway_service;
   class async_cgi_gateway_service;
   class fcgi_gateway_service;
- class scgi_gateway_service;
   template<typename> class gateway_service;
 
   class acgi_acceptor_service;
- class scgi_acceptor_service;
   class fcgi_acceptor_service;
 
   class cgi_request_service;
   class acgi_request_service;
   class fcgi_request_service;
- class scgi_request_service;
 
  namespace detail {
 
@@ -63,13 +86,15 @@
     template<>
     struct protocol_traits<tags::cgi>
     {
+ typedef protocol_traits<tags::cgi> type;
       typedef cgi_request_impl impl_type;
- typedef cgi_request_service request_service_type;
- typedef basic_protocol_service<tags::cgi> protocol_service_type;
- typedef basic_request<request_service_type, protocol_service_type>
- request_type;
+ typedef cgi_request_service request_service_impl;
+ typedef common::basic_protocol_service<tags::cgi> protocol_service_type;
+ typedef common::basic_request<
+ request_service_impl, protocol_service_type
+ > request_type;
       typedef cgi_service_impl service_impl_type;
- typedef basic_connection<tags::stdio> connection_type;
+ typedef common::basic_connection<tags::stdio> connection_type;
 // typedef cgi_gateway_impl gateway_impl_type;
 // typedef cgi_gateway_service gateway_service_impl_type;
     };
@@ -77,13 +102,15 @@
     template<>
     struct protocol_traits<tags::async_cgi>
     {
+ typedef protocol_traits<tags::async_cgi> type;
       typedef async_cgi_request_impl impl_type;
- typedef acgi_request_service request_service_type;
- typedef basic_protocol_service<tags::acgi> protocol_service_type;
- typedef basic_request<request_service_type, protocol_service_type>
- request_type;
+ typedef acgi_request_service request_service_impl;
+ typedef common::basic_protocol_service<tags::acgi> protocol_service_type;
+ typedef common::basic_request<
+ request_service_impl, protocol_service_type
+ > request_type;
       typedef async_cgi_service_impl service_impl_type;
- typedef basic_connection<tags::async_stdio> connection_type;
+ typedef common::basic_connection<tags::async_stdio> connection_type;
       typedef async_cgi_gateway_impl gateway_impl_type;
       typedef async_cgi_gateway_service gateway_service_type;
     };
@@ -94,12 +121,13 @@
     {
       typedef protocol_traits<tags::acgi> type;
       typedef acgi_request_impl impl_type;
- typedef acgi_request_service request_service_type;
- typedef basic_protocol_service<tags::acgi> protocol_service_type;
- typedef basic_request<request_service_type, protocol_service_type>
- request_type;
+ typedef acgi_request_service request_service_impl;
+ typedef common::basic_protocol_service<tags::acgi> protocol_service_type;
+ typedef common::basic_request<
+ request_service_impl, protocol_service_type
+ > request_type;
       typedef acgi_service_impl service_impl_type;
- typedef basic_connection<tags::async_stdio> connection_type;
+ typedef common::basic_connection<tags::async_stdio> connection_type;
       typedef acgi_gateway_impl gateway_impl_type;
       typedef acgi_gateway_service gateway_service_type;
     };
@@ -107,30 +135,52 @@
     template<>
     struct protocol_traits<tags::fcgi>
     {
- typedef fcgi_request_impl impl_type;
- typedef fcgi_request_service request_service_type;
- typedef basic_protocol_service<tags::fcgi> protocol_service_type;
- typedef basic_request<request_service_type, protocol_service_type>
- request_type;
- typedef fcgi_service_impl service_impl_type;
- typedef basic_connection<tags::tcp_socket> connection_type;
- typedef fcgi_gateway_impl gateway_impl_type;
- typedef fcgi_gateway_service gateway_service_type;
+ typedef protocol_traits<tags::fcgi> type;
+ typedef fcgi::fcgi_request_impl impl_type;
+ typedef fcgi::fcgi_request_service request_service_impl;
+ typedef common::basic_protocol_service<fcgi_> protocol_service_type;
+ typedef common::basic_request<
+ request_service_impl, protocol_service_type
+ > request_type;
+ typedef boost::shared_ptr<request_type> request_ptr;
+ //typedef fcgi_request_service
+ // ::implementation_type request_impl_type;
+ typedef fcgi::fcgi_service_impl service_impl_type;
+ typedef fcgi::fcgi_acceptor_service acceptor_service_impl;
+ typedef common::basic_connection<
+ tags::shareable_tcp_socket
+ > connection_type;
+ //typedef fcgi_gateway_impl gateway_impl_type;
+ //typedef fcgi_gateway_service gateway_service_type;
     };
 
     template<>
     struct protocol_traits<tags::scgi>
     {
- typedef scgi_request_impl impl_type;
- typedef scgi_request_service request_service_type;
- typedef basic_protocol_service<tags::scgi> protocol_service_type;
- typedef basic_request<request_service_type, protocol_service_type>
- request_type;
- typedef scgi_service_impl service_impl_type;
- typedef scgi_acceptor_service acceptor_service_impl;
- typedef basic_connection<tags::tcp_socket> connection_type;
- typedef scgi_gateway_impl gateway_impl_type;
- typedef scgi_gateway_service gateway_service_type;
+ typedef protocol_traits<tags::scgi> type;
+ typedef scgi::scgi_request_impl impl_type;
+ typedef scgi::scgi_request_service request_service_impl;
+ typedef common::basic_protocol_service<tags::scgi> protocol_service_type;
+ typedef common::basic_request<
+ request_service_impl, protocol_service_type
+ > request_type;
+ typedef scgi::scgi_service_impl service_impl_type;
+ typedef scgi::scgi_acceptor_service acceptor_service_impl;
+ typedef common::basic_connection<tags::tcp_socket> connection_type;
+ //typedef scgi_gateway_impl gateway_impl_type;
+ //typedef scgi_gateway_service gateway_service_type;
+ };
+
+ template<>
+ struct protocol_traits< ::cgi::scgi_>
+ : protocol_traits<tags::scgi>
+ {
+ };
+
+ template<>
+ struct protocol_traits< ::cgi::fcgi_>
+ : protocol_traits<tags::fcgi>
+ {
     };
 
  } // namespace detail

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-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -15,8 +15,13 @@
 #include "boost/cgi/map.hpp"
 
 // The process' environment
-// MSVC warns of 'inconsistent dll linkage' here...
-extern char** environ;
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ // MSVC warns of 'inconsistent dll linkage' here...
+ _CRTIMP extern char** environ;
+#else
+ extern char** environ;
+#endif
+
 
 namespace cgi {
  namespace detail {
@@ -26,8 +31,8 @@
     * @param env This defaults to `::environ`, or the current process'
     * environment.
     */
- void save_environment(std::map<std::string,std::string>& env_map
- , char** env = environ)
+ template<typename MapT>
+ void save_environment(MapT& env_map, char** env = environ)
    {
      for(; *env; ++env)
      {

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/throw_error.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/throw_error.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/throw_error.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -10,16 +10,19 @@
 #define CGI_THROW_ERROR_HPP_INCLUDED__
 
 #include <boost/system/error_code.hpp>
-//#include <boost/system/system_error.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/throw_exception.hpp>
 
 namespace cgi {
  namespace detail {
 
- void throw_error(boost::system::error_code& ec)
+ inline void throw_error(const boost::system::error_code& ec)
    {
      if(ec)
- throw ec;
-// throw boost::system::system_error(ec);
+ {
+ boost::system::system_error err(ec);
+ boost::throw_exception(err);
+ }
    }
 
  } // namespace detail

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/url_decode.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/url_decode.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/detail/url_decode.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -14,7 +14,31 @@
 namespace cgi {
  namespace detail {
 
+ /// Convert a char into a hexadecimal value
+ std::string char_to_hex(char const& ch)
+ {
+ return std::string();
+ }
+
+ /// Convert two characters into a single, hex-encoded character
+ char hex_to_char(char const& c1, char const& c2)
+ {
+ int ret ( ( std::isalpha(c1)
+ ? ((c1 & 0xdf) - 'A') + 10
+ : (c1 - '0')
+ ) << 4
+ );
+
+ ret += ( std::isalpha(c2)
+ ? ((c2 & 0xdf) - 'A') + 10
+ : (c2 - '0')
+ );
+
+ return static_cast<char>(ret);
+ }
+
    /// Take two characters (a hex sequence) and return a char
+ // **DEPRECATED**
    char url_decode( const char& c1, const char& c2 )
    {
      int ret = ( (c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')
@@ -42,21 +66,32 @@
    {
      std::string ret;
 
- for( unsigned int i=0; i < str.size(); i++ )
+ for( std::string::const_iterator iter = str.begin(), end = str.end()
+ ; iter != end; ++iter )
      {
- switch( str[i] )
+ switch( *iter )
        {
          case ' ':
            break;
          case '+':
- ret += ' ';
+ ret.append(1, ' ');
            break;
          case '%':
- ret += url_decode(str[i+1], str[i+2]);
- i += 2;
+ if (std::isxdigit(*(iter+1))
+ && std::isxdigit(*(iter+2))
+ && std::distance(iter, end) >= 2)
+ {
+ char ch = *++iter; // need this because order of function arg
+ // evaluation is UB.
+ ret.append(1, hex_to_char(ch, *++iter));
+ }
+ else // we're not dealing with a properly encoded hex value.
+ {
+ ret.append(1, '%');
+ }
            break;
          default:
- ret += str[i];
+ ret.append(1, *iter);
        }
      }
 

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -10,5 +10,26 @@
 #define CGI_FCGI_HPP_INCLUDED__
 
 // #include all fcgi-related files only
+#include "boost/cgi/fcgi/service.hpp"
+#include "boost/cgi/fcgi/acceptor.hpp"
+#include "boost/cgi/fcgi/client.hpp"
+#include "boost/cgi/fcgi/request.hpp"
+//#include "boost/cgi/fcgi/request_service.hpp"
+//#include "boost/cgi/fcgi/request_acceptor_service.hpp"
+#include "boost/cgi/detail/common_headers.hpp"
+
+namespace cgi {
+ namespace fcgi {
+ using namespace ::cgi; // **FIXME** this must go.
+ using namespace ::cgi::common; // import common elements.
+ } // namespace fcgi
+} // namespace cgi
+
+/// Dump fcgi stuff into the boost namespace
+namespace boost {
+ namespace fcgi {
+ using namespace ::cgi::fcgi;
+ } // namespace acgi
+} // namespace boost
 
 #endif // CGI_FCGI_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/specification.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/specification.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/fcgi/specification.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,14 +9,15 @@
 #ifndef CGI_FCGI_SPECIFICATION_HPP_INCLUDED__
 #define CGI_FCGI_SPECIFICATION_HPP_INCLUDED__
 
-#include <cinttypes>
+//#include <inttypes.h>
+#include <boost/cstdint.hpp>
 
 // NOTE: CamelCase style mimicks the FastCGI specification
 // SEE: http://www.fastcgi.com/devkit/doc/fcgi-spec.html#S8
 
 namespace cgi {
  namespace fcgi {
- namespace detail {
+ namespace spec_detail {
 
     // Listening socket file number
     const short LISTENSOCK_FILENO = 0;
@@ -27,11 +28,13 @@
      */
     const short HEADER_LEN = 8;
 
+#if 1
     // Value for version component of Header
- const short VERSION_1 = 1;
+ const short BOOST_CGI_FASTCGI_VERSION_1 = 1;
 
     // current version
- const unsigned char VERSION_NUM = (unsigned char)VERSION_1;
+ const unsigned char VERSION_NUM
+ = (unsigned char)BOOST_CGI_FASTCGI_VERSION_1;
 
     // Values for the type component of Header
     enum request_t { BEGIN_REQUEST = 1
@@ -55,7 +58,7 @@
     static const unsigned char KEEP_CONN = 1;
 
     // The longest message possible per record
- const std::u_int16_t MAX_MSG_LEN = 65535;
+ const boost::uint16_t MAX_MSG_LEN = 65535;
 
     // Values for role component of BeginRequestBody
     enum role_t { RESPONDER = 1
@@ -73,74 +76,100 @@
 
     struct Header
     {
- private:
- unsigned char version_;
- unsigned char type_;
- unsigned char requestIdB1_;
- unsigned char requestIdB0_;
- unsigned char contentLengthB1_;
- unsigned char contentLengthB0_;
- unsigned char paddingLength_;
- unsigned char reserved_;
+ //private:
+ /// The underlying type of a FastCGI header.
+ /**
+ * To guarantee the header is laid out exactly as we want, the
+ * structure must be a POD-type (see http://tinyurl.com/yo9eav).
+ */
+ struct implementation_type
+ {
+ unsigned char version_;
+ unsigned char type_;
+ unsigned char requestIdB1_;
+ unsigned char requestIdB0_;
+ unsigned char contentLengthB1_;
+ unsigned char contentLengthB0_;
+ unsigned char paddingLength_;
+ unsigned char reserved_;
+ } impl;
+
     public:
- Header() { memset(this, 0, sizeof(*this)); }
+ Header() { memset(static_cast<void*>(&this->impl), 0, sizeof(this->impl)); }
 
       Header(request_t t, int id, int len)
- : version_ (VERSION_NUM)
- , type_ ((unsigned char)t)
- , requestIdB1_ ((unsigned char)(id >> 8) & 0xff)
- , requestIdB0_ ((unsigned char)(id ) & 0xff)
- , contentLengthB1_((unsigned char)(len >> 8) & 0xff)
- , contentLengthB0_((unsigned char)(len ) & 0xff)
- , paddingLength_ ((unsigned char)0)
- , reserved_ (0)
- { }
+ {
+ reset(t, id, len);
+ }
+
+ void reset(request_t t, int id, int len)
+ {
+ impl.version_ = (VERSION_NUM);
+ impl.type_ = ((unsigned char)t);
+ impl.requestIdB1_ = ((unsigned char)(id >> 8) & 0xff);
+ impl.requestIdB0_ = ((unsigned char)(id ) & 0xff);
+ impl.contentLengthB1_ = ((unsigned char)(len >> 8) & 0xff);
+ impl.contentLengthB0_ = ((unsigned char)(len ) & 0xff);
+ impl.paddingLength_ = ((unsigned char)0);
+ impl.reserved_ = (0);
+ }
 
- std::u_int16_t version() const
+ boost::uint16_t version() const
       {
- return version_;
+ return impl.version_;
       }
 
- std::u_int16_t type() const
+ boost::uint16_t type() const
       {
- return type_;
+ return impl.type_;
       }
 
- std::u_int16_t request_id() const
+ boost::uint16_t request_id() const
       {
- return requestIdB0_ + (requestIdB1_ << 8);
+ return impl.requestIdB0_ + (impl.requestIdB1_ << 8);
       }
 
- std::u_int16_t content_length() const
+ boost::uint16_t content_length() const
       {
- return contentLengthB0_ + (contentLengthB1_ << 8);
+ return impl.contentLengthB0_ + (impl.contentLengthB1_ << 8);
       }
 
- std::u_int16_t padding_length() const
+ boost::uint16_t padding_length() const
       {
- return paddingLength_;
+ return impl.paddingLength_;
       }
+
       int body_length() const
       {
         return content_length() + padding_length();
       }
     };
 
- struct BeginRequestBody
+ class BeginRequestBody
     {
- unsigned char roleB1_;
- unsigned char roleB0_;
- unsigned char flags_;
- unsigned char reserved_[5];
+ /// The underlying type of a BeginRequestBody sub-header.
+ /**
+ * To guarantee the header is laid out exactly as we want, the
+ * structure must be a POD-type (see http://tinyurl.com/yo9eav).
+ */
+ struct implementation_type
+ {
+ unsigned char roleB1_;
+ unsigned char roleB0_;
+ unsigned char flags_;
+ unsigned char reserved_[5];
+ } impl;
+
+ public:
 
       int role() const
       {
- return (roleB1_ << 8 ) + roleB0_;
+ return (impl.roleB1_ << 8 ) + impl.roleB0_;
       }
 
       unsigned char flags() const
       {
- return flags_;
+ return impl.flags_;
       }
     };
 
@@ -150,68 +179,267 @@
       BeginRequestBody body_;
     };
 
- struct EndRequestBody
+ class EndRequestBody
     {
- unsigned char appStatusB3_;
- unsigned char appStatusB2_;
- unsigned char appStatusB1_;
- unsigned char appStatusB0_;
- unsigned char protocolStatus_;
- unsigned char reserved_[3];
+ /// The underlying type of an EndRequestBody sub-header.
+ /**
+ * To guarantee the header is laid out exactly as we want, the
+ * structure must be a POD-type (see http://tinyurl.com/yo9eav).
+ */
+ struct implementation_type
+ {
+ unsigned char appStatusB3_;
+ unsigned char appStatusB2_;
+ unsigned char appStatusB1_;
+ unsigned char appStatusB0_;
+ unsigned char protocolStatus_;
+ unsigned char reserved_[3];
+ } impl;
+
+ public:
+ EndRequestBody() {}
 
- EndRequestBody( std::u_int64_t appStatus
+ EndRequestBody( boost::uint64_t appStatus
                     , status_t procStatus
                     )
- : appStatusB3_( (appStatus >> 24) & 0xff )
- , appStatusB2_( (appStatus >> 16) & 0xff )
- , appStatusB1_( (appStatus >> 8) & 0xff )
- , appStatusB0_( (appStatus >> 0) & 0xff )
- , protocolStatus_((unsigned char)procStatus)
       {
- memset(reserved_, 0, sizeof(reserved_));
+ reset(appStatus, procStatus);
+ }
+
+ void reset( boost::uint64_t appStatus, status_t procStatus)
+ {
+ impl.appStatusB3_ = ( (appStatus >> 24) & 0xff );
+ impl.appStatusB2_ = ( (appStatus >> 16) & 0xff );
+ impl.appStatusB1_ = ( (appStatus >> 8) & 0xff );
+ impl.appStatusB0_ = ( (appStatus >> 0) & 0xff );
+ impl.protocolStatus_ = ((unsigned char)procStatus);
+
+ memset(impl.reserved_, 0, sizeof(impl.reserved_));
       }
     };
 
- struct EndRequestRecord
+ class EndRequestRecord
     {
- Header header_;
- EndRequestBody body_;
+ /// The underlying type of an EndRequestRecord sub-header.
+ /**
+ * To guarantee the header is laid out exactly as we want, the
+ * structure must be a POD-type (see http://tinyurl.com/yo9eav).
+ */
+ struct implementation_type
+ {
+ Header header_;
+ EndRequestBody body_;
+ } impl;
 
- EndRequestRecord( std::u_int16_t id
- , std::u_int64_t appStatus
+ public:
+ EndRequestRecord( boost::uint16_t id
+ , boost::uint64_t appStatus
                       , status_t procStatus
                       )
- : header_( END_REQUEST, id, sizeof(EndRequestBody) )
- , body_( appStatus, procStatus )
       {
+ impl.header_.reset( END_REQUEST, id, sizeof(EndRequestBody) );
+ impl.body_.reset( appStatus, procStatus );
       }
     };
 
- struct UnknownTypeBody
+ class UnknownTypeBody
     {
- unsigned char type_;
- unsigned char reserved_[7];
+ /// The underlying type of an UnknownTypeBody sub-header.
+ /**
+ * To guarantee the header is laid out exactly as we want, the
+ * structure must be a POD-type (see http://tinyurl.com/yo9eav).
+ */
+ struct implementation_type
+ {
+ unsigned char type_;
+ unsigned char reserved_[7];
+ } impl;
+
+ public:
+ UnknownTypeBody()
+ {
+ }
 
       UnknownTypeBody( unsigned char t )
- : type_(t)
       {
- memset(reserved_, 0, sizeof(reserved_));
+ reset(t);
+ }
+
+ void reset(unsigned char t)
+ {
+ impl.type_ = t;
+ memset(impl.reserved_, 0, sizeof(impl.reserved_));
       }
+
+ unsigned char type() const { return impl.type_; }
     };
 
- struct UnknownTypeRecord
+ class UnknownTypeRecord
     {
- Header header_;
- UnknownTypeBody body_;
+ /// The underlying type of a UnknownTypeRecord sub-header
+ /**
+ * To guarantee the header is laid out exactly as we want, the
+ * structure must be a POD-type (see http://tinyurl.com/yo9eav).
+ */
+ struct implementation_type
+ {
+ Header header_;
+ UnknownTypeBody body_;
+ } impl;
 
+ public:
       UnknownTypeRecord( int type )
- : header_( UNKNOWN_TYPE, 0, sizeof(UnknownTypeBody) )
- , body_( (unsigned char)type )
       {
+ impl.header_.reset( UNKNOWN_TYPE, 0, sizeof(UnknownTypeBody) );
+ impl.body_.reset( (unsigned char)type ); // not sure why this is C-style
       }
     };
     
- } // namespace detail
+#endif
+ } // namespace detail
+
+ namespace specification {
+
+#include <boost/mpl/int.hpp>
+
+ struct max_packet_size
+ : boost::mpl::int_<65535>
+ {};
+
+ struct header_length
+ : boost::mpl::int_<8>
+ {};
+
+ struct listensock_fileno
+ : boost::mpl::int_<0>
+ {};
+
+ static const unsigned char keep_connection = 1;
+
+ struct null_request_id
+ : boost::mpl::int_<0>
+ {};
+
+ template<typename Array>
+ int get_version(Array& a) { return static_cast<int>(a[0]); }
+
+ template<typename Array>
+ spec_detail::request_t get_type(Array& a)
+ {
+ return static_cast<spec_detail::request_t>(a[1]);
+ }
+
+ template<typename Array>
+ boost::uint16_t get_request_id(Array& a)
+ {
+ return (a[2] << 8) + a[3];
+ }
+
+ template<typename Array>
+ boost::uint16_t get_content_length(Array& a)
+ {
+ return (a[4] << 8) + a[5];
+ }
+
+ template<typename Array>
+ boost::uint16_t get_padding_length(Array& a)
+ {
+ return a[6];
+ }
+
+ template<typename Array>
+ boost::uint16_t get_length(Array& a)
+ {
+ return get_content_length(a) + get_padding_length(a);
+ }
+
+ struct request_type
+ {
+ template<typename Array>
+ static std::string to_string(Array& a)
+ {
+ switch(a[1])
+ {
+ case 0:
+ return "ADMIN_REQUEST";
+ case 1:
+ return "BEGIN_REQUEST";
+ case 2:
+ return "ABORT_REQUEST";
+ case 3:
+ return "END_REQUEST";
+ case 4:
+ return "PARAMS";
+ case 5:
+ return "STDIN";
+ case 6:
+ return "STDOUT";
+ case 7:
+ return "STDERR";
+ case 8:
+ return "DATA";
+ case 9:
+ return "GET_VALUES";
+ case 10:
+ return "GET_VALUES_RESULT";
+ case 11:
+ return "UNKNOWN_TYPE";
+ default:
+ return "***ERROR-INVALID-TYPE***";
+ }
+ }
+ };
+
+ struct begin_request
+ : boost::mpl::int_<1>
+ {
+ struct body
+ {
+ typedef boost::mpl::int_<8> size;
+ };
+
+ template<typename Array>
+ static spec_detail::role_t
+ get_role(Array& a)
+ {
+ return static_cast<spec_detail::role_t>( (a[0] << 8) + a[1] );
+ }
+
+ template<typename Array>
+ static unsigned char
+ get_flags(Array& a)
+ {
+ return a[2];
+ }
+
+ //typedef spec_detail::BEGIN_REQUEST type;
+
+ };
+
+ struct role_type
+ {
+ template<typename Array>
+ static std::string to_string(Array& a)
+ {
+ using namespace spec_detail;
+ switch(begin_request::get_role(a))
+ {
+ case RESPONDER:
+ return "RESPONDER";
+ case AUTHORIZER:
+ return "AUTHORISER";
+ case FILTER:
+ return "FILTER";
+ default:
+ return "ANY";
+ }
+ }
+ };
+ //using namespace ::cgi::fcgi::detail;
+ }
+
+ namespace spec = specification;
+
  } // namespace fcgi
 }// namespace cgi
 

Deleted: sandbox/SOC/2007/cgi/trunk/boost/cgi/gateway_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/gateway_service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
+++ (empty file)
@@ -1,117 +0,0 @@
-// -- gateway_service.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_SERVICE_HPP_INCLUDED__
-#define CGI_GATEWAY_SERVICE_HPP_INCLUDED__
-
-namespace cgi {
-
-
- template<typename Protocol
- , typename ProtocolService = basic_protocol_service<Protocol> >
- class gateway_service
- {
- public:
- typedef Protocol protocol_type;
- typedef ProtocolService io_service_type;
- typedef boost::shared_ptr<connection_type> conn_ptr;
-
-
- gateway_service(io_service_type& ios)
- : io_service_(ios)
- {
- }
-
- void stop(impl_type& impl)
- {
-
-
- //boost::system::error_code&
- //accept(impl_type& impl, conn_ptr conn, boost::system::error_code& ec)
- //{
- // boost::asio::acceptor(
- //}
-
- //boost::system::error_code&
- //accept(conn_ptr conn, boost::system::error_code& ec)
- //{
- // conn = create_connection();
-
- // if( accept_impl(conn, ec) )
- // {
- // io_service_.connections_.insert(conn);
- // return ec;
- // }
-
- // // else change the current connection type held by the service, and try again
- // // (when implemented by asio & server front-ends)
- // // for now just set an error and return
- // ec = boost::system::system_error(666);
- // return ec;
- //}
-
- //template<typename Handler>
- //class accept_handler
- //{
- //public:
- // accept_handler(Handler handler)
- // : handler_(handler)
- // {
- // }
-
- // void operator()(const boost::system::error_code& ec)
- // {
- // handler_(ec);
- // }
-
- //private:
- // Handler handler_;
- //};
-
- //template<typename Handler>
- //void async_accept(Handler handler)
- //{
- //}
-
- private:
-
- /// Create a connection of the correct type
- /**
- * For now this only creates one type of connection (either a tcp socket for FCGI,
- * or a cin/cout wrapper for vanilla CGI).
- *
- * It will be necessary once asio has the capabilities, to allow for different
- * connection types here. This should be relatively simple assuming conn_ptr is
- * a shared_ptr of a connection_base and all connection types inherit from this.
- */
- conn_ptr create_connection()
- {
- return new tcp_connection(io_service_);
- }
-
- io_service_type& io_service_;
- };
-
-
- template<> boost::system::error_code&
- gateway_service<protocol::cgi>::accept( gateway_service<protocol::cgi>::conn_ptr conn
- , boost::system::error_code& ec
- )
- {
- conn = create_connection();
- }
-
- template<> boost::shared_ptr<connection_base>
- gateway_service<protocol::cgi>::create_connection()
- {
- return new stdio_connection(gateway_);
- }
-
-} // namespace cgi
-
-#endif // CGI_GATEWAY_SERVICE_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/header.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/header.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/header.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -10,35 +10,125 @@
 #define CGI_HEADER_HPP_INCLUDED__
 
 #include <string>
+#include <boost/lexical_cast.hpp>
 
 namespace cgi {
+ namespace common {
 
+ //template<typename StringT = std::string>
   struct header
   {
+ typedef std::string string_type;
+
     header()
- : content("\r\n")
+ : content()
     {
     }
 
- header(const std::string& name, const std::string& val)
- : content(name + ": " + val + "\r\n")
+
+ /// Templated constructor to allow user-defined types to be converted
+ //template<typename T>
+ //header(T& t)
+ // : content(t.to_string())
+ //{
+ //}
+
+
+ //template<>
+ header(const string_type& _content)
+ : content(_content)
     {
     }
 
- std::string content;
+ header(const string_type& name, const string_type& val)
+ : content(name + ": " + val)
+ {
+ }
+
+ //header(const std::string& name, const std::string& val)
+ // : content(name + ": " + val)
+ //{
+ //}
+
+ /// Construct an header from a cookie.
+ template<typename T>
+ header(const basic_cookie<T>& ck)
+ : content("Set-cookie: " + ck.to_string())
+ {
+ }
+
+ string_type content;
+
   };
 
- // Some shortcuts, to cut down on errors
- header content_type(const std::string& str)
+/*
+ template<typename StringT>
+ header<StringT>
+ make_header(const StringT& name, const StringT& val)
+ {
+ return basic_header<StringT>(name, val);
+ }* /
+
+ template<typename T, typename StringT>
+ T make_header(const StringT& name, const StringT& val)
+ {
+ return basic_header<StringT>(name, val);
+ }*/
+
+
+ //{ Some shortcuts, to cut down on typing errors.
+ template<typename StringT>
+ header
+ content_type(StringT str)
   {
     return header("Content-type", str);
   }
 
+ template<typename StringT>
+ header
+ content_encoding(const StringT& str)
+ {
+ return header("Content-encoding", str);
+ }
+
+ template<typename T>
+ header
+ content_length(const T& t)
+ {
+ return header("Content-length", boost::lexical_cast<std::string>(t));
+ }
+
+ template<typename T, typename Traits, typename Alloc>
+ header
+ content_length(const std::basic_string<T, Traits, Alloc>& str)
+ {
+ return header("Content-length", str);
+ }
+/*
+ template<typename StringT>
+ header<StringT>
+ location(const StringT& url)
+ {
+ return header<StringT>("Location", url);
+ }
+
+ header<std::string>
+ location(const std::string& url)
+ {
+ return header<std::string>("Location", url);
+ }*/
+ //template<typename T>
   header location(const std::string& url)
   {
     return header("Location", url);
   }
+ //}
+
+ // typedefs for typical usage
+ //typedef basic_header<std::string> header;
+ //typedef basic_header<std::wstring> wheader;
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_HEADER_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,11 +9,21 @@
 #ifndef CGI_IO_SERVICE_HPP_INCLUDED__
 #define CGI_IO_SERVICE_HPP_INCLUDED__
 
+//#if _MSC_VER > 1020
+//#pragma once
+//#endif
+
 #include <boost/asio/io_service.hpp>
 
 namespace cgi {
+ namespace common {
+
+ using boost::asio::io_service;
+
+ } // namespace common
 
- typedef boost::asio::io_service io_service;
+ // This should go?
+ using boost::asio::io_service;
 
 } // namespace cgi
 

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service_provider.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service_provider.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service_provider.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,15 +9,20 @@
 #ifndef CGI_IO_SERVICE_PROVIDER_HPP_INCLUDED__
 #define CGI_IO_SERVICE_PROVIDER_HPP_INCLUDED__
 
-#include <list>
-#include <boost/ref.hpp>
-#include <boost/bind.hpp>
-#include <boost/thread.hpp>
-#include <boost/shared_ptr.hpp>
+#if _MSC_VER > 1020
+#pragma once
+#endif
+
+#include "boost/cgi/detail/push_options.hpp"
+
+//#include <list>
+//#include <boost/ref.hpp>
+//#include <boost/bind.hpp>
+//#include <boost/thread.hpp>
+//#include <boost/shared_ptr.hpp>
 #include <boost/noncopyable.hpp>
 
 #include "boost/cgi/io_service.hpp"
-#include "boost/cgi/detail/push_options.hpp"
 #include "boost/cgi/io_service_provider_fwd.hpp"
 
 
@@ -53,7 +58,8 @@
     {
     }
 
- cgi::io_service& get_io_service()
+ ::cgi::io_service&
+ get_io_service()
     {
       return io_service_;
     }
@@ -73,7 +79,7 @@
       io_service_.reset();
     }
   private:
- cgi::io_service io_service_;
+ ::cgi::io_service io_service_;
   };
 
 

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service_provider_fwd.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service_provider_fwd.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/io_service_provider_fwd.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,6 +9,10 @@
 #ifndef CGI_IO_SERVICE_PROVIDER_FWD_HPP_INCLUDED__
 #define CGI_IO_SERVICE_PROVIDER_FWD_HPP_INCLUDED__
 
+#if _MSC_VER > 1020
+#pragma once
+#endif
+
 #include "boost/cgi/tags.hpp"
 
 namespace cgi {

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/map.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/map.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/map.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -13,9 +13,11 @@
 #include <string>
 
 namespace cgi {
+ namespace common {
 
   typedef std::map<std::string,std::string> map;
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_MAP_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/read.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/read.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/read.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -12,10 +12,12 @@
 #include <boost/asio/read.hpp>
 
 namespace cgi {
+ namespace common {
 
   using boost::asio::read;
   using boost::asio::async_read;
 
+ } // namespace common
 } // namespace cgi
 
 #endif // CGI_READ_HPP_INCLUDED

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/request_ostream.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/request_ostream.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/request_ostream.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -77,7 +77,7 @@
   public:
     /// Default constructor
     request_ostream(http::status_code sc = http::ok)
- : buffer_(new cgi::streambuf())
+ : buffer_(new ::cgi::streambuf())
       , ostream_(buffer_.get())
       , http_status_(sc)
       , headers_sent_(false)
@@ -89,7 +89,7 @@
      * Takes the buffer and uses it internally, does nothing with it on
      * destruction.
      */
- request_ostream(cgi::streambuf* buf, http::status_code sc = http::ok)
+ request_ostream(::cgi::streambuf* buf, http::status_code sc = http::ok)
       : /*request_(NULL)
           , */ostream_(buf)
       , http_status_(sc)
@@ -168,8 +168,8 @@
         ostream_<< "Content-type: text/plain\r\n\r\n";
         headers_sent_ = true;
       }
- cgi::write(req, headers_);
- cgi::write(req, rdbuf()->data());
+ ::cgi::write(req, headers_);
+ ::cgi::write(req, rdbuf()->data());
       // the above function will throw on an error
       clear();
     }
@@ -180,15 +180,15 @@
      * If there is no error, the buffer is cleared.
      */
     template<typename CommonGatewayRequest>
- boost::system::error_code& flush(CommonGatewayRequest& req
- , boost::system::error_code& ec)
+ boost::system::error_code&
+ flush(CommonGatewayRequest& req, boost::system::error_code& ec)
     {
       if (!headers_sent_)
       {
         ostream_<< "Content-type: text/plain\r\n\r\n";
         headers_sent_ = true;
       }
- if(!cgi::write(req, rdbuf()->data(), ec))
+ if(!::cgi::write(req, rdbuf()->data(), ec))
         clear();
       return ec;
     }
@@ -227,9 +227,9 @@
         ostream_<< "Content-type: text/plain\r\n\r\n";
         headers_sent_ = true;
       }
- cgi::async_write(req, rdbuf()->data()
- , flush_handler<Handler>
- (*this, handler, boost::arg<1>()));
+ ::cgi::async_write(req, rdbuf()->data()
+ , flush_handler<Handler>
+ (*this, handler, boost::arg<1>()));
     }
 
 
@@ -277,7 +277,7 @@
         ostream_<< "Content-type: text/plain\r\n\r\n";
         headers_sent_ = true;
       }
- cgi::write(req.client(), rdbuf()->data());
+ ::cgi::write(req.client(), rdbuf()->data());
       req.set_status(http_status_);
     }
 
@@ -287,15 +287,15 @@
      * 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)
+ boost::system::error_code&
+ send(CommonGatewayRequest& req, boost::system::error_code& ec)
     {
       if (!headers_sent_)
       {
         ostream_<< "Content-type: text/plain\r\n\r\n";
         headers_sent_ = true;
       }
- cgi::write(req.client(), rdbuf()->data(), ec);
+ ::cgi::write(req.client(), rdbuf()->data(), ec);
       req.set_status(http_status_);
       return ec;
     }
@@ -313,13 +313,14 @@
         ostream_<< "Content-type: text/plain\r\n\r\n";
         headers_sent_ = true;
       }
- cgi::async_write(req, rdbuf()->data(), handler);
+ ::cgi::async_write(req, rdbuf()->data(), handler);
     }
 
     /// Get the buffer associated with the stream
- cgi::streambuf* rdbuf()
+ ::cgi::streambuf*
+ rdbuf()
     {
- return static_cast<cgi::streambuf*>(ostream_.rdbuf());
+ return static_cast<::cgi::streambuf*>(ostream_.rdbuf());
     }
 
     void set_status(const http::status_code& num)
@@ -334,7 +335,7 @@
 
   protected:
     std::vector<boost::asio::const_buffer> headers_;
- boost::shared_ptr<cgi::streambuf> buffer_;
+ boost::shared_ptr<::cgi::streambuf> buffer_;
     std::ostream ostream_;
     http::status_code http_status_;
     bool headers_sent_;
@@ -355,6 +356,6 @@
 
 } // namespace cgi
 
-#include "detail/pop_options.hpp"
+#include "boost/cgi/detail/pop_options.hpp"
 
 #endif // CGI_REQUEST_OSTREAM_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/request_service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,18 +9,19 @@
 #ifndef CGI_REQUEST_SERVICE_HPP_INCLUDED
 #define CGI_REQUEST_SERVICE_HPP_INCLUDED
 
-#include "detail/push_options.hpp"
+#include "boost/cgi/detail/push_options.hpp"
 
 #include <boost/utility/enable_if.hpp>
 
 //#include "is_async.hpp"
-#include "io_service.hpp"
-#include "detail/protocol_traits.hpp"
-#include "basic_protocol_service_fwd.hpp"
-#include "detail/service_base.hpp"
+#include "boost/cgi/io_service.hpp"
+#include "boost/cgi/detail/protocol_traits.hpp"
+#include "boost/cgi/basic_protocol_service_fwd.hpp"
+#include "boost/cgi/detail/service_base.hpp"
 //#include "service_selector.hpp"
 
 namespace cgi {
+ namespace common {
 
   /// The generic service class for basic_request<>s
   /**
@@ -35,15 +36,15 @@
     : public detail::service_base<request_service<Protocol> >
   {
     // The platform-specific implementation (only one for now)
- typedef typename detail::protocol_traits<Protocol>::service_impl_type
+ typedef typename detail::protocol_traits<Protocol>::request_service_impl
       service_impl_type;
 
   public:
     typedef typename service_impl_type::impl_type impl_type;
- typedef typename service_impl_type::implementation_type
- implementation_type;
+ typedef typename
+ service_impl_type::implementation_type implementation_type;
     typedef Protocol protocol_type;
- typedef basic_protocol_service<Protocol> protocol_service_type;
+ typedef common::basic_protocol_service<Protocol> protocol_service_type;
 
     /// The unique service identifier
     //static boost::asio::io_service::id id;
@@ -51,7 +52,7 @@
     //{
     //}
 
- request_service(cgi::io_service& ios)
+ request_service(::cgi::io_service& ios)
       : detail::service_base<request_service<Protocol> >(ios)
       , service_impl_(boost::asio::use_service<service_impl_type>(ios))
     {
@@ -85,8 +86,8 @@
 
     //void construct
 
- boost::system::error_code& load(impl_type& impl, bool parse_stdin
- , boost::system::error_code& ec)
+ boost::system::error_code&
+ load(impl_type& impl, bool parse_stdin, boost::system::error_code& ec)
     {
       return service_impl_.load(impl, parse_stdin, ec);
     }
@@ -104,13 +105,13 @@
     }
 
     boost::system::error_code&
- set_header(impl_type& impl, const std::string& name
- , const std::string& value, boost::system::error_code& ec)
+ set_header(impl_type& impl, const std::string& name
+ , const std::string& value, boost::system::error_code& ec)
     {
       return service_impl_.set_header(impl, name, value, ec);
     }
       
-
+/*
     template<typename ConstBufferSequence>
     std::size_t write_some(impl_type& impl, const ConstBufferSequence& buf
                           , boost::system::error_code& ec)
@@ -124,31 +125,44 @@
     {
       return service_impl_.read_some(impl, buf, ec);
     }
-
- std::string meta_get(impl_type& impl, const std::string& name
- , boost::system::error_code& ec)
+*/
+ std::string
+ GET(impl_type& impl, const std::string& name
+ , boost::system::error_code& ec)
     {
- return service_impl_.meta_get(impl, name, ec);
+ return service_impl_.GET(impl, name, ec);
     }
 
- std::string meta_post(impl_type& impl, const std::string& name
- , boost::system::error_code& ec)
+ std::string
+ POST(impl_type& impl, const std::string& name
+ , boost::system::error_code& ec)
     {
- return service_impl_.meta_post(impl, name, ec);
+ return service_impl_.POST(impl, name, ec);
     }
 
- std::string cookie(impl_type& impl, const std::string& name
- , boost::system::error_code& ec)
+ std::string
+ cookie(impl_type& impl, const std::string& name
+ , boost::system::error_code& ec)
     {
       return service_impl_.cookie(impl, name, ec);
     }
 
+ /*
+ std::string
+ header(impl_type& impl, const std::string& name
+ , boost::system::error_code& ec)
+ {
+ return "";
+ }
+*/
+
   private:
     service_impl_type& service_impl_;
   };
 
+ } // namespace common
 } // namespace cgi
 
-#include "detail/pop_options.hpp"
+#include "boost/cgi/detail/pop_options.hpp"
 
 #endif // CGI_REQUEST_SERVICE_HPP_INCLUDED

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/response.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/response.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/response.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,33 +9,79 @@
 #ifndef CGI_RESPONSE_HPP_INCLUDED__
 #define CGI_RESPONSE_HPP_INCLUDED__
 
+#include "boost/cgi/detail/push_options.hpp"
+
 #include <string>
+#include <fstream> // only for testing
 
-#include "boost/cgi/detail/push_options.hpp"
-#include "boost/cgi/request_ostream.hpp"
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+
+//#include "boost/cgi/request_ostream.hpp"
 #include "boost/cgi/buffer.hpp"
 #include "boost/cgi/cookie.hpp"
 #include "boost/cgi/header.hpp"
+#include "boost/cgi/write.hpp"
+#include "boost/cgi/basic_request_fwd.hpp"
+#include "boost/cgi/http/status_code.hpp"
+#include "boost/cgi/streambuf.hpp"
+#include "boost/cgi/detail/throw_error.hpp"
+
+/// This mess outputs a default Content-type header if the user hasn't set any.
+/** **FIXME** Not implemented; not sure if it should be...
+ * BOOST_CGI_ADD_DEFAULT_HEADER should not persiste beyond this file.
+ *
+ * It basically works like (default first):
+ *
+ * Debug mode:
+ * - Append a "Content-type: text/plain" header;
+ * - If BOOST_CGI_DEFAULT_CONTENT_TYPE is defined, set that as the
+ * content-type;
+ * - If BOOST_CGI_NO_DEFAULT_CONTENT_TYPE is defined, do nothing.
+ *
+ * Release mode:
+ * - Do nothing.
+ */
+#if !defined(NDEBUG) && !defined(BOOST_CGI_NO_DEFAULT_CONTENT_TYPE)
+//{
+# if !defined(BOOST_CGI_DEFAULT_CONTENT_TYPE)
+# define BOOST_CGI_DEFAULT_CONTENT_TYPE "Content-type: text/plain"
+# endif // !defined(BOOST_CGI_DEFAULT_CONTENT_TYPE)
+//}
+# define BOOST_CGI_ADD_DEFAULT_HEADER \
+ if (headers_.empty()) \
+ headers_.push_back(BOOST_CGI_DEFAULT_CONTENT_TYPE"\r\n");
+#else
+# define BOOST_CGI_ADD_DEFAULT_HEADER
+#endif // !defined(NDEBUG) && !defined(BOOST_CGI_NO_DEFAULT_CONTENT_TYPE)
 
-namespace cgi {
-
- /// The response class: a helper for responding to requests
-
- // The request_ostream is destined to become a basic_request_ostream
-//typedef request_ostream<> response_;
 
+namespace cgi {
+ namespace common {
 
+ /// The response class: a helper for responding to requests.
   class response
- : public cgi::request_ostream
   {
   public:
+ typedef std::ostream ostream_type;
+
     response(http::status_code sc = http::ok)
- : cgi::request_ostream(sc)
+ : buffer_(new ::cgi::streambuf())
+ , ostream_(buffer_.get())
+ , http_status_(sc)
+ , headers_terminated_(false)
     {
     }
 
- response(cgi::streambuf* buf, http::status_code sc = http::ok)
- : cgi::request_ostream(buf, sc)
+ /// Construct with a particular buffer
+ /**
+ * Takes the buffer and uses it internally, does nothing with it on
+ * destruction.
+ */
+ response(::cgi::streambuf* buf, http::status_code sc = http::ok)
+ : /*request_(NULL)
+ , */ostream_(buf)
+ , http_status_(sc)
     {
     }
 
@@ -43,26 +89,277 @@
     {
     }
 
- /// Some helper functions for the basic CGI 1.1 meta-variables
-// void auth_type(const std::string& value)
-// {
-// std::string str("Auth-type: ");
-// str += value;
-// this->headers_.push_back(cgi::buffer(str.c_str(), str.size()));
-// }
-//
-// void content_length(const std::string& value)
-// {
-// std::string str("Content-length: ");
-// str += value;
-// this->headers_.push_back(cgi::buffer(str.c_str(), str.size()));
-// }
+ /// Clear the response buffer.
+ void clear()
+ {
+ ostream_.clear();
+ headers_.clear();
+ headers_terminated_ = false;
+ }
+
+ /// Return the response to the 'just constructed' state.
+ void reset()
+ {
+ clear();
+ headers_terminated_ = false;
+ }
+
+ // provide this too?
+ std::size_t write(const char* str, std::size_t len)
+ {
+ ostream_.write(str, len);
+ return len;
+ }
+
+ std::size_t write(const std::string& str)
+ {
+ return write(str.c_str(), str.size());
+ }
+
+ template<typename ConstBufferSequence>
+ std::size_t write(const ConstBufferSequence& buf)
+ {
+ return ostream_.write(buf.begin(), buf.end());
+ //return buf.size();
+ }
+
+ /// Synchronously flush the data to the supplied SyncWriteStream
+ /**
+ * 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 SyncWriteStream>
+ void flush(SyncWriteStream& sws)
+ {
+ boost::system::error_code ec;
+ flush(sws, ec);
+ detail::throw_error(ec);
+ }
+
+ /// 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 SyncWriteStream>
+ boost::system::error_code
+ flush(SyncWriteStream& sws, boost::system::error_code& ec)
+ {
+ if (!headers_terminated_)
+ {
+ std::vector<boost::asio::const_buffer> headers;
+ prepare_headers(headers);//, ec);
+ common::write(sws, headers, boost::asio::transfer_all(), ec);
+ if (ec)
+ return ec;
+ }
+
+ std::size_t bytes_written
+ = common::write(sws, buffer_->data(), boost::asio::transfer_all(), ec);
+ if (!ec)
+ buffer_->consume(bytes_written);
+
+ 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 SyncWriteStream>
+ void send(SyncWriteStream& sws)
+ {
+ boost::system::error_code ec;
+ send(sws, ec);
+ detail::throw_error(ec);
+ }
+
+ /// Synchronously send the data via the supplied request.
+ /**
+ * This call will not throw, but will set `ec` such that `ec == true` if
+ * an error occurs. Details of the error are held in the `error_code`
+ * object.
+ */
+ template<typename SyncWriteStream>
+ boost::system::error_code
+ send(SyncWriteStream& sws, boost::system::error_code& ec)
+ {
+ if (!headers_terminated_)
+ {
+ /* Not sure if streambuf allows this
+ *
+ // We want to be able to keep adding to a response, calling send() on
+ // it whenever, without resending the headers. Call resend() if you
+ // want to send the whole response again.
+ headers_terminated_ = true;
+ */
+ std::vector<boost::asio::const_buffer> headers;
+ prepare_headers(headers);//, ec)
+ common::write(sws, headers, boost::asio::transfer_all(), ec);
+ }
+
+ common::write(sws, buffer_->data(), boost::asio::transfer_all(), ec);
+
+ return ec;
+ }
+
+ /// Resend headers + content regardless of value of `headers_terminated_`.
+ template<typename SyncWriteStream>
+ void resend(SyncWriteStream& sws)
+ {
+ std::vector<boost::asio::const_buffer> headers;
+ prepare_headers(headers);//, ec)
+ common::write(sws, headers);
+
+ common::write(sws, buffer_->data());
+ }
+
+ /// Asynchronously send the data through the supplied request
+ /**
+ * Note: This is quite crude at the moment and not as asynchronous as
+ * it could/should be. The data in the stream isn't cleared after
+ * this call.
+ */
+ template<typename AsyncWriteStream, typename Handler>
+ void async_send(AsyncWriteStream& aws, Handler handler)
+ {
+ aws.io_service().post(
+ boost::bind(&response::do_async_send, aws, handler)
+ );
+ }
+
+ template<typename AsyncWriteStream, typename Handler>
+ void do_async_send(AsyncWriteStream& aws, Handler handler)
+ {
+
+
+ //req.set_status(http_status_);
+ /*
+ if (!headers_terminated_)
+ {
+ ostream_<< "Content-type: text/plain\r\n\r\n";
+ headers_terminated_ = true;
+ }
+ */
+ common::async_write(aws, rdbuf()->data(), handler);
+ }
+
+ /// Get the buffer associated with the stream
+ common::streambuf*
+ rdbuf()
+ {
+ return static_cast<common::streambuf*>(ostream_.rdbuf());
+ }
+
+ /// Set the status code associated with the response.
+ response& set_status(const http::status_code& num)
+ {
+ http_status_ = num;
+ return *this;
+ }
+
+ /// Get the status code associated with the response.
+ http::status_code& status()
+ {
+ return http_status_;
+ }
+
+ /// Allow more headers to be added (WARNING: avoid using this).
+ void unterminate_headers()
+ {
+ headers_terminated_ = false;
+ }
+
+ /// Get the length of the body of the response
+ std::size_t content_length()
+ {
+ return rdbuf()->size();
+ }
+
+ /// Add a header after appending the CRLF sequence.
+ response& set_header(const std::string& value)
+ {
+ BOOST_ASSERT(!headers_terminated_);
+ headers_.push_back(value + "\r\n");
+ return *this;
+ }
+
+ /// Format and add a header given name and value, appending CRLF.
+ response& set_header(const std::string& name, const std::string& value)
+ {
+ BOOST_ASSERT(!headers_terminated_);
+ headers_.push_back(name + ": " + value + "\r\n");
+ return *this;
+ }
+
+ void clear_headers()
+ {
+ BOOST_ASSERT(!headers_terminated_);
+ headers_.clear();
+ }
+
+ void reset_headers()
+ {
+ headers_.clear();
+ headers_terminated_ = false;
+ }
+
+ bool headers_terminated() const
+ {
+ return headers_terminated_;
+ }
+ protected:
+ // Vector of all the headers, each followed by a CRLF
+ std::vector<std::string> headers_;
+
+ // The buffer is a shared_ptr, so you can keep it cached elsewhere.
+ boost::shared_ptr<common::streambuf> buffer_;
+
+ ostream_type ostream_;
+
+ http::status_code http_status_;
+
+ // True if no more headers can be appended.
+ bool headers_terminated_;
 
- private:
     template<typename T>
     friend response& operator<<(response& resp, const T& t);
- };
 
+ //template<typename A, typename B>
+ //friend A& operator<<(A& resp, B b);
+
+ private:
+
+ // Send the response headers and mark that they've been sent.
+ template<typename ConstBufferSequence>
+ //boost::system::error_code
+ void
+ prepare_headers(ConstBufferSequence& headers)//, boost::system::error_code& ec)
+ {
+ BOOST_CGI_ADD_DEFAULT_HEADER
+
+ // Terminate the headers.
+ if (!headers_terminated_)
+ headers_.push_back("\r\n");
+
+ //{ Construct a ConstBufferSequence out of the headers we have.
+ //std::vector<boost::asio::const_buffer> headers;
+ typedef std::vector<std::string>::iterator iter;
+ for (iter i(headers_.begin()), e(headers_.end()); i != e; ++i)
+ {
+ headers.push_back(common::buffer(*i));
+ }
+ //}
+
+ headers_terminated_ = true;
+ //return ec;
+ }
+ };
+
+ /// Generic ostream template
   template<typename T>
   response& operator<<(response& resp, const T& t)
   {
@@ -70,24 +367,80 @@
     return resp;
   }
 
+ /// You can stream a cgi::header into a response.
+ /**
+ * This is just a more convenient way of doing:
+ *
+ * ``
+ * resp.set_header(header_content)
+ * ``
+ *
+ * [tip
+ * If you stream a default-constructed header to a response, it
+ * 'terminates' the headers. ie. You can do this if you want to ensure
+ * no further headers are added to the response. It has no other side-
+ * effects; for instance, it won't write any data to the client.
+ * ]
+ * /
+ template<typename T>
+ response& operator<<(response& resp, const ::cgi::basic_header<std::basic_string<T> >& hdr)
+ {
+ if (hdr.content.empty()) {
+ resp.headers_terminated_ = true;
+ return resp;
+ }else{
+ // We shouldn't allow headers to be sent after they're explicitly ended.
+ BOOST_ASSERT(!resp.headers_terminated_);
+ resp.set_header(hdr.content);
+ return resp;
+ }
+ }*/
+
   template<>
- response& operator<<(response& resp, const header& hdr)
+ response& operator<<(response& resp, const ::cgi::common::header& hdr)
   {
- resp.headers_sent_ = true;
- return resp<< hdr.content;
+ if (hdr.content.empty()) {
+ resp.headers_terminated_ = true;
+ return resp;
+ }else{
+ // We shouldn't allow headers to be sent after they're explicitly ended.
+ BOOST_ASSERT(!resp.headers_terminated_);
+ resp.set_header(hdr.content);
+ return resp;
+ }
   }
 
- template<>
- response& operator<<(response& resp, const cookie& ck)
+ /// You can stream a cgi::cookie into a response.
+ /**
+ * This is just a shorthand way of setting a header that will set a
+ * client-side cookie.
+ *
+ * You cannot stream a cookie to a response after the headers have been
+ * terminated. In this case, an alternative could be to use the HTML tag:
+ * <meta http-equiv="Set-cookie" ...> (see http://tinyurl.com/3bxftv or
+ * http://tinyurl.com/33znkj), but this is outside the scope of this
+ * library.
+ */
+ template<typename T>
+ response& operator<<(response& resp, basic_cookie<T> ck)
   {
- // Note: the 'set-cookie' isn't part of the cookie object since
- // the cookie can also be set after the headers have been sent.
- // See http://tinyurl.com/33znkj
- return resp<< "Set-cookie: " << ck << "\r\n";
+ BOOST_ASSERT(!resp.headers_terminated());
+ resp.set_header("Set-cookie", ck.to_string());
+ return resp;
+ }
+
+ template<typename T>
+ response& operator<<(response& resp, http::status_code status)
+ {
+ BOOST_ASSERT(!resp.headers_terminated());
+ return resp.set_status(status);
   }
 
+ } // namespace common
 } // namespace cgi
 
-#include "detail/pop_options.hpp"
+#undef BOOST_CGI_ADD_DEFAULT_HEADER
+
+#include "boost/cgi/detail/pop_options.hpp"
 
 #endif // CGI_RESPONSE_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/role_type.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/role_type.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/role_type.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -11,7 +11,8 @@
  } // namespace role
  
   enum role_type
- { responder
+ { none
+ , responder
   , authorizer
   , filter
   };

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,12 +9,14 @@
 #ifndef CGI_SCGI_HPP_INCLUDED__
 #define CGI_SCGI_HPP_INCLUDED__
 
-// #include all scgi-related headers only
-#include "scgi/service.hpp"
-#include "scgi/request_service.hpp"
-#include "scgi/request_acceptor_service.hpp"
-#include "detail/common_headers.hpp"
+// #include headers for SCGI use.
+#include "boost/cgi/scgi/service.hpp"
+#include "boost/cgi/scgi/acceptor.hpp"
+#include "boost/cgi/scgi/request_service.hpp"
+#include "boost/cgi/scgi/request_acceptor_service.hpp"
+#include "boost/cgi/detail/common_headers.hpp"
 
+/*
 namespace cgi {
 
   typedef basic_request_acceptor<scgi_request_acceptor_service> scgi_acceptor;
@@ -24,5 +26,14 @@
 # endif
 
 } // namespace cgi
+*/
+
+/// Dump acgi stuff into the boost namespace
+namespace boost {
+ namespace scgi {
+ using namespace ::cgi::scgi;
+ using namespace ::cgi::common;
+ } // namespace acgi
+} // namespace boost
 
 #endif // CGI_SCGI_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/acceptor_service_impl.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/acceptor_service_impl.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/acceptor_service_impl.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,11 +9,281 @@
 #ifndef CGI_SCGI_ACCEPTOR_SERVICE_IMPL_HPP_INCLUDED__
 #define CGI_SCGI_ACCEPTOR_SERVICE_IMPL_HPP_INCLUDED__
 
-namespace cgi {
+#include "boost/cgi/detail/push_options.hpp"
+
+#include <boost/ref.hpp>
+#include <boost/bind.hpp>
+#include <boost/asio.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/system/error_code.hpp>
+
+//#include "is_async.hpp"
+#include "boost/cgi/io_service.hpp"
+#include "boost/cgi/detail/throw_error.hpp"
+#include "boost/cgi/detail/protocol_traits.hpp"
+#include "boost/cgi/basic_protocol_service_fwd.hpp"
+#include "boost/cgi/detail/service_base.hpp"
+//#include "service_selector.hpp"
+#include "boost/cgi/scgi/request.hpp"
 
+namespace cgi {
+ namespace scgi {
   
+ /// The service_impl class for SCGI basic_request_acceptor<>s
+ /**
+ * Note: this is near enough to being generic. It will hopefully translate
+ * directly to the fcgi_acceptor_service_impl. In other words you would
+ * then have one acceptor_service_impl<>, so you'd use
+ * acceptor_service_impl<scgi> acceptor_service_impl_; // and
+ * acceptor_service_impl<fcgi> acceptor_service_impl_; // etc...
+ *
+ * Note: If the protocol is an asynchronous protocol, which means it requires
+ * access to a boost::asio::io_service instance, then this class becomes a
+ * model of the Service concept (**LINK**) and must only use the constructor
+ * which takes a ProtocolService (**LINK**). If the protocol isn't async then
+ * the class can be used without a ProtocolService.
+ */
+ template<typename Protocol_ = ::cgi::scgi_>
+ class acceptor_service_impl
+ : public detail::service_base<acceptor_service_impl<Protocol_> >
+ {
+ public:
+
+ /// The unique service identifier
+ //static boost::asio::io_service::id id;
+
+ struct implementation_type
+ {
+ typedef Protocol_ protocol_type;
+ typedef basic_protocol_service<protocol_type> protocol_service_type;
+ typedef boost::asio::ip::tcp native_protocol_type;
+ typedef scgi::request request_type;
+ typedef boost::asio::socket_acceptor_service<
+ native_protocol_type
+ > acceptor_service_type;
+ typedef unsigned short port_number_type;
+ typedef boost::asio::ip::tcp::endpoint endpoint_type;
+ //typedef typename
+ // acceptor_service_type::native_type native_type;
+
+ acceptor_service_type::implementation_type acceptor_;
+ boost::mutex mutex_;
+ std::queue<boost::shared_ptr<request_type> > waiting_requests_;
+ protocol_service_type* service_;
+ port_number_type port_num_;
+ endpoint_type endpoint_;
+ };
 
+ typedef acceptor_service_impl<Protocol_> type;
+ typedef typename
+ type::implementation_type::protocol_type
+ protocol_type;
+ typedef typename
+ type::implementation_type::protocol_service_type
+ protocol_service_type;
+ typedef typename
+ type::implementation_type::acceptor_service_type
+ acceptor_service_type;
+ typedef typename
+ type::implementation_type::native_protocol_type
+ native_protocol_type;
+ typedef typename
+ acceptor_service_type::native_type native_type;
+
 
+ explicit acceptor_service_impl(::cgi::io_service& ios)
+ : detail::service_base<acceptor_service_impl<Protocol_> >(ios)
+ , acceptor_service_(boost::asio::use_service<acceptor_service_type>(ios))
+ //, endpoint(boost::asio::ip::tcp::v4())
+ {
+ }
+
+ void set_protocol_service(implementation_type& impl
+ , protocol_service_type& ps)
+ {
+ impl.protocol_service_ = &ps;
+ }
+
+ protocol_service_type&
+ get_protocol_service(implementation_type& impl)
+ {
+ BOOST_ASSERT(impl.service_ != NULL);
+ return *impl.service_;
+ }
+
+ void construct(implementation_type& impl)
+ {
+ acceptor_service_.construct(impl.acceptor_);
+ //impl.acceptor_ptr().reset(impl::acceptor_type(this->io_service()));
+ }
+
+ void destroy(implementation_type& impl)
+ {
+ // close/reject all the waiting requests
+ /***/
+ acceptor_service_.destroy(impl.acceptor_);
+ }
+
+ void shutdown_service()
+ {
+ acceptor_service_.shutdown_service();
+ }
+
+ /// Check if the given implementation is open.
+ bool is_open(implementation_type& impl)
+ {
+ return acceptor_service_.is_open(impl.acceptor_);
+ }
+
+ /// Open a new *socket* acceptor implementation.
+ boost::system::error_code
+ open(implementation_type& impl, const native_protocol_type& protocol
+ , boost::system::error_code& ec)
+ {
+ return acceptor_service_.open(impl.acceptor_, protocol, ec);
+ }
+
+ template<typename Endpoint>
+ boost::system::error_code
+ bind(implementation_type& impl, const Endpoint& endpoint
+ , boost::system::error_code& ec)
+ {
+ acceptor_service_.set_option(impl.acceptor_,
+ boost::asio::socket_base::reuse_address(true), ec);
+ return acceptor_service_.bind(impl.acceptor_, endpoint, ec);
+ }
+
+ /// Assign an existing native acceptor to a *socket* acceptor.
+ boost::system::error_code
+ assign(implementation_type& impl, const native_protocol_type& protocol
+ , const native_type& native_acceptor
+ , boost::system::error_code& ec)
+ {
+ return acceptor_service_.assign(impl.acceptor_, protocol
+ , native_acceptor, ec);
+ }
+
+ boost::system::error_code
+ listen(implementation_type& impl, int backlog, boost::system::error_code& ec)
+ {
+ return acceptor_service_.listen(impl.acceptor_, backlog, ec);
+ }
+
+ /// Accepts one request.
+ template<typename CommonGatewayRequest>
+ boost::system::error_code
+ accept(implementation_type& impl, CommonGatewayRequest& request
+ , boost::system::error_code& ec)
+ {
+ /* THIS BIT IS BROKEN:
+ *-- The noncopyable semantics of a basic_request<> don't allow the
+ assignment. There are a couple of ways around this; the one that
+ seems sensible is to keep the basic_request<>s noncopyable, but
+ allow the actual data be copied. At the moment the actual data is
+ held in a vector<string> headers container and a cgi::streambuf.
+ These two bits should really be factored out into a message type.
+ IOW, the message type will be copyable (but should probably have
+ unique-ownership semantics).
+ --*
+ {
+ boost::mutex::scoped_lock lk(impl.mutex_);
+ if (!impl.waiting_requests_.empty())
+ {
+ request = *(impl.waiting_requests_.front());
+ impl.waiting_requests_.pop();
+ return ec;
+ }
+ }
+ */
+ return acceptor_service_.accept(impl.acceptor_,
+ request.client().connection()->next_layer(), 0, ec);
+ }
+
+ /// Accepts one request.
+ template<typename CommonGatewayRequest, typename Endpoint>
+ boost::system::error_code
+ accept(implementation_type& impl, CommonGatewayRequest& request
+ , Endpoint* endpoint, boost::system::error_code& ec)
+ {
+ /* THIS BIT IS BROKEN:
+ *-- The noncopyable semantics of a basic_request<> don't allow the
+ assignment. There are a couple of ways around this; the one that
+ seems sensible is to keep the basic_request<>s noncopyable, but
+ allow the actual data be copied. At the moment the actual data is
+ held in a vector<string> headers container and a cgi::streambuf.
+ These two bits should really be factored out into a message type.
+ IOW, the message type will be copyable (but should probably have
+ unique-ownership semantics).
+ --*
+ {
+ boost::mutex::scoped_lock lk(impl.mutex_);
+ if (!impl.waiting_requests_.empty())
+ {
+ request = *(impl.waiting_requests_.front());
+ impl.waiting_requests_.pop();
+ return ec;
+ }
+ }
+ */
+ return acceptor_service_.accept(impl.acceptor_,
+ request.client().connection()->next_layer(), 0, ec);
+ }
+
+ /// Asynchronously accepts one request.
+ template<typename CommonGatewayRequest, typename Handler>
+ void async_accept(implementation_type& impl, CommonGatewayRequest& request
+ , Handler handler, boost::system::error_code& ec)
+ {
+ this->io_service().post(
+ boost::bind(
+ &acceptor_service_impl<protocol_type>::check_for_waiting_request,
+ boost::ref(impl), boost::ref(request), handler, ec));
+ }
+
+ /// Close the acceptor (not implemented yet).
+ boost::system::error_code
+ close(implementation_type& impl, boost::system::error_code& ec)
+ {
+ return boost::system::error_code(348, boost::system::system_category);
+ }
+
+ typename implementation_type::endpoint_type
+ local_endpoint(implementation_type& impl, boost::system::error_code& ec)
+ {
+ return acceptor_service_.local_endpoint(impl.acceptor_, ec);
+ }
+ private:
+ template<typename CommonGatewayRequest, typename Handler>
+ void check_for_waiting_request(implementation_type& impl
+ , CommonGatewayRequest& request
+ , Handler handler)
+ {
+ /*
+ {
+ boost::mutex::scoped_lock lk(impl.mutex_);
+ if (!impl.waiting_requests_.empty())
+ {
+ request = *(impl.waiting_requests_.front());
+ impl.waiting_requests_.pop();
+ return handler(ec); // this could be `io_service::post`ed again
+ }
+ }
+ */
+ return this->accceptor_service_.async_accept(
+ request.client().connection()->next_layer(), handler);
+ }
+
+ public:
+ /// The underlying socket acceptor service.
+ acceptor_service_type& acceptor_service_;
+ };
+
+ } // namespace scgi
 } // namespace cgi
+
+#include "boost/cgi/detail/pop_options.hpp"
 
 #endif // CGI_SCGI_ACCEPTOR_SERVICE_IMPL_HPP_INCLUDED__
+

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,15 +9,25 @@
 #ifndef CGI_SCGI_REQUEST_HPP_INCLUDED__
 #define CGI_SCGI_REQUEST_HPP_INCLUDED__
 
-#include "../tags.hpp"
-#include "../basic_request.hpp"
-
+#include "boost/cgi/tags.hpp"
+#include "boost/cgi/basic_request_fwd.hpp"
+//#include "boost/cgi/request_service_fwd.hpp"
+#include "boost/cgi/scgi/request_service.hpp"
+#include "boost/cgi/scgi/service.hpp"
 namespace cgi {
 
- class scgi_request_service;
+ //class scgi::scgi_request_service;
 
- typedef basic_request<scgi_request_service> scgi_request;
+ // This is deprecated/obsolete
+ //typedef basic_request<scgi::scgi_request_service> scgi_request;
 
+ namespace scgi {
+ // typedef for typical usage (SCGI)
+ typedef basic_request<scgi_request_service, service> request;
+ } // namespace scgi
 } // namespace cgi
 
+//#include "boost/cgi/request_service.hpp"
+#include "boost/cgi/basic_request.hpp"
+
 #endif // CGI_SCGI_REQUEST_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_acceptor_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_acceptor_service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_acceptor_service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -8,22 +8,22 @@
 ////////////////////////////////////////////////////////////////
 #ifndef CGI_REQUEST_SERVICE_HPP_INCLUDED
 #define CGI_REQUEST_SERVICE_HPP_INCLUDED
-
-#include "../detail/push_options.hpp"
+#include "boost/cgi/detail/push_options.hpp"
 
 #include <boost/utility/enable_if.hpp>
 
 //#include "is_async.hpp"
-#include "../io_service.hpp"
-#include "../detail/throw_error.hpp"
-#include "../detail/protocol_traits.hpp"
-#include "../basic_protocol_service_fwd.hpp"
-#include "../detail/service_base.hpp"
+#include "boost/cgi/io_service.hpp"
+#include "boost/cgi/detail/throw_error.hpp"
+#include "boost/cgi/detail/protocol_traits.hpp"
+#include "boost/cgi/basic_protocol_service_fwd.hpp"
+#include "boost/cgi/detail/service_base.hpp"
 //#include "service_selector.hpp"
+#include "boost/cgi/scgi/acceptor_service_impl.hpp"
 
 namespace cgi {
 
- /// The generic service class for basic_request<>s
+ /// The service class for SCGI basic_request_acceptor<>s
   /**
    * Note: If the protocol is an asynchronous protocol, which means it requires
    * access to a boost::asio::io_service instance, then this class becomes a
@@ -31,63 +31,133 @@
    * which takes a ProtocolService (**LINK**). If the protocol isn't async then
    * the class can be used without a ProtocolService.
    */
- template<typename Protocol>
+ template<typename Protocol_ = scgi_>
   class scgi_request_acceptor_service
- : public detail::service_base<request_service<Protocol> >
+ : public detail::service_base<scgi_request_acceptor_service<Protocol_> >
   {
   public:
     //typedef typename service_impl_type::impl_type impl_type;
 
- typedef scgi_request_acceptor_impl implementation_type;
- typedef typename implementation_type::protocol_type
- protocol_type;
- typedef basic_protocol_service<Protocol> protocol_service_type;
+ typedef scgi::acceptor_service_impl<> service_impl_type;
+ typedef service_impl_type::implementation_type implementation_type;
+ typedef typename implementation_type::protocol_type protocol_type;
+ typedef implementation_type::endpoint_type endpoint_type;
+ typedef typename service_impl_type::native_type native_type;
+ //typedef basic_protocol_service<protocol_type> protocol_service_type;
 
     /// The unique service identifier
     //static boost::asio::io_service::id id;
- //explicit request_service()
- //{
- //}
 
- scgi_request_acceptor_service(cgi::io_service& ios)
- : detail::service_base<request_service<Protocol> >(ios)
+ scgi_request_acceptor_service(::cgi::io_service& ios)
+ : detail::service_base<scgi_request_acceptor_service<protocol_type> >(ios)
+ , service_impl_(ios)
     {
     }
 
- /*
- request_service(protocol_service_type& ps)
- : detail::service_base<request_service<Protocol> >(ps.io_service())
- {
- }
- */
-
     void construct(implementation_type& impl)
     {
+ service_impl_.construct(impl);
     }
 
     void destroy(implementation_type& impl)
     {
+ service_impl_.destroy(impl);
     }
 
     void shutdown_service()
     {
+ service_impl_.shutdown_service();
+ }
+
+ bool is_open(implementation_type& impl)
+ {
+ return service_impl_.is_open(impl);
+ }
+
+ void close(implementation_type& impl)
+ {
+ boost::system::error_code ec;
+ service_impl_.close(impl, ec);
+ detail::throw_error(ec);
+ }
+
+ boost::system::error_code
+ close(implementation_type& impl, boost::system::error_code& ec)
+ {
+ return service_impl_.close(impl, ec);
+ }
+
+ template<typename Protocol>
+ boost::system::error_code
+ open(implementation_type& impl, const Protocol& protocol
+ , boost::system::error_code& ec)
+ {
+ return service_impl_.open(impl, protocol, ec);
+ }
+
+ template<typename Endpoint>
+ boost::system::error_code
+ bind(implementation_type& impl, const Endpoint& endpoint
+ , boost::system::error_code& ec)
+ {
+ return service_impl_.bind(impl, endpoint, ec);
     }
 
- boost::system::error_code& accept(implementation_type& impl
- , boost::system::error_code& ec)
+ boost::system::error_code
+ listen(implementation_type& impl, int backlog, boost::system::error_code& ec)
     {
-
+ return service_impl_.listen(impl, backlog, ec);
+ }
+
+ template<typename CommonGatewayRequest>
+ boost::system::error_code
+ accept(implementation_type& impl, CommonGatewayRequest& request
+ , boost::system::error_code& ec)
+ {
+ return service_impl_.accept(impl, request, ec);
+ }
+
+ template<typename CommonGatewayRequest, typename Endpoint>
+ boost::system::error_code
+ accept(implementation_type& impl, CommonGatewayRequest& request
+ , Endpoint* ep, boost::system::error_code& ec)
+ {
+ return service_impl_.accept(impl, request, ep, ec);
     }
 
     template<typename Handler>
     void async_accept(implementation_type& impl, Handler handler)
     {
-
+ service_impl_.async_accept(impl, handler);
+ }
+
+ template<typename T>
+ void set_protocol_service(implementation_type& impl, T& ps)
+ {
+ impl.service_ = &ps;
     }
+
+ typename implementation_type::endpoint_type
+ local_endpoint(implementation_type& impl, boost::system::error_code& ec)
+ {
+ return service_impl_.local_endpoint(impl, ec);
+ }
+
+ template<typename Protocol>
+ boost::system::error_code
+ assign(implementation_type& impl, Protocol protocol
+ , const native_type& native_acceptor, boost::system::error_code& ec)
+ {
+ return service_impl_.assign(impl, protocol, native_acceptor, ec);
+ }
+
+ public:
+ service_impl_type service_impl_;
   };
 
 } // namespace cgi
 
-#include "../detail/pop_options.hpp"
+#include "boost/cgi/detail/pop_options.hpp"
 
 #endif // CGI_REQUEST_SERVICE_HPP_INCLUDED
+

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_impl.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_impl.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_impl.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -11,25 +11,39 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include "../map.hpp"
-#include "../role_type.hpp"
-#include "../status_type.hpp"
-#include "../http/status_code.hpp"
-#include "../connections/tcp_socket.hpp"
+#include "boost/cgi/map.hpp"
+#include "boost/cgi/role_type.hpp"
+#include "boost/cgi/status_type.hpp"
+#include "boost/cgi/http/status_code.hpp"
+#include "boost/cgi/connections/tcp_socket.hpp"
+
+/**************
+ *
+ * THIS FILE IS OBSOLETE.
+ *
+ * SEE request_service.hpp:cgi::scgi::scgi_request_service::implementation_type
+ * INSTEAD.
+ *
+**************/
 
 namespace cgi {
+ namespace scgi {
 
+
+ /// The implementation_type for scgi_request_service
   class scgi_request_impl
   {
   public:
- typedef cgi::map map_type;
- typedef tcp_connection connection_type;
- typedef connection_type::pointer connection_ptr;
+ typedef cgi::map map_type;
+ typedef tcp_connection connection_type;
+ typedef connection_type::pointer connection_ptr;
+ typedef ::cgi::basic_client<connection_type> client_type;
 
     scgi_request_impl()
       : stdin_parsed_(false)
       , http_status_(http::ok)
       , request_status_(unloaded)
+ , request_finished_(false)
     {
     }
 
@@ -57,9 +71,10 @@
     map_type cookie_vars_;
 
     std::string null_str_;
-
+ bool request_finished_;
   };
 
+ } // namespace scgi
 } // namespace cgi
 
 #endif // CGI_SCGI_REQUEST_IMPL_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/request_service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -11,28 +11,66 @@
 
 #include <boost/system/error_code.hpp>
 
-#include "request_impl.hpp"
-#include "../map.hpp"
-#include "../tags.hpp"
-#include "../role_type.hpp"
-#include "../io_service.hpp"
-#include "../detail/throw_error.hpp"
-#include "../detail/service_base.hpp"
-#include "../detail/extract_params.hpp"
+//#include "boost/cgi/scgi/request_impl.hpp"
+#include "boost/cgi/map.hpp"
+#include "boost/cgi/tags.hpp"
+#include "boost/cgi/read.hpp"
+#include "boost/cgi/role_type.hpp"
+#include "boost/cgi/io_service.hpp"
+#include "boost/cgi/basic_client.hpp"
+#include "boost/cgi/connections/tcp_socket.hpp"
+#include "boost/cgi/detail/throw_error.hpp"
+#include "boost/cgi/detail/service_base.hpp"
+#include "boost/cgi/detail/extract_params.hpp"
 
 namespace cgi {
+ namespace scgi {
 
+ /// The IoObjectService class for a SCGI basic_request<>s
   class scgi_request_service
     : public detail::service_base<scgi_request_service>
   {
   public:
- typedef tags::scgi protocol_type;
- typedef scgi_request_impl implementation_type;
- typedef cgi::map map_type;
+ /// The actual implementation date for an SCGI request.
+ struct implementation_type
+ {
+ typedef ::cgi::map map_type;
+ typedef tcp_connection connection_type;
+ typedef ::cgi::scgi_ protocol_type;
+ typedef basic_client<
+ connection_type, protocol_type
+ > client_type;
+
+ implementation_type()
+ : client_()
+ , stdin_parsed_(false)
+ , http_status_(http::no_content)
+ , request_status_(unloaded)
+ , all_done_(false)
+ {
+ }
 
- scgi_request_service(cgi::io_service& ios)
+ client_type client_;
+
+ bool stdin_parsed_;
+ http::status_code http_status_;
+ status_type request_status_;
+
+ map_type env_vars_;
+ map_type get_vars_;
+ map_type post_vars_;
+ map_type cookie_vars_;
+
+ std::string null_str_;
+ bool all_done_;
+ };
+
+ typedef scgi_request_service type;
+ typedef type::implementation_type::protocol_type protocol_type;
+ typedef type::implementation_type::map_type map_type;
+
+ scgi_request_service(::cgi::io_service& ios)
       : detail::service_base<scgi_request_service>(ios)
- , io_service_(ios)
     {
     }
 
@@ -42,19 +80,50 @@
 
     void construct(implementation_type& impl)
     {
- impl.connection()
- = implementation_type::connection_type::create(this->io_service());
+ //std::cerr<< "request_service.hpp:83 Creating connection" << std::endl;
+ impl.client_.set_connection(//new implementation_type::connection_type(this->io_service()));
+ implementation_type::connection_type::create(this->io_service())
+ );
+ //std::cerr<< "conn.is_open() == " << impl.client_.is_open() << std::endl;
     }
 
     void destroy(implementation_type& impl)
     {
+ //if (!impl.all_done_)
+ // detail::abort_impl(impl); // this function isn't implemented yet!
       //impl.set_state(aborted);
     }
 
- boost::system::error_code& load(implementation_type& impl, bool parse_stdin
- , boost::system::error_code& ec)
+ void shutdown_service()
+ {
+ }
+
+ bool is_open(implementation_type& impl)
+ {
+ return !impl.all_done_ && impl.client_.is_open();
+ }
+
+ /// Close the request.
+ int close(implementation_type& impl, http::status_code& hsc
+ , int program_status)
     {
- const std::string& request_method = meta_env(impl, "REQUEST_METHOD", ec);
+ impl.all_done_ = true;
+ impl.client_.close();
+ return program_status;
+ }
+
+ boost::system::error_code&
+ load(implementation_type& impl, bool parse_stdin
+ , boost::system::error_code& ec)
+ {
+ //int header_len( get_length_of_header(impl, ec) );
+ BOOST_ASSERT(!ec);
+
+ std::vector<char> buf;
+ // read the header content
+ //::cgi::read(impl.client_, buffer(buf, header_len), ec);
+/*
+ const std::string& request_method = env(impl, "REQUEST_METHOD", ec);
       if (request_method == "GET")
         if (parse_get_vars(impl, ec))
               return ec;
@@ -64,9 +133,10 @@
               return ec;
 
       parse_cookie_vars(impl, ec);
- return ec;
+ */ return ec;
     }
 
+ /* These Don't Belong Here.
     template<typename MutableBufferSequence>
     std::size_t read_some(implementation_type& impl
                          , const MutableBufferSequence& buf
@@ -85,14 +155,15 @@
     }
 
     //template<typename VarType> map_type& var(implementation_type&) const;
+ ********************************************/
 
- std::string meta_get(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
+ std::string GET(implementation_type& impl, const std::string& name
+ , boost::system::error_code& ec)
     {
       return var(impl.get_vars_, name, ec);
     }
 
- map_type& meta_get(implementation_type& impl)
+ map_type& GET(implementation_type& impl)
     {
       return impl.get_vars_;
     }
@@ -109,9 +180,9 @@
      -----------------------------------------------
 
      */
- std::string meta_post(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec
- , bool greedy = true)
+ std::string POST(implementation_type& impl, const std::string& name
+ , boost::system::error_code& ec
+ , bool greedy = true)
     {
       const std::string& val = var(impl.post_vars_, name, ec);
       if (val.empty() && greedy && !ec)
@@ -122,7 +193,7 @@
       return val;
     }
 
- map_type& meta_post(implementation_type& impl)
+ map_type& POST(implementation_type& impl)
     {
       return impl.post_vars_;
     }
@@ -135,15 +206,15 @@
       return var(impl.cookie_vars_, name, ec);
     }
 
- map_type& meta_cookie(implementation_type& impl)
+ map_type& cookie(implementation_type& impl)
     {
       return impl.cookie_vars_;
     }
 
 
     /// Find the environment meta-variable matching name
- std::string meta_env(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
+ std::string env(implementation_type& impl, const std::string& name
+ , boost::system::error_code& ec)
     {
       return var(impl.env_vars_, name, ec);
     }
@@ -154,9 +225,15 @@
       return responder;
     }
 
+ implementation_type::client_type&
+ client(implementation_type& impl)
+ {
+ return impl.client_;
+ }
+
   protected:
     /// Extract the var value from
- std::string var(map_type& meta_data, const std::string& name
+ std::string var(map_type& _data, const std::string& _name
                    , boost::system::error_code& ec)
     {
       /* Alt:
@@ -168,8 +245,8 @@
       return std::string();
       **/
 
- if( meta_data.find(name) != meta_data.end() )
- return meta_data[name];
+ if( _data.find(_name) != _data.end() )
+ return _data[_name];
       return "";
     }
 
@@ -177,7 +254,7 @@
     boost::system::error_code&
     parse_get_vars(implementation_type& impl, boost::system::error_code& ec)
     {
- detail::extract_params(meta_env(impl, "QUERY_STRING", ec)
+ detail::extract_params(env(impl, "QUERY_STRING", ec)
                     , impl.get_vars_
                     , boost::char_separator<char>
                         ("", "=&", boost::keep_empty_tokens)
@@ -194,11 +271,11 @@
       // Make sure this function hasn't already been called
       //BOOST_ASSERT( impl.cookie_vars_.empty() );
 
- std::string vars = meta_env(impl, "HTTP_COOKIE", ec);
+ std::string vars = env(impl, "HTTP_COOKIE", ec);
       if (vars.empty())
         return ec;
 
- detail::extract_params(meta_env(impl, "HTTP_COOKIE", ec)
+ detail::extract_params(env(impl, "HTTP_COOKIE", ec)
                             , impl.cookie_vars_
                             , boost::char_separator<char>
                                 ("", "=&", boost::keep_empty_tokens)
@@ -234,9 +311,10 @@
     }
 
   private:
- cgi::io_service& io_service_;
+ //cgi::io_service& io_service_;
   };
 
+ } // namespace scgi
 } // namespace cgi
 
 #endif // CGI_SCGI_REQUEST_SERVICE_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/service.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/scgi/service.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,13 +9,19 @@
 #ifndef CGI_SCGI_SERVICE_HPP_INCLUDED__
 #define CGI_SCGI_SERVICE_HPP_INCLUDED__
 
-#include "../tags.hpp"
-#include "../basic_protocol_service.hpp"
+#include "boost/cgi/tags.hpp"
+#include "boost/cgi/basic_protocol_service.hpp"
 
 namespace cgi {
 
- typedef basic_protocol_service<tags::scgi> scgi_service;
+ //typedef basic_protocol_service<tags::scgi> scgi_service;
 
+ namespace scgi {
+
+ // typedef for standard scgi::service (a model of ProtocolService)
+ typedef basic_protocol_service< ::cgi::scgi_> service;
+
+ }
 } // namespace cgi
 
 #endif // CGI_SCGI_SERVICE_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/status_type.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/status_type.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/status_type.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -14,8 +14,9 @@
   enum status_type
     { null
     , unloaded
+ , activated
     , loaded
- , ok
+ , ok = loaded
     , aborted
     , closed
     };

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/streambuf.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/streambuf.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/streambuf.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -12,9 +12,14 @@
 #include <boost/asio/streambuf.hpp>
 
 namespace cgi {
+ namespace common {
 
   using boost::asio::streambuf;
 
+ } // namespace common
+
+ using common::streambuf;
+
 } // namespace cgi
 
 #endif // CGI_STREAMBUF_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/tags.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/tags.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/tags.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -9,7 +9,17 @@
 #ifndef CGI_TAGS_HPP_INCLUDED__
 #define CGI_TAGS_HPP_INCLUDED__
 
+#if _MSC_VER > 1020
+#pragma once
+#endif
+
 namespace cgi {
+
+ /// SCGI (note, this must be removed)
+ struct scgi_{};
+ /// FastCGI
+ struct fcgi_{};
+
  namespace tags {
 
    // the null tag type

Modified: sandbox/SOC/2007/cgi/trunk/boost/cgi/write.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/boost/cgi/write.hpp (original)
+++ sandbox/SOC/2007/cgi/trunk/boost/cgi/write.hpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -12,10 +12,16 @@
 #include <boost/asio/write.hpp>
 
 namespace cgi {
+ namespace common {
 
   using boost::asio::write;
   using boost::asio::async_write;
 
+ } // namespace common
+
+ //using common::write;
+ //using common::async_write;
+
 } // namespace cgi
 
 #endif // CGI_WRITE_HPP_INCLUDED

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-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -3,8 +3,8 @@
 # subject to the Boost Software License, Version 1.0. (See accompanying
 # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
-project boost_cgi
- : build-dir ../../../bin.v2
+project cgi.docs
+ #: build-dir ../../../bin.v2
   ;
 
 import boostbook : boostbook ;

Deleted: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/cgi.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/cgi.qbk 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
+++ (empty file)
@@ -1,47 +0,0 @@
-[/
- / 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)
- /]
-
-[article CGI
- [quickbook 1.3]
- [version 0.01]
- [id cgi]
- [dirname the_document_dir]
- [copyright 2007 Darren Garvey]
- [purpose Thoughts about CGI implementation]
- [authors [Garvey, Darren]]
- [license
- 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])
- ]
-]
-
-[def __cgi__ [@http://en.wikipedia.org/wiki/Common_Gateway_Interface CGI]]
-[def __scgi__ [@http://en.wikipedia.org/wiki/Simple_Common_Gateway_Interface SCGI]]
-[def __fcgi__ [@http://en.wikipedia.org/wiki/FastCGI FastCGI]]
-
-[def __asio__ [@http://asio.sourceforge.net Asio]]
-
-[def __reading_the_docs__ [link cgi.intro.reading_the_docs reading the docs]]
-[def __naming conventions__ [link cgi.intro.naming_conventions naming conventions]]
-
-[include preface.qbk]
-
-[include introduction.qbk]
-
-[section Tutorial]
-
-The tutorial is broken up into several parts, corresponding to the different protocols you can use.
-
-[include tutorial.qbk]
-
-[endsect]
-
-
-[xinclude autodoc.boostbook]
-
-[include reference.qbk]

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/building.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/building.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/building.qbk 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -27,7 +27,7 @@
     [Boost.Jam - `bjam`]
     [No]
     [
-Download 'boost-jam' (precomiled versions are highly recommended) and make it accessible by putting it somewhere pointed to by your system's PATH.
+Download 'boost-jam' (precompiled versions are highly recommended) and make it accessible by putting it somewhere pointed to by your system's PATH.
     ]
   ]
   [
@@ -38,7 +38,7 @@
 
 * Set the environment variable BOOST_ROOT on your system to the download location.
 
-* Go to the directory BOOST_ROOT and invoke `bjam` (see above). This should finish without any fails.
+* Go to the directory BOOST_ROOT and invoke `bjam --with-system install` (see above). This should finish without any fails.
     ]
   ]
   [
@@ -52,7 +52,7 @@
     [Unit tests]
     [Yes]
     [
-Tests can be run by going to the libs/cgi/test directory and invoking `bjam` (see above). Boost.CGI aims to be cross-platform, but not all platforms are available for testing. If any tests fail, problems can be reported to [link __reporting_problems__ here].
+Tests can be run by going to the libs/cgi/test directory and invoking `bjam` (see above). Boost.CGI aims to be cross-platform, but not all platforms are available for testing. If any tests fail, problems can be reported to [link __reporting_problems__ here], please.
     ]
   ]
   [

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/future_development.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/future_development.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/future_development.qbk 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -27,8 +27,8 @@
 
 [table
  [[Protocol][Native error reporting capabilities]]
- [[CGI] [Single error output stream (`std::cout`)]]
- [[SCGI] [A single output stream is shared between requests: Boost.CGI will guarantee thread-safe access to it.]]
+ [[CGI] [Single error output stream (`std::cerr`)]]
+ [[SCGI] [A single output stream (`std::cerr`) is shared between requests: Boost.CGI will guarantee thread-safe access to it.]]
  [[FastCGI] [Error stream per request. Inherently thread-safe.]]
 ]
 
@@ -38,11 +38,11 @@
 
 [h4 Session handling.]
 
-Access to persistent session data is a very useful stop-gap to using a complete RDBMS to store/retrieve data. In some cases, such as when an object is supposed to stay in active memory, a RDBMS will not be sufficient, so session management fits in nicely. A templated `basic_session<>` will be provided so various session-storage methods can be used. Boost.Interprocess is an ideal default, while Boost.UUID can be used to generate unique session identifiers.
+Access to persistent session data is a very useful stop-gap to using a complete RDBMS to store/retrieve data. In some cases, such as when an object is supposed to stay in active memory, a RDBMS will not be efficient, so session management fits in nicely. A templated `basic_session<>` will be provided so various session-storage methods can be used. Boost.Interprocess is an ideal default, while Boost.UUID can be used to generate unique session identifiers.
 
-[h4 Having `meta_*` functions return a `cgi::param` type instead of `std::string`]
+[h4 Having request variable functions return a `cgi::param` type instead of `std::string`]
 
-An advantage to this approach, for the functions that look up request meta-data, is that multiple values can be easily extracted from the same key, when they exist. Currently, a user must get the complete map of meta-data and use that themselves. [-Since environment meta-data can't be uniformly retrieved as a `cgi::map_type&` (since they are actually process-level environment variables, accessible only through `::getenv()`) this can be awkward.]
+An advantage to this approach, for the functions that look up request data, is that multiple values can be easily extracted from the same key, when they exist. Currently, a user must get the complete map of data and use that themselves.
 
 Another advantage is that a macro can be provided to turn on/off implicit conversion to `std::string`, which is in essence a form of tainting, akin to perl's taint mode.
 

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/introduction.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/introduction.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/introduction.qbk 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -11,34 +11,65 @@
 #include <boost/cgi/cgi.hpp>
 using namespace cgi;
 
-int main(int, char**)
+int main()
 {
   request req;
   response resp;
 
   resp<< "Hello there, Universe. "
- << "Oh wait, it's just you, " << req.form_("name")
- << ", isn't it?!";
- resp.send(req);
+ << "Oh wait, it's just you, " << req.form("name")
+ << ", isn't it.";
+
+ return_(req, resp, 0); // write the response and 'return 0;'
 }
 ``
 
-This CGI library reasonably high-level library for web programming. Herein the controller portion of the Model-View-Controller idiom is implemented. The intricacies of dealing with the widely varying specifications of CGI, FastCGI and SCGI are abstracted into three main parts:
+This CGI library is a reasonably high-level library for creating CGI, FastCGI or SCGI programs. Its scope is intentionally limited to the ''controller'' portion of the Model-View-Controller idiom. In other words, XML/HTML templates are not addressed, even if their use is highly recommended (consider having a look at google's cTemplate, or the upcoming ''Karma'' part of Boost.Spirit).
+
+[h4 Concepts]
+
+The library provides abstractions which hide details of the widely varying specifications of CGI, FastCGI and SCGI. These abstractions are briefly:
+
+[table
+[
+ [Concept] [Purpose]
+]
+[
+ [RequestAcceptor]
+ [CGI applications handle one request per process, while both SCGI and FastCGI allow each process to handle many requests, potentially at the same time. A RequestAcceptor makes it easy to ignore these differences and it also allows you to control how fast your process takes on new requests.
+ ]
+]
+[
+ [Request]
+ [Access to all request data is done through a Request object.]
+]
+[
+ [Client]
+ [Each request has an associated Client, which will usually represent a connection to the HTTP server associated with the current request.
+ ]
+]
+[
+ [ProtocolService]
+ [For those of you familiar with Boost.Asio, this is very similar to the `io_service` class (it actually uses one or more of these for its functionality). Its purpose is to provide certain guarantees when you are using asynchronous functions and/or multiple threads. The asynchronous stuff is what underpins this whole library.]
+]
+]
+
+[h4 Protcols]
 
-* Accepting,
+[:['See __protocol_details__ for more.]]
 
-* Loading, and
+In a nutshell, CGI is the simple and 'original' way of communicating with web servers. I'll assume you know what it is: one request per process and communication using standard input/output. A nice and simple way of making ['web pages that can change].
 
-* Handling.
+FastCGI was then developed as a means of allowing much more scalable CGI-like programs to be written. In fact, the FastCGI specification implies maximal efficiency was the main goal of the protocol. Communication with the server now works over sockets or pipes (only TCP sockets are supported for now). Each process and each connection can be used for handling multiple requests. In theory this means you could have a single monolithic process behind your HTTP server handling thousands of concurrent requests.
 
-Sometimes all a problem calls for is a thin interface to request data and '''I/O''' streams, without any need to be hyper-efficient: in other words, like a short CGI script that you can with [@http://tinyurl.com/2ss4ae perl], [@http://tinyurl.com/39b37l python], [@http://tinyurl.com/3yg4m8 php], etc. To allow this, the library and documentation are split into two parts: 'scripting' and 'everything else'. The code excerpt above is an example of a 'script' which, as you can see, skips the 'accepting' and 'loading' stages.
+SCGI is essentially a simpler version - hence [*S]imple[*CGI] - of FastCGI but is still a significant step up from vanilla CGI: as with FastCGI, each process can handle multiple requests. Use of FastCGI is recommended over SCGI, but unfortunately support for FastCGI is unreliable and buggy with some servers so it may not be a matter of choice.
 
-If a program's purpose is to serve the wider world, it should be written with scalability in mind. When it comes to heavily used web applications CGI has an inherent limitation: there must be a complete heavyweight process ['for every request].
+[h4 Multiple Requests per Process]
 
-The __FastCGI__ and __SCGI__ protocols are essentially reworkings of CGI which remove this restriction. They offer other advantages too, the support of which - of widely varying quality and completeness ([-more [link __server_support__ here]]) - comes for most HTTP servers. These protocols add an extra layer to your CGI programs, as you now must manage the request queue.
+So I keep harping on about this, that's because it removes so many limitations of traditional CGI programming. In return for the added complexity, your programs become complete servers, capable of handling arbitrary numbers of requests during each invocation (assuming they don't crash, or leak memory!). This gives you the freedom to keep database connections open between requests, or cache ready-parsed responses, for example. Processing of a client request can even be continued in the case of the client crashing - the `response` can then be stored and given to them when they return - saving precious CPU cycles.
 
-In return for the added complexity, your programs become complete servers, capable of handling arbitrary numbers of requests during each invocation (assuming they don't crash!). This gives you the freedom to keep database connections open between requests, or cache ready-parsed responses, for example. Processing of a client request can even be continued in the case of the client crashing - the `response` can then be stored and given to them when they return - saving precious CPU cycles.
+You might think dealing with request queues could be a handful but, fortunately, management of the queue (or queues, if you'd prefer) can be largely isolated from the handling of each request. That means that after you have set up a 'server' (ie. something that gathers requests), requests can be handled in much the same way as they would be with a standard CGI program that uses this library.
 
-It might sound like a handful but, fortunately, management of the request queue can be largely isolated from the handling of each request. That means that after you have set up a 'server' (ie. something that gathers requests), requests can be handled in the same way as they would be with a conventional CGI program.
+Now on to demonstrations...
 
 [endsect]

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/preface.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/preface.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/preface.qbk 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -13,13 +13,13 @@
 
 [h3 Overview]
 
-Boost.CGI is a library for writing CGI programs in Standard C++. It can be used to write anything from simple 'admin scripts' to full-fledged, scalable applications. This library rests on top of and should appear familiar to users of Boost.Asio, a cross-platform networking library in boost-style C++. Currently the __cgi__, [-__scgi__ and __fcgi__] protocols are supported, within a framework that should allow code to be reused with as-yet-unwritten protocols without any real modification.
+Boost.CGI is an open-source library for writing CGI programs in Standard C++. The library supports vanilla CGI, SCGI and FastCGI (SCGI/FastCGI don't really work yet) so it can be used to write anything from simple 'admin scripts' to full-fledged, scalable applications. This library rests on top of and should appear familiar to users of Boost.Asio, a cross-platform asynchronous networking library in boost-style C++. One of the main aims of the library is to allow programs to be written for any of the supported protocols without any real modification.
 
 [h3 Motivation]
 
-C++ isn't the language of choice for many CGI programmers, although it is a powerful one and can be used to produce maintainable and uncompromisingly efficient applications with any feature possible in any other language.
+C++ isn't the language of choice for many CGI programmers, despite being a powerful one that can be used to produce scalable, maintainable and uncompromisingly efficient applications.
 
-A complete discussion about the benefits of CGI programming in C++ is beyond the scope of this document, but here is a short list:
+A discussion about the benefits of CGI programming in C++ is beyond the scope of this document and I've assumed you're here because you want to try C++ CGI programming, but here is a short list anyway:
 
 * Having a binary application is inherently more secure than scripting languages in the situation where an error causes the application, rather than the output to be returned to the client. See http://www.w3.org/Security/Faq/wwwsf4.html for more.
 
@@ -29,9 +29,9 @@
 
 * In places where RAD (rapid application development) is of the utmost importance, scripting languages can still be used, for instance by using [link __boost_python__ Boost.Python] - though it could be argued that C++ and RAD are not mutually exclusive.
 
-* C++ is ['fast]. You can rest assured that the language will never be a bottleneck in your applications.
+* C++ is ['fast]. You can rest assured that the language will never be a bottleneck for your applications.
 
-* C++ rarely misses out on access to new technologies: for instance, if a new RDBMS came out tomorrow, it would almost certainly ship with a C/C++ API. The same would not be true for most other languages.
+* C++ rarely misses out on access to new technologies: for instance, if a new RDBMS came out tomorrow, it would almost certainly ship with a C/C++ API. The same would not be true for many other languages.
 
 * Web applications can benefit from an enforced modular design.[footnote For an example design choice, see [@http://www.google.co.uk/search?hl=en&rlz=1B3GGGL_enGB234GB235&q=model+view+controller&btnG=Search&meta= Model-View-Controller].] C++'s flexibility with regard to object-oriented design patterns is highly-regarded and well documented.
 
@@ -42,7 +42,7 @@
 [h3 How to use this manual]
 
 [note
-At the moment, the Boost [@http://www.boost.org/more/lib_guide.htm#Guidelines style guidelines] aren't honoured properly or consistently. Please ignore this for now, as the ambiguity is intentional and is simple enough to rectify.
+At the moment, the Boost [@http://www.boost.org/more/lib_guide.htm#Guidelines style guidelines] aren't honoured properly or consistently. Please ignore this for now, as the ambiguity is intentional (['since this [*is not] a Boost library]) and is simple enough to rectify.
 ]
 
 Start with the introduction, then the tutorial. You can skip the 'scripting' section, as that is a quickstart and the information in it is repeated throughout the rest of the manual. The doxygen header reference is very ugly for now and is going to be heavily reworked and reorganised.

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/user_guide/async_ops.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/user_guide/async_ops.qbk (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/doc/src/user_guide/async_ops.qbk 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -1,6 +1,6 @@
 [section:async Asynchronous Operations]
 
-Asynchronous functionality is inherited from __boost_asio__, which uses __IoService__s to manage I/O operations. Each program that uses an asynchronous __protocol__ requires a single __ProtocolService__ to service all requests in the program. Amongst other things, the ProtocolService uses an underlying IoService to run asynchronous operations.
+Asynchronous functionality is inherited from __boost_asio__, which uses __IoService__s to manage I/O operations. Each program that uses an asynchronous __protocol__ requires a single __ProtocolService__ to service all requests in the program. Amongst other things, the ProtocolService uses one or several underlying IoService(s) to handle asynchronous operations.
 
 The asynchronous operations provided by the library are:
 
@@ -10,7 +10,7 @@
 
 * Async __loading__ of request meta-data.
 
-Using asynchronous operations takes a bit of getting used to, but after overcoming the initial Conceptual hurdles, use of the library should be relatively straight-forward.
+Using asynchronous operations takes a bit of getting used to, but after overcoming the initial conceptual hurdles, use of the library should be relatively straight-forward.
 
 
 
@@ -20,4 +20,4 @@
 
 [/ link to the asio IoService concept docs; mention *briefly* what they are for; explain how the protocol services use an IoServiceProvider, linking to relevant examples in the examples section.]
 
-[endsect]
\ No newline at end of file
+[endsect]

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/Jamfile.v2 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -4,23 +4,32 @@
 # (See accompanying file LICENSE_1_0.txt or copy
 # at http://www.boost.org/LICENSE_1_0.txt)
 
+project boost.cgi.examples
+ : requirements
+ <library>/boost/system/
+ <library>/boost/thread/
+ ;
 
-import os ;
-
-local BOOST_ROOT = [ os.environ BOOST_ROOT ] ;
-
+# Install all of the acgi examples
+install acgi
+ : # sources
+ acgi//install
+ :
+ <location>$(cgi-bin)
+ ;
 
+explicit acgi ;
 
-install examples
- : # the sources
- ecgi
- acgi
- #reply
- : <location>/var/www/cgi-bin
- ;
+#install examples
+# : # the sources
+# ecgi
+# acgi
+# #reply
+# : <location>/var/www/cgi-bin
+# ;
 
 #install scgi
 # : # the sources
 # scgi
 # : <location>/var/www/scgi-bin
-# ;
\ No newline at end of file
+# ;

Deleted: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/main.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
+++ (empty file)
@@ -1,99 +0,0 @@
-#include <boost/cgi/acgi.hpp>
-#include <boost/cgi/response.hpp>
-#include <iostream>
-
-// class handler
-// {
-// public:
-// handler(cgi::request_ostream& ros, cgi::acgi::request& req)
-// : ros_(ros)
-// , req_(req)
-// {
-// }
-//
-// void operator()(boost::system::error_code& ec)
-// {
-// if (!ec)
-// {
-// ros_<< "All ok";
-// ros_.flush(req_);
-// }
-// }
-// private:
-// cgi::request_ostream& ros_;
-// cgi::acgi::request& req_;
-// };
-
-/**
- * The following example has a few simple stages.
- * It is best understood by compiling and testing it, and then looking at
- * the source code.
- */
-
-int main()
-{
- using namespace cgi::acgi;
-
- service srv;
- request req(srv);
-
- // Load up the request data
- req.load(true);
-
- response resp;
-
- if (req.get_("reset") == "true")
- {
- resp<< cookie("name")
- << location("acgi")
- << content_type("text/plain")
- << header();
- resp.send(req);
- return 0;
- }
-
- // First, see if they have a cookie set
- std::string& name = req.cookie_()["name"];
- if (!name.empty())
- {
- resp<< header("Content-type", "text/html")
- << header() // terminate the headers
- << "Hello again " << name << "<p />"
- << "<a href='?reset=true'><input type='submit' value='Reset' /></a>";
- resp.send(req);
- return 0;
- }
-
- // Now we'll check if they sent us a name in a form
- name = req.form_("name");
- if (!name.empty())
- {
- resp<< header("Content-type", "text/html")
- << cookie("name", name)
- << header() // terminate the headers
- << "Hello there, " << "<a href=''>" << name << "</a>";
- resp.send(req);
- return 0;
- }
-
- //std::string buf("Content-type: text/html\r\n\r\nHello there, Universe.<br />");
- //cgi::write(req, cgi::buffer(buf.c_str(), buf.size()));
-
- resp<< header("Content-type", "text/html")
- << header()
- << "Hello there, Universe.<p />"
- << "What's your name?<br />";
-
- //std::cerr<< std::endl << "name = " << req.form_("name") << std::endl;
- //std::cerr.flush();
-
- resp<< "<form method='POST'>"
- "<input name='name' type='text' value='" << req.form_("name") << "'>"
- "</input>"
- "<input type='submit'></input>"
- "</form>";
-
- resp.send(req);
-
- return 0;
-}

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/Jamfile.v2 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -22,7 +22,9 @@
     <library>../../util/system//boost_system
     #<library>l:/usr/local/lib/libboost_system.a
     <define>BOOST_ALL_NO_LIB=1
- <define>_CRT_SECURE_NO_DEPRECIATE=1
+ <define>_CRT_SECURE_NO_DEPRECATE=1
+ <define>_SCL_SECURE_NO_WARNINGS
+ <define>_CRT_SECURE_NO_WARNINGS
     <toolset>gcc:<linkflags>-lpthread
   ;
 

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/Jamfile.v2 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -2,29 +2,70 @@
 
 import testing ;
 
+project boost/cgi/test/compile
+ : requirements
+ <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE=1
+ <toolset>msvc:<define>_CRT_NONSTDC_NO_DEPRECATE=1
+ <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE=1
+ <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
+ <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS
+ ;
+
+#rule compile-test( name )
+#{
+# return [ run $(name).cpp ] ;
+#}
+
+#test-suite scgi_compile_tests
+# :
+# [ compile scgi_service.cpp ]
+# [ compile scgi_request.cpp ]
+# [ compile scgi_acceptor.cpp ]
+# :
+# <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE=1
+# <toolset>msvc:<define>_CRT_NONSTDC_NO_DEPRECATE=1
+# <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE=1
+# <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
+# <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS
+# ;
+
+#explicit scgi_compile_tests ;
+
+#test-suite acgi_compile_test
+# :
+# ;
+
 test-suite compile_test_suite
   :
     # connections
- [ compile stdio_connection.cpp ]
- [ compile async_stdio_connection.cpp ]
- [ compile tcp_connection.cpp ]
+ [ compile stdio_connection.cpp ]
+ [ compile async_stdio_connection.cpp ]
+ [ compile tcp_connection.cpp ]
+ [ compile shareable_tcp_connection.cpp ]
     
     # services
- [ compile acgi_service.cpp ]
-# [ compile fcgi_service.cpp ]
+ [ compile acgi_service.cpp ]
+ [ compile fcgi_service.cpp ]
 
     # requests
- [ compile cgi_request.cpp ]
- [ compile acgi_request.cpp ]
+ [ compile cgi_request.cpp ]
+ [ compile acgi_request.cpp ]
+ [ compile fcgi_request.cpp ]
 
     # response
- [ compile response.cpp ]
+ [ compile response.cpp ]
+
+ # acceptors
+ #[ compile acgi_acceptor.cpp ]
+ [ compile fcgi_acceptor.cpp ]
     
     # misc tests
- [ compile cgi_header_check.cpp ]
- [ compile is_async_test.cpp ]
+ [ compile cgi_header_check.cpp ]
+ [ compile is_async_test.cpp ]
   :
- <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECIATE=1
+ <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE=1
     <toolset>msvc:<define>_CRT_NONSTDC_NO_DEPRECATE=1
     <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE=1
   ;
+
+#explicit compile_test_suite ;

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/async_stdio_connection.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/async_stdio_connection.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/async_stdio_connection.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -2,8 +2,8 @@
 
 int main()
 {
- cgi::io_service ios;
- cgi::async_stdio_connection conn(ios);
+ cgi::common::io_service ios;
+ cgi::common::async_stdio_connection conn(ios);
 
   return 0;
 }

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/cgi_request.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/cgi_request.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/cgi_request.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -2,7 +2,7 @@
 
 int main()
 {
- cgi::cgi::request req;
+ cgi::request req;
 
   return 0;
 }

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/fcgi_service.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/fcgi_service.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/fcgi_service.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -1,8 +1,8 @@
-#include "boost/cgi/fcgi/fcgi_service.hpp"
+#include "boost/cgi/fcgi/service.hpp"
 
 int main()
 {
- cgi::fcgi_service s;
+ cgi::fcgi::service s;
 
   return 0;
 }

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/response.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/response.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/response.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -2,7 +2,7 @@
 
 int main(int, char**)
 {
- cgi::response resp;
+ cgi::common::response resp;
 
   resp<< "blah";
 

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/stdio_connection.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/stdio_connection.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/stdio_connection.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -2,7 +2,7 @@
 
 int main()
 {
- cgi::stdio_connection conn;
+ cgi::common::connection::stdio conn;
 
   return 0;
 }

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/tcp_connection.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/tcp_connection.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/compile/tcp_connection.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -2,8 +2,8 @@
 
 int main()
 {
- cgi::io_service ios;
- cgi::tcp_connection conn(ios);
+ cgi::common::io_service ios;
+ cgi::common::connection::tcp conn(ios);
 
   return 0;
 }

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/Jamfile.v2 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -3,9 +3,32 @@
 
 import testing ;
 
+project boost/cgi/tests/run
+ : requirements
+ <include>/usr/local/src/boost/sandbox/SOC/2006/process/tags/process-0.1
+ <library>/boost/test//boost_unit_test_framework/
+ <library>/boost/system/
+ <library>/boost/thread/
+ ;
+
+#local rule run-test( name )
+#{
+# return [
+# run $(name).cpp /boost/test//boost_unit_test_framework/<link>static
+# ] ;
+#}
+
 test-suite run_test_suite
   :
     #[ run [ glob *.cpp ] ]
     
     [ run cookie.cpp ]
+ [ run response.cpp ]
   ;
+
+test-suite wget_test
+ :
+ [ run wget.cpp : "--log_level=message" ]
+ ;
+
+explicit wget_test ;

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/cookie.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/cookie.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/cookie.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -5,7 +5,7 @@
  * - Verify it works with other string types (std::wstring is probably enough)
  */
 
-#define BOOST_TEST_MAIN
+#define BOOST_TEST_MODULE cookie_test
 #include <boost/test/unit_test.hpp>
 
 #include <sstream>
@@ -18,7 +18,9 @@
   // delete the cookie. ie. set its value to NULL and give it a date
   // in the past
   using namespace cgi;
+ using namespace std;
 
+ string ex("Fri, 05-Jun-1989 15:30:00 GMT");
   cookie ck("unwanted_cookie_name");
   
   BOOST_CHECK(ck.name == "unwanted_cookie_name");
@@ -26,7 +28,7 @@
   BOOST_CHECK(ck.path == "/");
   // this one could be more robust (by using a generic RFC2616 date parser)
   // see: http://www.apps.ietf.org/rfc/rfc2616.html#sec-3.3
- BOOST_CHECK(ck.data == "Fri, 05 Jun 1989 15:30:00 GMT");
+ BOOST_CHECK_EQUAL(ck.expires, ex);
   BOOST_CHECK(ck.domain == "");
   BOOST_CHECK(ck.secure == false);
   BOOST_CHECK(ck.http_only == false);
@@ -36,8 +38,11 @@
 {
   // Check the full version of the constructor works (simple test)
   using namespace cgi;
+ using namespace std;
 
- cookie ck("name", "value", "Wed, 03-Oct-2007 16:26:06 GMT"
+ string ex("Wed, 03-Oct-2007 16:26:06 GMT");
+
+ cookie ck("name", "value", ex
            , "/cookie", "example.com", false, true);
 
   BOOST_CHECK(ck.name == "name");
@@ -45,7 +50,7 @@
   BOOST_CHECK(ck.path == "/cookie");
   // this one could be more robust (by using a generic RFC2616 date parser)
   // see: http://www.apps.ietf.org/rfc/rfc2616.html#sec-3.3
- BOOST_CHECK(ck.data == "Wed, 03-Oct-2007 16:26:06 GMT");
+ BOOST_CHECK_EQUAL(ck.expires, ex);
   BOOST_CHECK(ck.domain == "example.com");
   BOOST_CHECK(ck.secure == false);
   BOOST_CHECK(ck.http_only == true);
@@ -80,9 +85,11 @@
   cookie_content = "name=value; expires=Wed, 03-Oct-2007 16:26:06 GMT;"
                    " path=/cookie; domain=example.com; secure; HttpOnly";
 
- cookie ck("name", "value", "Wed, 03-Oct-2007 16:26:06 GMT"
- , "/cookie", "example.com", true, true);
- oss.clear();
- oss<< ck;
- BOOST_CHECK(oss.str() == cookie_content);
+ cookie ck2("name", "value", "Wed, 03-Oct-2007 16:26:06 GMT"
+ , "/cookie", "example.com", true, true);
+ oss.str("");
+ BOOST_CHECK(oss.str() == "");
+ oss<< ck2;
+ string ostr(oss.str());
+ BOOST_CHECK_EQUAL(ostr, cookie_content);
 }

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/response.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/response.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/response.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -1,10 +1,87 @@
 // Test the cgi::response class works as advertised
-#define BOOST_TEST_MAIN
+#define BOOST_TEST_MODULE response_test
 #include <boost/test/unit_test.hpp>
 
 #include "boost/cgi/response.hpp"
 
+using namespace std;
+using namespace boost;
+
+class dummy_request
+{
+public:
+
+ template<typename ConstBufferSequence>
+ size_t write_some(ConstBufferSequence buf, boost::system::error_code ec)
+ {
+ return write_some(buf);
+ }
+
+ template<typename ConstBufferSequence>
+ size_t write_some(ConstBufferSequence buf)
+ {
+ typedef typename ConstBufferSequence::const_iterator iter;
+ size_t bytes_written = 0;
+
+ for( iter i = buf.begin(), e = buf.end()
+ ; i != e
+ ; ++i )
+ {
+ size_t len( asio::buffer_size(*i) );
+ buffer.append( asio::buffer_cast<const char*>(*i), len );
+ //buffer += b;
+ bytes_written += len;
+ }
+
+ return bytes_written;
+ }
+
+ std::string buffer;
+};
+
 BOOST_AUTO_TEST_CASE( response_test )
 {
- using namespace cgi;
-}
\ No newline at end of file
+ using namespace cgi::common;
+
+ dummy_request req;
+ string s ("Hello, world.");
+ string crlf ("\r\n");
+ string ct ("Content-type: text/non-plain");
+
+ {
+ response resp;
+ resp<< s
+ << content_type("text/non-plain");
+ resp.flush(req);
+
+ BOOST_CHECK( !req.buffer.empty() );
+ BOOST_CHECK_EQUAL( req.buffer, ct + crlf + crlf + s );
+
+ resp<< "...." << double(7.99);
+ resp.send(req);
+ BOOST_CHECK_EQUAL( req.buffer, ct + crlf + crlf + s + "....7.99" );
+
+ req.buffer.clear();
+ BOOST_CHECK( req.buffer.empty() );
+
+ resp.flush(req);
+ BOOST_CHECK_EQUAL( req.buffer, "....7.99" );
+
+ req.buffer.clear();
+ BOOST_CHECK( req.buffer.empty() );
+ } // destroy the response (no good way of clearing it now)
+
+ response resp;
+ resp<< content_type("text/non-plain")
+ << s
+ << header("Some", "other");
+
+ string expected( ct + crlf + "Some: other" + crlf + crlf + s );
+
+ resp.send(req);
+ BOOST_CHECK_EQUAL( req.buffer, expected );
+
+ resp.resend(req); // send it again
+ BOOST_CHECK_EQUAL( req.buffer, expected + expected );
+}
+

Modified: sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/stdio_connection.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/stdio_connection.cpp (original)
+++ sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/stdio_connection.cpp 2008-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -4,7 +4,7 @@
 
 int main()
 {
- cgi::stdio_connection conn;
+ cgi::common::connection::stdio conn;
 
   boost::system::error_code ec;
 

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-03-21 16:33:04 EDT (Fri, 21 Mar 2008)
@@ -1,4 +1,66 @@
 import os ;
+import modules ;
 
 path-constant BOOST_ROOT : [ os.environ BOOST_ROOT ] ;
 path-constant BOOST_BUILD_PATH : [ os.environ BOOST_BUILD_PATH ] ;
+
+path-constant PROJECT_ROOT : . ;
+
+path-constant top : . ;
+path-constant include-dir : /usr/local/include ;
+path-constant boost-root : [ os.environ BOOST_ROOT ] ;
+
+# A relative path to boost (for documentation stuff)
+path-constant boost-root-relative : $(top)/../../../../boost/trunk/ ;
+
+
+#############################################################################
+# Rule so we can extract install bin directories easily
+#
+# User can pass either:
+#
+# --cgi-bin=/path/to/cgi-bin (equally with fcgi-bin / scgi-bin)
+#
+# on the bjam command line OR set the environment variable:
+#
+# BOOST_CGI_BIN_PATH (equally with BOOST_FCGI_BIN_PATH / BOOST_SCGI_BIN_PATH)
+#
+# Note that the command line will override the environment variable!
+#############################################################################
+local rule get-bin-dir ( bin-name : envvar )
+{
+ local bin-dir = [ MATCH "^--$(bin-name)=(.*)" : [ modules.peek : ARGV ] ] ;
+ if $(bin-dir)
+ {
+ return $(bin-dir) ;
+ }
+ else
+ {
+ bin-dir = [ os.environ $(envvar) ] ;
+ if $(bin-dir)
+ {
+ return $(bin-dir) ;
+ }
+ return $(top)/$(bin-name) ;
+ }
+}
+
+path-constant cgi-bin : [ get-bin-dir "cgi-bin" : "BOOST_CGI_BIN_PATH" ] ;
+path-constant fcgi-bin : [ get-bin-dir "fcgi-bin" : "BOOST_FCGI_BIN_PATH" ] ;
+path-constant scgi-bin : [ get-bin-dir "scgi-bin" : "BOOST_SCGI_BIN_PATH" ] ;
+
+
+use-project /boost/ : $(boost-root) ;
+use-project /boost/cgi/ : $(top)/libs/cgi/build ;
+
+
+project cgi
+ : build-dir
+ $(top)/bin.v2
+ : requirements
+ <include>$(boost-root)
+ <include>$(top)
+ #<include>C:\cc\src\ctemplate\windows
+ <define>_CRT_SECURE_NO_WARNINGS
+ <define>_SCL_SECURE_NO_WARNINGS
+ ;


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