Boost logo

Boost-Commit :

From: lists.drrngrvy_at_[hidden]
Date: 2008-05-17 11:54:49


Author: drrngrvy
Date: 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
New Revision: 45453
URL: http://svn.boost.org/trac/boost/changeset/45453

Log:
Merged revisions 40139-43768,43770-43772,43774-43787,43789-43812,43814-45452 via svnmerge from
https://svn.boost.org/svn/boost/sandbox/SOC/2007/cgi/trunk

........
  r43780 | drrngrvy | 2008-03-21 20:59:00 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Adding shareable_tcp_socket.hpp to trunk
........
  r43783 | drrngrvy | 2008-03-21 21:13:06 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Copying basic_client.hpp to trunk.
........
  r43787 | drrngrvy | 2008-03-21 22:07:59 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Modified tags.hpp, adding shareable_tcp_socket
........
  r43791 | drrngrvy | 2008-03-21 22:22:42 +0000 (Fri, 21 Mar 2008) | 1 line
  
  Oops. Fix a possible buffer overflow.
........
  r43819 | drrngrvy | 2008-03-24 14:00:15 +0000 (Mon, 24 Mar 2008) | 1 line
  
  Removing SCGI examples (which haven't been tested)
........
  r43869 | drrngrvy | 2008-03-26 16:12:38 +0000 (Wed, 26 Mar 2008) | 1 line
  
  Minor fix to project-root.jam
........
  r43912 | drrngrvy | 2008-03-28 16:35:17 +0000 (Fri, 28 Mar 2008) | 1 line
  
  Adding basic FastCGI server example.
........
  r43917 | drrngrvy | 2008-03-28 22:01:04 +0000 (Fri, 28 Mar 2008) | 1 line
  
  Adding slightly more async FastCGI server example.
........
  r43918 | drrngrvy | 2008-03-28 22:10:40 +0000 (Fri, 28 Mar 2008) | 1 line
  
  Tiny addition moving towards an async_load function.
........
  r43933 | drrngrvy | 2008-03-29 18:31:19 +0000 (Sat, 29 Mar 2008) | 1 line
  
  Better docs.
........
  r43934 | drrngrvy | 2008-03-29 18:35:24 +0000 (Sat, 29 Mar 2008) | 1 line
  
  Added documentation to the examples.
........
  r43935 | drrngrvy | 2008-03-29 18:36:55 +0000 (Sat, 29 Mar 2008) | 1 line
  
  Modify project-root.jam to allow user to set htdocs directory (for amortization example files).
........
  r43973 | drrngrvy | 2008-03-31 21:02:15 +0100 (Mon, 31 Mar 2008) | 1 line
  
  Fixing cookie game example.
........
  r43974 | drrngrvy | 2008-03-31 21:06:39 +0100 (Mon, 31 Mar 2008) | 1 line
  
  Modifying jamfiles to make compiling examples easier.
........
  r43975 | drrngrvy | 2008-03-31 21:08:24 +0100 (Mon, 31 Mar 2008) | 1 line
  
  Modified CGI stuff to not use std::cout/cin/cerr, removing the dependence on <iostream> and reducing binary size a fair bit (seemingly making things faster too).
........
  r43977 | drrngrvy | 2008-04-01 04:23:32 +0100 (Tue, 01 Apr 2008) | 1 line
  
  basic_request<>::boundary_marker() is gone now.
........
  r43978 | drrngrvy | 2008-04-01 04:24:30 +0100 (Tue, 01 Apr 2008) | 1 line
  
  Cosmetic updates.
........
  r43979 | drrngrvy | 2008-04-01 04:29:41 +0100 (Tue, 01 Apr 2008) | 7 lines
  
  * Moved multipart/form-data parsing into separate form_parser class. It's only a crude start, but it works as well as before (maybe very slightly better).
  
  * Emptied request_ostream.hpp (should be gone soon).
  
  * Fixed connections/stdio.hpp - the last updates didn't actually use it properly so the problems with it didn't show up... Should work fine now, slightly better than when using std::cin functions.
........
  r44571 | drrngrvy | 2008-04-19 14:05:37 +0100 (Sat, 19 Apr 2008) | 1 line
  
  Factoring form_parser body into an ipp file.
........
  r44573 | drrngrvy | 2008-04-19 14:23:03 +0100 (Sat, 19 Apr 2008) | 9 lines
  
  * Added case-insensitive name type (typedef for std::basic_string<> using a custom traits class).
  * Modified cgi::map to use cgi::name as key.
  * Also modified files to include common/map.hpp instead of map.hpp.
  * Changed code because a std::string isn't automatically convertible to cgi::name
  * Fixed it so multiple cookies are parsed correctly.
  * Plus, other smallish fixes (cleanup / updating Boost.Thread compatibility).
........
  r44574 | drrngrvy | 2008-04-19 14:25:08 +0100 (Sat, 19 Apr 2008) | 1 line
  
  Small fixes to examples.
........
  r44576 | drrngrvy | 2008-04-19 14:32:06 +0100 (Sat, 19 Apr 2008) | 1 line
  
  Add a test which uses wget to check the output of the *cgi_hello_world examples through a server. It's not used by default, but has the BBv2 id of wget_test.
........
  r44577 | drrngrvy | 2008-04-19 14:34:48 +0100 (Sat, 19 Apr 2008) | 1 line
  
  Added basic tests for cgi::name and cgi::map and another for a cgi::request.
........
  r44578 | drrngrvy | 2008-04-19 14:40:56 +0100 (Sat, 19 Apr 2008) | 1 line
  
  Added simple test for acgi::request.
........
  r44879 | drrngrvy | 2008-04-29 13:22:22 +0100 (Tue, 29 Apr 2008) | 1 line
  
  Fix ichar_traits<>::compare(). Minor optimisations to ichar_traits<>::find() and save_environment().
........
  r44880 | drrngrvy | 2008-04-29 13:23:50 +0100 (Tue, 29 Apr 2008) | 1 line
  
  Extracting out cgi/acgi test commonality. Checking name(bar) < name(foo) in name_test too.
........
  r44898 | drrngrvy | 2008-04-29 22:08:35 +0100 (Tue, 29 Apr 2008) | 5 lines
  
  * Added basic_request<>::id() member function.
  * Changed basic_request<>::operator[] so that it decides at compile-time rather than runtime what data map is being accessed.
  * Added additional typedefs env_map, get_map, post_map, cookie_map, form_map corresponding to the dataset they obviously refer to - for now they are just typedefs to cgi::common::map, but eventually they may change - only to make code safer (eg. protect the user against XSS vulnerabilities).
........
  r44899 | drrngrvy | 2008-04-29 23:24:00 +0100 (Tue, 29 Apr 2008) | 1 line
  
  Moved a couple of common bits from cgi_service_impl_base and fcgi_request_service into common::request_base<>.
........
  r44908 | drrngrvy | 2008-04-30 03:31:09 +0100 (Wed, 30 Apr 2008) | 1 line
  
  Refactoring/housekeeping. Lots of common stuff has moved into common::request_base<> (this *isn't* the same as ::cgi::request_base - an old class that will be removed/replaced).
........
  r44909 | drrngrvy | 2008-04-30 03:31:32 +0100 (Wed, 30 Apr 2008) | 1 line
  
  Fix examples because of an interface change.
........

Added:
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_parser.ipp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/boost/cgi/common/form_parser.ipp
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/map.hpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/boost/cgi/common/map.hpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/name.hpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/boost/cgi/common/name.hpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/request_base.hpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/boost/cgi/common/request_base.hpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/source_enums.hpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/boost/cgi/common/source_enums.hpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/utility/
      - copied from r44909, /sandbox/SOC/2007/cgi/trunk/boost/cgi/utility/
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/amortization/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/echo/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/acgi/hello_world/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/echo/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/hello_world/
      - copied from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/hello_world/Jamfile.v2
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/hello_world/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/hello_world/main.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/cgi/hello_world/main.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/Jamfile.v2
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/amortization/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/echo/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/hello_world/
      - copied from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/hello_world/
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/hello_world/Jamfile.v2
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/hello_world/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/hello_world/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/hello_world/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/hello_world/main.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/hello_world/main.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server1/
      - copied from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server1/Jamfile.v2
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server1/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server1/main.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/main.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server1/server.hpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server1/server.hpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server2/
      - copied from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server2/
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server2/Jamfile.v2
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server2/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server2/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server2/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server2/main.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server2/main.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server3/
      - copied from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server3/
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server3/Jamfile.v2
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server3/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server3/doc.qbk
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server3/doc.qbk
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server3/main.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server3/main.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server4/
      - copied from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server4/
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server4/Jamfile.v2
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server4/Jamfile.v2
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/server4/main.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/example/fcgi/server4/main.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/acgi_simple_request.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/acgi_simple_request.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/cgi_simple_request.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/cgi_simple_request.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/hello_world.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/hello_world.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/map_test.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/map_test.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/name_test.cpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/name_test.cpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/request_test_template.hpp
      - copied unchanged from r44909, /sandbox/SOC/2007/cgi/trunk/libs/cgi/test/run/request_test_template.hpp
Removed:
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/data_sink.hpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/data_source.hpp
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/scgi/
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/servers/
Properties modified:
   sandbox/SOC/2007/cgi/branches/acceptor_work/ (props changed)
Text files modified:
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/acgi/request_impl.hpp | 1
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/acgi/request_service.hpp | 4
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_client.hpp | 22
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_request.hpp | 154 +++----
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_sync_io_object.hpp | 1
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/cgi/request_impl.hpp | 38 -
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/cgi/request_service.hpp | 2
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_parser.hpp | 89 +++
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_part.hpp | 2
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/connections/shareable_tcp_socket.hpp | 4
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/connections/stdio.hpp | 56 +-
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/cgi_request_impl_base.hpp | 20
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/cgi_service_impl_base.hpp | 824 +--------------------------------------
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/common_headers.hpp | 2
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/extract_params.hpp | 8
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/save_environment.hpp | 11
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/url_decode.hpp | 13
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/error.hpp | 9
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/acceptor_service_impl.hpp | 25 -
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/client.hpp | 5
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/request_service.hpp | 337 ++++-----------
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/io_service_provider.hpp | 4
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/map.hpp | 11
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/request_ostream.hpp | 7
   sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/response.hpp | 1
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/Jamfile.v2 | 23
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/acknowledgements.qbk | 35 +
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/cgi.qbk | 10
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/future_development.qbk | 28 -
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/introduction.qbk | 24
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/preface.qbk | 40 +
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/user_guide.qbk | 4
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/user_guide/examples.qbk | 75 ---
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/Jamfile.v2 | 49 +
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/Jamfile.v2 | 15
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/Jamfile.v2 | 14
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/main.cpp | 40 +
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/Jamfile.v2 | 7
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/main.cpp | 10
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/Jamfile.v2 | 12
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/main.cpp | 53 +-
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/Jamfile.v2 | 3
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/main.cpp | 4
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/Jamfile.v2 | 39 -
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/Jamfile.v2 | 12
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/main.cpp | 37
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/main.cpp | 6
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/Jamfile.v2 | 2
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/main.cpp | 71 ++
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/Jamfile.v2 | 8
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/response.cpp | 13
   sandbox/SOC/2007/cgi/branches/acceptor_work/project-root.jam | 58 ++
   52 files changed, 751 insertions(+), 1591 deletions(-)

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/acgi/request_impl.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/acgi/request_impl.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/acgi/request_impl.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -32,7 +32,6 @@
         connection_type, tags::acgi
>
     client_type;
- //typedef async_stdio_connection client_type;
 
     acgi_request_impl()
       : cgi_request_impl_base<connection_type>()

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/acgi/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/acgi/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/acgi/request_service.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -12,7 +12,7 @@
 #include "boost/cgi/acgi/request_impl.hpp"
 #include "boost/cgi/tags.hpp"
 #include "boost/cgi/io_service.hpp"
-#include "boost/cgi/map.hpp"
+#include "boost/cgi/common/map.hpp"
 #include "boost/cgi/detail/cgi_service_impl_base.hpp"
 #include "boost/cgi/detail/service_base.hpp"
 #include "boost/cgi/detail/extract_params.hpp"
@@ -28,8 +28,6 @@
   {
   public:
     typedef acgi_request_service type;
- typedef acgi_request_impl impl_type;
- typedef ::cgi::common::map map_type;
     typedef tags::acgi protocol_type;
     typedef acgi_service protocol_service_type;
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_client.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_client.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_client.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -11,12 +11,13 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include "boost/cgi/map.hpp"
+#include "boost/cgi/common/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"
 
+
 namespace cgi {
  namespace common {
 
@@ -110,9 +111,20 @@
     std::size_t read_some(const MutableBufferSequence& buf
                          , boost::system::error_code& ec)
     {
- std::size_t bytes_read = connection_->read_some(buf, ec);
- bytes_left_ -= bytes_read;
- return bytes_left_ > 0 ? bytes_read : (bytes_read + bytes_left_);
+ //if (boost::asio::buffer_size(buf) > bytes_left_)
+ //{
+ std::size_t bytes_read = connection_->read_some(buf, ec);
+ bytes_left_ -= bytes_read;
+ if (ec == boost::asio::error::eof)
+ ec = boost::system::error_code();
+ return bytes_left_ > 0 ? bytes_read : (bytes_read + bytes_left_);
+ //}
+ //else
+ //{
+ //
+ // ec = boost::asio::error::eof;
+ // return 0;
+ //}
     }
 
     /// Asynchronously write some data to the client.
@@ -131,6 +143,8 @@
   private:
     //io_service& io_service_;
     connection_ptr connection_;
+
+ public: // **FIXME**
     // we should never read more than content-length bytes.
     std::size_t bytes_left_;
   };

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_request.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_request.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_request.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -16,7 +16,6 @@
 
 #include "boost/cgi/detail/push_options.hpp"
 
-#include <iostream>
 #include <boost/noncopyable.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/assert.hpp>
@@ -29,7 +28,7 @@
 #include "boost/cgi/detail/protocol_traits.hpp"
 #include "boost/cgi/request_base.hpp"
 #include "boost/cgi/role_type.hpp"
-#include "boost/cgi/data_sink.hpp"
+#include "boost/cgi/common/source_enums.hpp"
 #include "boost/cgi/status_type.hpp"
 #include "boost/cgi/is_async.hpp"
 #include "boost/cgi/connection_base.hpp"
@@ -39,7 +38,7 @@
 #include "boost/cgi/basic_request_fwd.hpp"
 #include "boost/cgi/basic_sync_io_object.hpp"
 #include "boost/cgi/basic_io_object.hpp"
-#include "boost/cgi/map.hpp"
+#include "boost/cgi/common/map.hpp"
 
 namespace cgi {
  namespace common {
@@ -73,8 +72,8 @@
           , role_type Role
           , typename Allocator>
   class basic_request
- : public request_base
- , public boost::mpl::if_c<is_async<typename RequestService::protocol_type>::value
+ : //public request_base
+ public boost::mpl::if_c<is_async<typename RequestService::protocol_type>::value
                              , basic_io_object<RequestService>
                              , basic_sync_io_object<RequestService>
>::type
@@ -188,16 +187,17 @@
     }
 
 
+ // **FIXME**
     /// Asynchronously read/parse the request meta-data
     /**
      * Note: 'loading' including reading/parsing STDIN if parse_stdin == true
      */
- template<typename Handler>
- void async_load(Handler handler, bool parse_stdin = false)
- {
- this->service.async_load(this->implementation, parse_stdin
- , handler);
- }
+ //template<typename Handler>
+ //void async_load(Handler handler, bool parse_stdin = false)
+ //{
+ // this->service.async_load(this->implementation, parse_stdin
+ // , handler);
+ //}
 
     /// Notify the server the request has finished being handled
     /**
@@ -261,34 +261,6 @@
       return this->service.client(this->implementation);
     }
 
- /// Set the output for the request
- /**
- * Not Implemented Yet ******************
- *
- * Set the output sink as `stdout_`, `stderr_`, or `stdout_ | stderr_`
- */
- /*
- void set_output(cgi::sink dest = stdout_)
- {
- boost::system::error_code ec;
- this->service(this->implementation, dest, ec);
- detail::throw_error(ec);
- }
- */
-/*
- void read_some()
- {
- boost::system::error_code ec;
- this->service.read_some(this->implementationementation,ec);
- detail::throw_error(ec);
- }
-
- boost::system::error_code
- read_some(boost::system::error_code& ec)
- {
- return this->service.read_some(this->implementationementation, ec);
- }
-*/
     template<typename MutableBufferSequence>
     void read_some(const MutableBufferSequence& buf)
     {
@@ -318,12 +290,6 @@
     }
     */
 
- /// Get a `cgi::map&` corresponding to all of the GET variables
- map_type& GET()
- {
- return this->service.GET(this->implementation);
- }
-
     /// Find the get meta-variable matching name
     /**
      * @throws `boost::system::system_error` if an error occurred. This may
@@ -349,12 +315,6 @@
       return this->service.GET(this->implementation, name, ec);
     }
 
- /// Get a `cgi::map&` corresponding to all of the POST variables
- map_type& POST()
- {
- return this->service.POST(this->implementation);
- }
-
     /// Find the post meta-variable matching name
     /**
      * @param greedy This determines whether more data can be read to find
@@ -385,15 +345,6 @@
       return this->service.POST(this->implementation, name, ec, greedy);
     }
 
- /// Get a `cgi::map&` corresponding to all of the form variables
- map_type& form(bool greedy = true)
- {
- 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
     /**
      * Depending on the request's request_method, either the GET or the POST
@@ -429,12 +380,6 @@
         return "";
     }
 
- /// Get a `cgi::map&` corresponding to all of the HTTP_COOKIE variables
- map_type& cookie()
- {
- return this->service.cookie(this->implementation);
- }
-
     /// Find the cookie meta-variable matching name
     /**
      * @throws `boost::system::system_error` if an error occurred. This may
@@ -461,12 +406,6 @@
       return this->service.cookie(this->implementation, name, ec);
     }
 
- /// Get a `cgi::map&` corresponding to all of the environment variables
- map_type& env()
- {
- return this->service.env(this->implementation);
- }
-
     /// Find the environment meta-variable matching name
     /**
      * @throws `boost::system::system_error` if an error occurred. This may
@@ -506,7 +445,7 @@
      * 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(std::string const& name, bool greedy = false)
     {
       boost::system::error_code ec;
       std::string ret = var(name, ec, greedy);
@@ -620,32 +559,65 @@
       return this->service.get_role(this->implementation);
     }
 
- /// Get the strand associated with the request (if any)
- // Not sure if the strand concept should be kept separate or a member
- // function like basic_request<>::wrap() should be provided: in the case of
- // a synchronous request type the wrapping would still function as expected
- // and there would be no need for protocol-specific code in user programs.
- /* boost::asio::strand* strand()
+ void set_status(http::status_code const& status)
     {
- return this->implementation.strand();
+ this->service.set_status(this->implementation, status);
     }
- */
 
- /// Get the implementation type for the request
- //implementation_type* impl()
- //{
- // return &(this->implementation);
- //}
+ ////////////////////////////////////////////////////////////
+ // Note on operator[]
+ // ------------------
+ // It is overloaded on different enum types to allow
+ // compile-time (I hope) retrieval of different data
+ // maps.
+ //
+ /// Get a `common::env_map&` of all the environment variables.
+ env_map& operator[](common::env_data_type const&)
+ {
+ return this->implementation.env_vars();
+ }
 
- void set_status(http::status_code status)
+ /// Get a `common::get_map&` of all the GET variables.
+ get_map& operator[](common::get_data_type const&)
     {
- this->service.set_status(this->implementation, status);
+ return this->implementation.get_vars();
+ }
+
+ /// Get a `common::post_map&` of all the POST variables.
+ post_map& operator[](common::post_data_type const&)
+ {
+ return this->implementation.post_vars();
+ }
+
+ /// Get a `common::cookie_map&` of all the cookies.
+ cookie_map& operator[](common::cookie_data_type const&)
+ {
+ return this->implementation.cookie_vars();
     }
 
- // The boundary marker for multipart forms (this is likely a transient function).
- std::string boundary_marker()
+ /// Get a `common::form_map&` of either the GET or POST variables.
+ form_map& operator[](common::form_data_type const&)
+ {
+ if (request_method() == "GET")
+ return this->implementation.get_vars();
+ else
+ if (request_method() == "POST")
+ return this->implementation.post_vars();
+ else
+ return this->implementation.env_vars();
+ }
+ ////////////////////////////////////////////////////////////
+
+ /// The id of this request.
+ /**
+ * This is 1 for CGI/aCGI requests, but may be != 1 for FastCGI requests.
+ * Note that for FastCGI requests, the id's are assigned on a
+ * *per-connection* policy, so in one application you may have several
+ * requests with the same id.
+ */
+ int id()
     {
- return this->implementation.boundary_marker;
+ return this->service.request_id(this->implementation);
     }
   };
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_sync_io_object.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_sync_io_object.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/basic_sync_io_object.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -26,7 +26,6 @@
   protected:
     explicit basic_sync_io_object()
     {
- std::cerr<< "Hello";
       service.construct(implementation);
     }
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/cgi/request_impl.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/cgi/request_impl.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/cgi/request_impl.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -19,7 +19,7 @@
 #include "boost/cgi/connections/stdio.hpp"
 #include "boost/cgi/role_type.hpp"
 #include "boost/cgi/status_type.hpp"
-#include "boost/cgi/map.hpp"
+#include "boost/cgi/common/map.hpp"
 #include "boost/cgi/detail/cgi_request_impl_base.hpp"
 
 // Make this ProtocolService-independent
@@ -41,7 +41,6 @@
     : 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
@@ -61,42 +60,9 @@
     }
 
   protected:
- friend class cgi_service_impl;//<cgi_request_impl>;
+ friend class cgi_service_impl;
   };
 
- //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_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/cgi/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/cgi/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/cgi/request_service.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -26,11 +26,9 @@
   class cgi_request_service
    : public cgi_service_impl_base<cgi_request_impl>
   {
- typedef ::cgi::common::map map_type;
   public:
     typedef cgi_request_impl impl_type;
     typedef tags::cgi protocol_type;
- //typedef cgi_service_impl_base<cgi_request_impl> base;
 
     cgi_request_service()
       : cgi_service_impl_base<cgi_request_impl>()

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_parser.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_parser.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_parser.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -1,3 +1,11 @@
+// -- form_parser.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
 #ifndef CGI_DETAIL_FORM_PARSER_HPP_INCLUDED__
 #define CGI_DETAIL_FORM_PARSER_HPP_INCLUDED__
 
@@ -6,43 +14,94 @@
 #include <set>
 #include <vector>
 #include <string>
+#include <boost/regex.hpp>
 #include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
 #include <boost/function.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/algorithm/string/find.hpp>
 #include "boost/cgi/common/form_part.hpp"
+#include "boost/cgi/basic_client.hpp"
 
 namespace cgi {
  namespace detail {
 
- /// Destined for greater things than an implementation detail.
+ /// Destined for better things than an implementation detail (hopefully).
+ template<typename RequestImplType>
   class form_parser
   {
   public:
- typedef
- boost::function<
- std::size_t (
- const boost::asio::mutable_buffer&
- , boost::system::error_code& )
- >
- callback_type;
+ //typedef
+ // boost::function<
+ // std::size_t (
+ // const mutable_buffers_type&
+ // , boost::system::error_code& )
+ // >
+ //callback_type;
+
+ typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
+ typedef std::vector<char> buffer_type;
+ typedef ::cgi::common::map map_type;
 
- typedef std::vector<char> buffer_type;
+ typedef RequestImplType implementation_type;
 
- form_parser()
- {
+ form_parser(implementation_type& impl);
 
+ mutable_buffers_type prepare(std::size_t size)
+ {
+ std::size_t bufsz(impl_.buffer_.size());
+ impl_.buffer_.resize(bufsz + size);
+ return boost::asio::buffer(&impl_.buffer_[bufsz], size);
+ }
+
+ std::string buffer_string()
+ {
+ return std::string(impl_.buffer_.begin() + offset_, impl_.buffer_.end());
     }
     
+ boost::system::error_code
+ parse(boost::system::error_code& ec);
+
+ boost::system::error_code
+ parse_url_encoded_form(boost::system::error_code& ec);
+
+ boost::system::error_code
+ parse_multipart_form(boost::system::error_code& ec);
+
+ boost::system::error_code
+ parse_form_part(boost::system::error_code& ec);
+
+ boost::system::error_code
+ parse_form_part_data(boost::system::error_code& ec);
+
+ boost::system::error_code
+ parse_form_part_meta_data(boost::system::error_code& ec);
+
+ boost::system::error_code
+ move_to_start_of_first_part(boost::system::error_code& ec);
+
+ /// Get the boundary marker from the CONTENT_TYPE header.
+ boost::system::error_code
+ parse_boundary_marker(boost::system::error_code& ec);
+
   private:
- std::set<std::string> boundary_markers_;
- std::vector<common::form_part> form_parts_;
+ implementation_type& impl_;
+ std::size_t& bytes_left_;
+ buffer_type::iterator pos_;
+ //bool& stdin_data_read_;
+ std::size_t offset_;
 
- //buffer_type& buffer_;
+ std::string boundary_marker;
+ std::list<std::string> boundary_markers;
+ std::vector<common::form_part> form_parts_;
 
- callback_type callback_;
+ //callback_type callback_;
   };
 
  } // namespace detail
 } // namespace cgi
 
+#include "boost/cgi/common/form_parser.ipp"
+
 #endif // CGI_DETAIL_FORM_PARSER_HPP_INCLUDED__
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_part.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_part.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/common/form_part.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -37,7 +37,7 @@
      pair_t buffer_;
 
      std::string content_type; // must exist
- std::string name; // Has to exist?
+ std::string name; // must exist (?) **FIXME**
 
      // Using a simple map while everything is changing. This will not copy the
      // values when it is properly implemented (it'll hold a pair of iterators

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/connections/shareable_tcp_socket.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/connections/shareable_tcp_socket.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/connections/shareable_tcp_socket.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -63,8 +63,8 @@
     /** End FastCGI stuff **/
 
     // A wrapper to provide condition_type::pointer
- struct condition_type : public boost::condition
- { typedef boost::shared_ptr<boost::condition> pointer; };
+ struct condition_type : public boost::condition_variable
+ { typedef boost::shared_ptr<boost::condition_variable> pointer; };
 
     basic_connection(io_service& ios)
       : sock_(ios)

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/connections/stdio.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/connections/stdio.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/connections/stdio.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -9,9 +9,7 @@
 #ifndef CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
 #define CGI_STDIO_CONNECTION_IMPL_HPP_INCLUDED__
 
-#include <iostream>
-#include <istream>
-#include <ostream>
+#include <cstdio>
 #include <string>
 #include <boost/system/error_code.hpp>
 #include <boost/asio.hpp>
@@ -19,7 +17,7 @@
 #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/error.hpp"
 //#include "boost/cgi/io_service.hpp"
 
 namespace cgi {
@@ -61,32 +59,23 @@
     template<typename MutableBufferSequence>
     std::size_t read_some(MutableBufferSequence buf
                          , boost::system::error_code& ec)
- {
- 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())
+ {
+ if (std::fread(boost::asio::buffer_cast<void *>(buf)
+ , boost::asio::buffer_size(buf)
+ , 1, stdin))
       {
- ec = boost::system::error_code(654, boost::system::system_category);
- return 0;
+ return strlen(boost::asio::buffer_cast<char *>(buf));
       }
- //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();
+
+ if (std::feof(stdin))
+ ec = boost::asio::error::eof;
+ else
+ if (std::ferror(stdin))
+ ec = ::cgi::error::bad_read;
+ else
+ ec = ::cgi::error::broken_pipe;
+
+ return 0;
     }
 
     template<typename ConstBufferSequence>
@@ -99,7 +88,16 @@
       {
         std::size_t buf_len = boost::asio::buffer_size(*i);
         bytes_transferred += buf_len;
- std::cout.write(boost::asio::buffer_cast<const char*>(*i), buf_len);
+ int ret( fputs(boost::asio::buffer_cast<const char*>(*i), stdout) );
+ if (ret == EOF)
+ {
+ return ::cgi::error::broken_pipe;
+ }
+ //else
+ //if (ret < 0)
+ //{
+ // return ::cgi::error::
+ //std::cout.write(boost::asio::buffer_cast<const char*>(*i), buf_len);
       }
       return bytes_transferred;
     }

Deleted: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/data_sink.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/data_sink.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
+++ (empty file)
@@ -1,27 +0,0 @@
-// -- data_sink.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_DATA_SINK_HPP_INCLUDED__
-#define CGI_DATA_SINK_HPP_INCLUDED__
-
-namespace cgi {
-
- enum sink
- { stdout_ = 0
- , stderr_ = 1
- };
-
- namespace data_sink {
-
- //struct stdout_ {};
- //struct stderr_ {};
-
- } // namespace data_sink
-} // namespace cgi
-
-#endif // CGI_DATA_SINK_HPP_INCLUDED__

Deleted: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/data_source.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/data_source.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
+++ (empty file)
@@ -1,24 +0,0 @@
-// -- data_source.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_DATA_SOURCE_HPP_INCLUDED__
-#define CGI_DATA_SOURCE_HPP_INCLUDED__
-
-namespace cgi {
-
- enum source
- { stdin_ };
-
- namespace data_source {
-
- //struct stdin_ {};
-
- } // namespace data_source
-} // namespace cgi
-
-#endif // CGI_DATA_SOURCE_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/cgi_request_impl_base.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/cgi_request_impl_base.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/cgi_request_impl_base.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -18,8 +18,10 @@
 #include "boost/cgi/connections/stdio.hpp"
 #include "boost/cgi/role_type.hpp"
 #include "boost/cgi/status_type.hpp"
-#include "boost/cgi/map.hpp"
-//#include
+#include "boost/cgi/common/map.hpp"
+
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/support.hpp>
 
 // Make this ProtocolService-independent
 
@@ -38,6 +40,7 @@
    */
   template<typename Connection>
   class cgi_request_impl_base
+
   {
   public:
     typedef ::cgi::common::map map_type;
@@ -56,28 +59,17 @@
     {
     }
 
- map_type& env_vars() { return env_vars_; }
- map_type& get_vars() { return get_vars_; }
- map_type& post_vars() { return post_vars_; }
- map_type& cookie_vars() { return cookie_vars_; }
-
     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_; }
 
- protected:
+ public:
     //conn_ptr connection() { return connection_; }
 
     //friend class cgi_service_impl_base<RequestImpl>;
 
- map_type env_vars_;
- map_type get_vars_;
- map_type post_vars_;
- map_type cookie_vars_;
-
   public:
     bool stdin_parsed_;
     bool stdin_data_read_;

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/cgi_service_impl_base.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/cgi_service_impl_base.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/cgi_service_impl_base.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -1,3 +1,11 @@
+// -- detail/cgi_service_impl_base.hpp --
+//
+// Copyright (c) Darren Garvey 2007-2008.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
 #ifndef CGI_CGI_SERVICE_IMPL_BASE_HPP_INCLUDED__
 #define CGI_CGI_SERVICE_IMPL_BASE_HPP_INCLUDED__
 
@@ -5,7 +13,6 @@
 
 #include <string>
 #include <cstdlib>
-#include <iostream>
 #include <boost/assert.hpp>
 #include <boost/regex.hpp>
 #include <boost/tokenizer.hpp>
@@ -13,7 +20,7 @@
 #include <boost/system/error_code.hpp>
 #include <boost/algorithm/string/find.hpp>
 
-#include "boost/cgi/map.hpp"
+#include "boost/cgi/common/map.hpp"
 #include "boost/cgi/basic_client.hpp"
 #include "boost/cgi/role_type.hpp"
 #include "boost/cgi/status_type.hpp"
@@ -23,6 +30,7 @@
 #include "boost/cgi/detail/throw_error.hpp"
 
 #include "boost/cgi/common/form_parser.hpp"
+#include "boost/cgi/common/request_base.hpp"
 
 namespace cgi {
 
@@ -31,12 +39,10 @@
 
  } // namespace detail
 
- using std::cerr; // **FIXME**
- using std::endl; // **FIXME**
-
 
   template<typename RequestImplType>
   class cgi_service_impl_base
+ : public common::request_base<cgi_service_impl_base<RequestImplType> >
   {
   public:
     //typedef RequestImplType implementation_type;
@@ -53,106 +59,24 @@
 
     struct implementation_type
       : RequestImplType
+ , common::request_base<
+ cgi_service_impl_base<RequestImplType>
+ >::impl_base
     {
- typedef boost::asio::const_buffers_1 const_buffers_type;
- typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
- typedef typename RequestImplType::client_type client_type;
- typedef std::vector<char> buffer_type;
- //typedef std::list<std::string>::iterator marker_list_type;
+ typedef typename RequestImplType::client_type client_type;
+ typedef detail::form_parser<implementation_type> form_parser_type;
 
       implementation_type()
- : //buffer_()
- //, istream_(&buffer_)
- pos_()
- , offset_(0)
- , fp_(NULL)
+ : fp_(NULL)
       {
       }
 
       client_type client_;
 
- std::string boundary_marker;
- std::list<std::string> boundary_markers;
- //std::vector<char> data_buffer_;
       // The number of characters left to read (ie. "content_length - bytes_read")
       std::size_t characters_left_;
       
- //std::vector<char>::iterator read_pos_;
- //boost::asio::streambuf buffer_;
- //std::istream istream_;
-
- buffer_type buf_;
- typename buffer_type::iterator pos_;
- std::size_t offset_;
- //boost::sub_match<typename buffer_type::iterator> offset_;
- std::vector<common::form_part> form_parts_;
-
- detail::form_parser* fp_;
-
- /*
- mutable_buffers_type prepare(typename buffer_type::iterator& pos, std::size_t size)
- {
- std::size_t bufsz( buf_.size() );
-
- // Reserve more space if it's needed.
- // (this could be safer, referencing this against CONTENT_LENGTH)
- if ( (bufsz + size) >= buf_.capacity() )
- {
- buf_.resize(bufsz + size);
- }
-
- return boost::asio::buffer(&(buf_.begin()), size);
- // return boost::asio::buffer(&buf_[bufsz], size);
- }
- */
-
- mutable_buffers_type prepare(std::size_t size)
- {
-
- std::size_t bufsz( buf_.size() );
- cerr<< "bufsz = " << bufsz << endl;
-
- // Reserve more space if it's needed.
- // (this could be safer, referencing this against CONTENT_LENGTH)
- //if ( (bufsz + size) >= buf_.capacity() )
- //{
- buf_.resize(bufsz + size);
- //}
-
- cerr<< "Pre-read buffer (size: " << buf_.size()
- << "|capacity: " << buf_.capacity() << ") == {" << endl
- << std::string(buf_.begin() + offset_, buf_.end()) << endl
- // << "-----end buffer-----" << endl
- // << "-------buffer-------" << endl
- // << std::string(&buf_[0], &buf_[buf_.size()]) << endl
- << "}" << endl;
- ;
- //return boost::asio::buffer(&(*(buf_.end())), size);
- // return boost::asio::buffer(&(*(buf_.begin())) + bufsz, size);
- return boost::asio::buffer(&buf_[bufsz], size);
- }
-
- std::string buffer_string()
- {
- return std::string(buf_.begin() + offset_, buf_.end());
- //return std::string(pos_, buf_.size());//buf_.end());
- }
- /*
- // Silently ignore a request to grow the buffer greater than the
- // content-length allows.
- // Note: this will break if the contents of the buffer are ever changed
- // (such as if data is url-decoded and inserted back into the buffer).
- if (size >= characters_left_)
- {
- size = characters_left_;
- }
-
- data_buffer_.reserve(bufsz + size);
- return boost::asio::buffer(data_buffer_.begin() + bufsz
- , data_buffer_.capacity() - bufsz);
- }
- */
- //boost::acgi::form_entry form_;
+ boost::scoped_ptr<form_parser_type> fp_;
     };
 
     /// Return if the request is still open
@@ -173,6 +97,8 @@
       return impl.client_;
     }
 
+ int request_id(implementation_type& impl) { return 1; }
+
     int close(implementation_type& impl, http::status_code& http_s, int status)
     {
       impl.status() = closed;
@@ -189,20 +115,20 @@
           , boost::system::error_code& ec)
     {
       detail::save_environment(impl.env_vars());
- const std::string& cl = var(impl.env_vars(), "CONTENT_LENGTH", ec);
+ std::string const& cl = impl.env_vars()["CONTENT_LENGTH"];
       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);
+ std::string const& request_method = impl.env_vars()["REQUEST_METHOD"];
       if (request_method == "GET")
- parse_get_vars(impl, ec);
+ this->parse_get_vars(impl, ec);
       else
       if (request_method == "POST" && parse_stdin)
         parse_post_vars(impl, ec);
 
       if (ec) return ec;
 
- parse_cookie_vars(impl, ec);
+ this->parse_cookie_vars(impl, ec);
       impl.status() = loaded;
 
       //BOOST_ASSERT(impl.status() >= loaded);
@@ -210,69 +136,6 @@
       return ec;
     }
 
- std::string&
- var(map_type& meta_data, const std::string& name
- , boost::system::error_code& ec)
- {
- return meta_data[name];
- }
-
- std::string
- GET(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
- {
- //BOOST_ASSERT(impl.status() >= loaded);
- return var(impl.get_vars(), name, ec);
- }
-
- map_type&
- GET(implementation_type& impl)
- {
- //BOOST_ASSERT(impl.status() >= loaded);
- return impl.get_vars();
- }
-
- /// Find the post meta-variable matching name
- /**
- * @param greedy This determines whether more data can be read to find
- * the variable. The default is true to cause least surprise in the common
- * case of having not parsed any of the POST data.
-
- -----------------------------------------------
- Should this return a pair of iterators instead?
- What about url_decoding?
- -----------------------------------------------
-
- */
- std::string
- POST(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec, bool greedy = true)
- {
- //BOOST_ASSERT(impl.status() >= loaded);
- const std::string& val = var(impl.post_vars(), name, ec);
- if (val.empty() && greedy && !ec)
- {
-
- }
-
- return val;
- }
-
- map_type&
- POST(implementation_type& impl)
- {
- //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
@@ -286,6 +149,7 @@
                         if (rm == "POST")
                           return POST(impl, name, ec);
                         else
+ // **FIXME** What about HEAD, PUT ???
                           return "***BOOST_CGI_ERROR_INVALID_REQUEST_METHOD***";
                 }
                 
@@ -303,41 +167,6 @@
                           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)
- {
- //BOOST_ASSERT(impl.status() >= loaded);
- return var(impl.cookie_vars(), name, ec);
- }
-
- map_type&
- cookie(implementation_type& impl)
- {
- //BOOST_ASSERT(impl.status() >= loaded);
- return impl.cookie_vars();
- }
-
-
- /// Find the environment meta-variable matching name
- std::string
- env(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
- {
- //BOOST_ASSERT(impl.status() >= loaded);
- const char* c = ::getenv(name.c_str());
- return c ? c : std::string();
- }
-
- map_type&
- env(implementation_type& impl)
- {
- //BOOST_ASSERT(impl.status() >= loaded);
- return impl.env_vars();
- }
-
-
     role_type
       get_role(implementation_type& impl)
     {
@@ -350,46 +179,6 @@
     }
 
   protected:
- /// Read and parse the cgi GET meta variables
- template<typename RequestImpl>
- 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);
-
- std::string& vars = impl.env_vars()["QUERY_STRING"];
- if (vars.empty())
- return ec;
-
- detail::extract_params(vars, impl.get_vars()
- , boost::char_separator<char>
- ("", "=&", boost::keep_empty_tokens)
- , ec);
-
- return ec;
- }
-
- /// Read and parse the HTTP_COOKIE meta variable
- template<typename RequestImpl>
- 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);
-
- std::string& vars(impl.env_vars()["HTTP_COOKIE"]);
- if (vars.empty())
- return ec;
-
- detail::extract_params(vars, impl.cookie_vars()
- , boost::char_separator<char>
- ("", "=&", boost::keep_empty_tokens)
- , ec);
-
- return ec;
- }
-
     /// Read and parse the cgi POST meta variables (greedily)
     template<typename RequestImpl>
     boost::system::error_code
@@ -398,563 +187,12 @@
       // Make sure this function hasn't already been called
       //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;
- map_type& post_map(impl.post_vars());
-
- while( is.get(ch) && impl.characters_left_-- )
- {
- //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.append(1, ' ');
- break;
- case ' ':
- continue;
- case '=': // the name is complete, now get the corresponding value
- name = str;
- str.clear();
- break;
- case '&': // we now have the name/value pair, so save it
- post_map[name] = str;
- str.clear();
- name.clear();
- break;
- default:
- str.append(1, ch);
- }
- }
- // save the last param (it won't have a trailing &)
- if( !name.empty() )
- 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
- parse_one_post_var(RequestImpl& impl, boost::system::error_code& ec)
- {
- //# error "Not implemented"
+ impl.fp_.reset
+ (
+ new typename implementation_type::form_parser_type
+ ( impl )
+ );
+ impl.fp_->parse(ec);
       return ec;
     }
   };

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/common_headers.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/common_headers.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/common_headers.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -13,7 +13,7 @@
 // headers can just include this after other headers.
 
 #include "boost/cgi/buffer.hpp"
-#include "boost/cgi/map.hpp"
+#include "boost/cgi/common/map.hpp"
 #include "boost/cgi/io_service.hpp"
 #include "boost/cgi/streambuf.hpp"
 #include "boost/cgi/basic_request.hpp"

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/extract_params.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/extract_params.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/extract_params.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -13,7 +13,7 @@
 #include <boost/tokenizer.hpp>
 #include <boost/system/error_code.hpp>
 
-#include "url_decode.hpp"
+#include "boost/cgi/detail/url_decode.hpp"
 
 namespace cgi {
  namespace detail {
@@ -47,9 +47,9 @@
          name = current_token;
          current_token.clear();
        }else
- if( *iter == "&" )
+ if( *iter == "&" || *iter == ";" )
        {
- destination[name] = current_token;
+ destination[name.c_str()] = current_token;
          current_token.clear();
          name.clear();
        }else
@@ -58,7 +58,7 @@
        }
      }
      if( !name.empty() )
- destination[name] = current_token;
+ destination[name.c_str()] = current_token;
 
      return ec;
    }

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/save_environment.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/save_environment.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/save_environment.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -12,7 +12,7 @@
 #include <map>
 #include <string>
 #include <cstdlib>
-#include "boost/cgi/map.hpp"
+#include "boost/cgi/common/map.hpp"
 
 // The process' environment
 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
@@ -34,6 +34,9 @@
    template<typename MapT>
    void save_environment(MapT& env_map, char** env = environ)
    {
+ std::string sa;
+ std::string sb;
+
      for(; *env; ++env)
      {
        int i=0;
@@ -46,9 +49,9 @@
        // we are free to ignore them too.
        if ((*env)[i+1] != '\0')
        {
- std::string sa(*env, i);
- std::string sb((*env+i+1), j-i-1);
- env_map[sa] = sb;
+ sa.assign(*env, i);
+ sb.assign((*env+i+1), j-i-1);
+ env_map[sa.c_str()] = sb;
        }
      }
    }

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/url_decode.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/url_decode.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/detail/url_decode.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -54,13 +54,6 @@
      return static_cast<char>(ret);
    }
 
- /// Workaround for istreams, since the above can't be used directly
- char url_decode(std::istream& is)
- {
- const char c1 = is.get();
- return url_decode(c1, is.get());
- }
-
    /// URL-decode a string
    std::string url_decode( const std::string& str )
    {
@@ -77,9 +70,9 @@
            ret.append(1, ' ');
            break;
          case '%':
- if (std::isxdigit(*(iter+1))
- && std::isxdigit(*(iter+2))
- && std::distance(iter, end) >= 2)
+ if (std::distance(iter, end) >= 2
+ && std::isxdigit(*(iter+1))
+ && std::isxdigit(*(iter+2)))
            {
              char ch = *++iter; // need this because order of function arg
                                 // evaluation is UB.

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/error.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/error.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/error.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -50,7 +50,14 @@
   // allowed.
   accepting_on_an_open_request,
 
- invalid_socket
+ invalid_socket,
+
+ // Used in basic_connection<tags::stdio>
+ // **FIXME**
+ broken_pipe,
+
+ // **FIXME**
+ bad_read
 };
 
   namespace detail {

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/acceptor_service_impl.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/acceptor_service_impl.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/acceptor_service_impl.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -34,7 +34,7 @@
    namespace detail {
 
      /// Helper functions for async_accept operation.
- template<typename T, /*typename Request, */typename Handler>
+ template<typename T, typename Handler>
      struct accept_handler
      {
        accept_handler(T& t, typename T::implementation_type& impl
@@ -297,17 +297,6 @@
        this->io_service().post(
          detail::accept_handler<type, Handler>(*this, impl, request, handler)
        );
- //boost::system::error_code ec;
- //handler(ec);
- //acceptor_service_.async_accept(impl.acceptor_, request.client().connection()->next_layer_type()
-
-/*
- &acceptor_service_impl<protocol_type>
- ::typename check_for_waiting_request<
- CommonGatewayRequest
- , Handler>,
- this, boost::ref(impl), boost::ref(request), handler));
-*/
      }
 
      /// Close the acceptor (not implemented yet).
@@ -329,18 +318,6 @@
                                    , 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
- }
- }
- */
-
        // We can't call accept on an open request (close it first).
        if (request.is_open())
          return handler(error::accepting_on_an_open_request);

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/client.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/client.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/client.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -14,7 +14,7 @@
 #include <boost/logic/tribool.hpp>
 #include <boost/asio/buffer.hpp>
 #include "boost/cgi/tags.hpp"
-#include "boost/cgi/map.hpp"
+#include "boost/cgi/common/map.hpp"
 #include "boost/cgi/io_service.hpp"
 #include "boost/cgi/basic_client.hpp"
 #include "boost/cgi/connections/shareable_tcp_socket.hpp"
@@ -254,10 +254,13 @@
       return keep_connection_;
     }
 
+ //int id() { return request_id_; }
+
   public:
     friend class fcgi_request_service;
     boost::uint16_t request_id_;
     client_status status_;
+ std::size_t bytes_left_;
     //request_impl_type* current_request_;
     
     /// A marker to say if the final STDIN (and/or DATA) packets have been

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/request_service.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/request_service.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/fcgi/request_service.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -10,40 +10,65 @@
 #define CGI_FCGI_REQUEST_SERVICE_HPP_INCLUDED__
 
 #include <boost/system/error_code.hpp>
-
-//#include "boost/cgi/scgi/request_impl.hpp"
-#include "boost/cgi/map.hpp"
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/support.hpp>
+////////////////////////////////////////////////////////////////
+#include "boost/cgi/common/map.hpp"
+#include "boost/cgi/common/request_base.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/detail/throw_error.hpp"
 #include "boost/cgi/detail/service_base.hpp"
-#include "boost/cgi/detail/extract_params.hpp"
-//#include "boost/cgi/basic_request.hpp"
 #include "boost/cgi/fcgi/client.hpp"
+#include "boost/cgi/common/form_parser.hpp"
 
 namespace cgi {
- namespace fcgi {
 
+ namespace detail {
+
+ template<typename T, typename Handler>
+ struct async_load_helper
+ {
+ async_load_helper(T& t, typename T::implementation_type& impl
+ , bool parse_stdin, Handler h)
+ : type(t)
+ , impl_(impl)
+ , parse_stdin_(parse_stdin)
+ , handler_(h)
+ {
+ }
+
+ void operator()()
+ {
+ boost::system::error_code ec;
+ type.load(impl_, parse_stdin_, ec);
+ handler_(ec);
+ }
+
+ T& type;
+ typename T::implementation_type& impl_;
+ bool parse_stdin_;
+ Handler handler_;
+ };
+ }
+
+ namespace fcgi {
+
   /// The IoObjectService class for a FCGI basic_request<>s
   class fcgi_request_service
     : public detail::service_base<fcgi_request_service>
+ , public common::request_base<fcgi_request_service>
   {
   public:
     /// The actual implementation date for an FCGI request.
     struct implementation_type
+ : common::request_base<fcgi_request_service>::impl_base
     {
- typedef ::cgi::common::map map_type;
- //typedef shareable_tcp_connection connection_type;
       typedef ::cgi::fcgi_ protocol_type;
- //typedef basic_client<
- // connection_type, protocol_type
- //> client_type;
       typedef ::cgi::fcgi::client client_type;
       typedef client_type::connection_type connection_type;
- typedef std::vector<char> buffer_type;
- typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
       typedef client_type::header_buffer_type header_buffer_type;
       typedef detail::protocol_traits<
         protocol_type
@@ -71,14 +96,6 @@
       status_type request_status_;
       fcgi::spec_detail::role_t request_role_;
 
- buffer_type buffer_;
-
- map_type env_vars_;
- map_type get_vars_;
- map_type post_vars_;
- map_type cookie_vars_;
-
- std::string null_str_;
       bool all_done_;
 
       mutable_buffers_type prepare(std::size_t size)
@@ -93,18 +110,6 @@
         //{
           buffer_.resize(bufsz + size);
         //}
- /*
- cerr<< "Pre-read buffer (size: " << buffer_.size()
- << "|capacity: " << buffer_.capacity() << ") == {" << endl
- << std::string(buffer_.begin(), buffer_.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(&buffer_[bufsz], size);
       }
 
@@ -112,12 +117,14 @@
      /************** New stuff *****************/
       header_buffer_type header_buf_;
       boost::uint16_t id_;
- };
+ typedef detail::form_parser<implementation_type> form_parser_type;
+
+ boost::scoped_ptr<form_parser_type> fp_;
+ };
 
     typedef fcgi_request_service type;
     typedef ::cgi::fcgi::fcgi_request_service full_type;
     typedef type::implementation_type::protocol_type protocol_type;
- typedef type::implementation_type::map_type map_type;
     typedef type::implementation_type::request_type request_type;
 
     fcgi_request_service(::cgi::io_service& ios)
@@ -131,11 +138,9 @@
 
     void construct(implementation_type& impl)
     {
- //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)
@@ -186,10 +191,10 @@
       );
                 
       impl.buffer_.clear();
- impl.get_vars_.clear();
- impl.post_vars_.clear();
- impl.cookie_vars_.clear();
- impl.env_vars_.clear();
+ impl.get_vars().clear();
+ impl.post_vars().clear();
+ impl.cookie_vars().clear();
+ impl.env_vars().clear();
       impl.stdin_parsed_ = false;
       impl.http_status_ = http::no_content;
       impl.request_status_ = null;
@@ -215,7 +220,6 @@
           , boost::system::error_code& ec)
     {
       //int header_len( get_length_of_header(impl, ec) );
- //std::cerr<< "Loading request...";
       BOOST_ASSERT(!ec && "Can't load request due to previous errors.");
 
       impl.client_.construct(impl, ec);
@@ -264,103 +268,23 @@
       if (request_method == "GET")
         if (parse_get_vars(impl, ec))
           return ec;
-/** FIXME **
       else
       if (request_method == "POST" && parse_stdin)
         if (parse_post_vars(impl, ec))
               return ec;
-*/
+
       parse_cookie_vars(impl, ec);
 
- //std::cerr<< "done!" << std::endl;
       return ec;
     }
 
- /* These Don't Belong Here.
- 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;
- }
-
- 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);
- }
-
- //template<typename VarType> map_type& var(implementation_type&) const;
- ********************************************/
-
- std::string GET(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
- {
- return var(impl.get_vars_, name, ec);
- }
-
- map_type& GET(implementation_type& impl)
- {
- return impl.get_vars_;
- }
-
- /// Find the post meta-variable matching name
- /**
- * @param greedy This determines whether more data can be read to find
- * the variable. The default is true to cause least surprise in the common
- * case of having not parsed any of the POST data.
-
- -----------------------------------------------
- Should this return a pair of iterators instead?
- What about url_decoding?
- -----------------------------------------------
-
- */
- 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)
- {
-
- }
-
- return val;
- }
-
- map_type& POST(implementation_type& impl)
- {
- return impl.post_vars_;
- }
-
-
- /// Find the cookie meta-variable matching name
- std::string cookie(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
- {
- return var(impl.cookie_vars_, name, ec);
- }
-
- map_type& cookie(implementation_type& impl)
- {
- return impl.cookie_vars_;
- }
-
- /// Find the environment meta-variable matching name
- std::string env(implementation_type& impl, const std::string& name
- , boost::system::error_code& ec)
- {
- return var(impl.env_vars_, name, ec);
- }
-
- map_type& env(implementation_type& impl)
+ // **FIXME**
+ template<typename Handler>
+ void async_load(implementation_type& impl, bool parse_stdin, Handler handler)
     {
- return impl.env_vars_;
+ this->io_service().post(
+ detail::async_load_helper<type, Handler>(this, parse_stdin, handler)
+ );
     }
 
     role_type get_role(implementation_type& impl)
@@ -375,70 +299,22 @@
     }
 
   protected:
- /// Extract the var value from
- std::string var(map_type& _data, const std::string& _name
- , boost::system::error_code& ec)
- {
- /* Alt:
- if ((typename map_type::iterator pos = meta_data.find(name))
- != meta_data.end())
- {
- return *pos;
- }
- return std::string();
- **/
-
- if( _data.find(_name) != _data.end() )
- return _data[_name];
- return "";
- }
-
- /// Read and parse the cgi GET meta variables
- boost::system::error_code&
- parse_get_vars(implementation_type& impl, boost::system::error_code& ec)
- {
- detail::extract_params(env(impl, "QUERY_STRING", ec)
- , impl.get_vars_
- , boost::char_separator<char>
- ("", "=&", boost::keep_empty_tokens)
- , ec);
-
- return ec;
- }
-
- /// Read and parse the HTTP_COOKIE meta variable
- boost::system::error_code&
- parse_cookie_vars(implementation_type& impl, boost::system::error_code& ec)
- {
- // Make sure this function hasn't already been called
- //BOOST_ASSERT( impl.cookie_vars_.empty() );
-
- std::string vars = env(impl, "HTTP_COOKIE", ec);
- if (vars.empty())
- return ec;
-
- detail::extract_params(env(impl, "HTTP_COOKIE", ec)
- , impl.cookie_vars_
- , boost::char_separator<char>
- ("", "=&", boost::keep_empty_tokens)
- , ec);
-
- return ec;
- }
-
     /// Read and parse the cgi POST meta variables (greedily)
- template<typename RequestImpl>
     boost::system::error_code&
     parse_post_vars(implementation_type& impl, boost::system::error_code& ec)
     {
       // Make sure this function hasn't already been called
- //BOOST_ASSERT( impl.post_vars_.empty() );
+ //BOOST_ASSERT( impl.post_vars().empty() );
           
       //# error "Not implemented"
-
- if (impl.stdin_parsed_)
- {
- }
+/*
+ impl.fp_.reset
+ (
+ new typename implementation_type::form_parser_type
+ ( impl )
+ );
+ impl.fp_->parse(ec);
+*/
 
       return ec;
     }
@@ -509,15 +385,15 @@
     // **FIXME**
     void handle_admin_request(implementation_type& impl)
     {
- std::cerr<< std::endl << "**FIXME** " << __FILE__ << ":" << __LINE__
- << " handle_admin_request()" << std::endl;
+ //std::cerr<< std::endl << "**FIXME** " << __FILE__ << ":" << __LINE__
+ // << " handle_admin_request()" << std::endl;
     }
 
     // **FIXME**
     void handle_other_request_header(implementation_type& impl)
     {
- std::cerr<< std::endl << "**FIXME** " << __FILE__ << ":" << __LINE__
- << " handle_other_request_header()" << std::endl;
+ //std::cerr<< std::endl << "**FIXME** " << __FILE__ << ":" << __LINE__
+ // << " handle_other_request_header()" << std::endl;
     }
 
     // **FIXME**
@@ -537,8 +413,8 @@
         return ec;
       }
       try {
- std::cerr<< "**FIXME** request aborted (id = " << id
- << ") but request not notified." << std::endl;
+ //std::cerr<< "**FIXME** request aborted (id = " << id
+ // << ") but request not notified." << std::endl;
         //impl.client_.connection_->requests_.at(id - 1)->abort();
       }catch(...){
         ec = error::abort_request_record_recieved_for_invalid_request;
@@ -612,7 +488,8 @@
         //std::cerr<< "[hw] name := " << name << std::endl;
         //std::cerr<< "[hw] data := " << data << std::endl;
 
- impl.env_vars_[name] = data;
+ // **FIXME**
+ impl.env_vars()[name.c_str()] = data;
       }
 
       return ec;
@@ -687,13 +564,10 @@
       }else
       if (!state)
       { // The header is confusing; something's wrong. Abort.
- std::cerr<< "Bad header received (this isn't implemented properly yet"
- << std::endl;
         return error::bad_header_type;
       }
       // else route (ie. state == boost::indeterminate)
 
- //std::cerr<< "Got to read more stuff now I think." << std::endl;
       implementation_type::mutable_buffers_type buf
         = impl.prepare(fcgi::spec::get_length(impl.header_buf_));
 
@@ -724,62 +598,41 @@
       parse_body(implementation_type& impl, const MutableBuffersType& buffer
                 , boost::system::error_code& ec)
     {
- return //ec;/*
+ return
         (this->* proc_funcs[fcgi::spec::get_type(impl.header_buf_)])
             (impl, fcgi::spec::get_request_id(impl.header_buf_)
             , boost::asio::buffer_cast<unsigned char*>(buffer)
             , boost::asio::buffer_size(buffer), ec);
     }
 
-/*
- implementation_type::request_type&
- get_or_make_request(implementation_type& impl, boost::uint16_t id);
 
- request_type::pointer ret
-
- try {
- ret = &requests.at(id - 1);
- BOOST_ASSERT(req != 0); // should throw
- return *ret;
- }catch(...){
- req = request_type::create(impl.service_);
- if (requests.size() < (id - 1))
- requests.resize(id);
- requests.at(id-1) = *req;
- return req->impl(); // same as *ret
- }
- }
-*/
- boost::system::error_code
- begin_request_helper(implementation_type& impl
- , implementation_type::header_buffer_type& header
- , boost::system::error_code& ec)
- {
- impl.client_.request_id_ = fcgi::spec::get_request_id(header);
+ boost::system::error_code
+ begin_request_helper(implementation_type& impl
+ , implementation_type::header_buffer_type& header
+ , boost::system::error_code& ec)
+ {
+ impl.client_.request_id_ = fcgi::spec::get_request_id(header);
 
         BOOST_STATIC_ASSERT((
- fcgi::spec::begin_request::body::size::value
- == fcgi::spec::header_length::value));
+ fcgi::spec::begin_request::body::size::value
+ == fcgi::spec::header_length::value));
+
+ // A begin request body is as long as a header, so we can optimise:
+ if (read_header(impl, ec))
+ return ec;
         
- // A begin request body is as long as a header, so we can optimise:
- if (read_header(impl, ec))
- return ec;
-
- impl.request_role_
- = fcgi::spec::begin_request::get_role(impl.header_buf_);
- // **FIXME** (rm impl.request_role_)
- impl.client_.role_ = impl.request_role_;
- //std::cerr<< "[hw] New request role: " << impl.request_role_
- // << " (" << fcgi::spec::role_type::to_string(impl.header_buf_) << ")"
- // << std::endl;
- impl.client_.keep_connection_
- = fcgi::spec::begin_request::get_flags(impl.header_buf_)
- & fcgi::spec::keep_connection;
-
- impl.client_.status_ = common::constructed;
- return ec;
- }
- };
+ impl.request_role_
+ = fcgi::spec::begin_request::get_role(impl.header_buf_);
+ // **FIXME** (rm impl.request_role_)
+ impl.client_.role_ = impl.request_role_;
+ impl.client_.keep_connection_
+ = fcgi::spec::begin_request::get_flags(impl.header_buf_)
+ & fcgi::spec::keep_connection;
+ impl.client_.status_ = common::constructed;
+
+ return ec;
+ }
+ };
 
   //template<>
   const fcgi_request_service::proc_func_t fcgi_request_service::proc_funcs[] =

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/io_service_provider.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/io_service_provider.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/io_service_provider.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -58,7 +58,7 @@
     {
     }
 
- ::cgi::io_service&
+ ::cgi::common::io_service&
       get_io_service()
     {
       return io_service_;
@@ -79,7 +79,7 @@
       io_service_.reset();
     }
   private:
- ::cgi::io_service io_service_;
+ ::cgi::common::io_service io_service_;
   };
 
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/map.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/map.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/map.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -9,15 +9,8 @@
 #ifndef CGI_MAP_HPP_INCLUDED__
 #define CGI_MAP_HPP_INCLUDED__
 
-#include <map>
-#include <string>
+#warning This file is deprecated, use common/map.hpp instead.
 
-namespace cgi {
- namespace common {
-
- typedef std::map<std::string,std::string> map;
-
- } // namespace common
-} // namespace cgi
+#include "boost/cgi/common/map.hpp"
 
 #endif // CGI_MAP_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/request_ostream.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/request_ostream.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/request_ostream.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -9,6 +9,11 @@
 #ifndef CGI_REQUEST_OSTREAM_HPP_INCLUDED__
 #define CGI_REQUEST_OSTREAM_HPP_INCLUDED__
 
+#if 0
+
+// THIS FILE ISN'T USED!
+// **FIXME**
+
 /*********************************
 ISSUES:
 -------
@@ -358,4 +363,6 @@
 
 #include "boost/cgi/detail/pop_options.hpp"
 
+#endif
+
 #endif // CGI_REQUEST_OSTREAM_HPP_INCLUDED__

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/response.hpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/response.hpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/boost/cgi/response.hpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -95,6 +95,7 @@
       ostream_.clear();
       headers_.clear();
       headers_terminated_ = false;
+ //buffer_->consume(
     }
 
     /// Return the response to the 'just constructed' state.

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -11,32 +11,35 @@
 import doxygen ;
 
 # compile the doxygen sources here
-#doxygen cgi_dox
-# :
+doxygen cgi_dox
+ :
 # [ glob-tree ../../../boost/cgi/*.hpp : .svn ]
 # [ glob-tree ../../../boost/libs/cgi/src/*.cpp : .svn ]
 
-# [ glob ../../../boost/cgi/*.hpp ]
+ [ glob ../../../boost/cgi/*.hpp ]
+ [ glob ../../../boost/cgi/fcgi*.hpp ]
+ [ glob ../../../boost/cgi/acgi*.hpp ]
+ [ glob ../../../boost/cgi/cgi*.hpp ]
 # [ glob ../../../boost/cgi/gateway_impl/*.hpp ]
 # [ glob ../../../boost/cgi/gateway_service/*.hpp ]
-# [ glob ../../../boost/cgi/http/*.hpp ]
+ [ glob ../../../boost/cgi/http/*.hpp ]
 # [ glob ../../../boost/cgi/connections/*.hpp ]
 # [ glob ../../../boost/cgi/request_impl/*.hpp ]
 # [ glob ../../../boost/cgi/request_service/*.hpp ]
-# :
+ :
 # <doxygen:param>HIDE_UNDOC_MEMBERS=NO
-# <doxygen:param>EXTRACT_PRIVATE=NO
+ <doxygen:param>EXTRACT_PRIVATE=NO
 # #<doxygen:param>EXTRACT_ALL=YES
-# <doxygen:param>SEARCH_INCLUDES=YES
+ <doxygen:param>SEARCH_INCLUDES=YES
 # <doxygen:param>INCLUDE_PATH=$(BOOST_ROOT)
-# ;
+ ;
 
 xml cgi_xml : src/cgi.qbk ;
 
 boostbook standalone
   :
     cgi_xml
-# cgi_dox
+ cgi_dox
   :
     <doxygen.processor>doxproc
     <doxygen.doxproc.index>no
@@ -49,7 +52,7 @@
     # the depth (of sub-pages) the TOC shows
     <xsl:param>toc.max.depth=1
     # Path to the stylesheet
- <xsl:param>html.stylesheet=../../../../../../../../boost/trunk/doc/html/boostbook.css
+ <xsl:param>html.stylesheet=../../../../../../boost/trunk/doc/html/boostbook.css
  
     #
     <xsl:param>toc.section.depth=2

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/acknowledgements.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/acknowledgements.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/acknowledgements.qbk 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -7,14 +7,39 @@
 
 [section Acknowledgements]
 
-Provided courtesy of the Google Summer of Code (GSoC '08)!
+The library in its current form was started as part of the Google Summer of Code (GSoC '07) - in my case a union of [@http://code.google.com/soc Google] collaborating with [@http://boost.org Boost]!
 
-Christopher Kohlhoff: for crafting Boost.Asio, which does most of the hard stuff. Chris mentored me through the GSoC (no mean feat!), without which this library would not be in your hands.
+People involved in the development of this library:
 
-Phil Endecott: for offering use-cases and encouragement at the start of the GSoC and for coming up with many further suggestions (such as the Client concept) in the months since.
+* [*Christopher Kohlhoff]: for crafting __asio__, which does most of the hard stuff. Chris mentored me through the GSoC (no mean feat!), without which this library would be neither in your hands, nor modelled the way it is.
 
-The Boost mailing lists: for so many deeply critical and objective comments about the library. :) That, is a relentless and ['Good Thing].
+* [*Phil Endecott]: for offering use-cases and encouragement at the start of the GSoC and for coming up with many further suggestions (such as the Client concept) in the months since.
 
-[-forgetting everyone's names:] Jeff Dunlap
+* [*Peter Simons]: His FastCGI library [@http://cryp.to/libfastcgi libfastcgi] provided initial motivation for this library. Also his article [@http://cryp.to/publications/fastcgi/ "FastCGI - The Forgotten Treasure"] is an good read for those not sold on FastCGI.
+
+Also many thanks to:
+
+* [*Jeff Dunlap]: for help with testing and for pushing the idea of supporting HTML templates. Jeff provided an online version of the amortization example which I aimed to replicate using this library and Google.cTemplate.
+
+* [*Jeff Garland]: for organising access to Boost's SVN repo, being involved in early discussion and probably being involved in my SoC application having any chance. :)
+
+* [*Christian Henning]: for help testing early code.
+
+The [*Boost mailing lists]: for so many helpful and objective comments about the library.
+
+Discussions on the Boost lists included:
+
+* *Martin Wille*
+* *Mathias Gaunard*
+* *Peter Foley*
+* *'Jose'*
+* *'Shams'*
+* *Peter Dimov*
+* *Simon Richter*
+* *Cris Frey*
+* *Sohail Somani*
+* *Jean-Christophe Roux*
+
+[-forgetting everyone's names:] Apologies to anyone missed... tell me, please!
 
 [endsect]

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/cgi.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/cgi.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/cgi.qbk 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -40,10 +40,10 @@
 [def __tutorial__ [link boost.cgi.tutorial tutorial]]
 [def __reference__ [link /doc/html/cgi/reference.html reference]]
 
-[def __current_branch__ http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/acceptor_work]
+[def __current_branch__ http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/release]
 
-[def __examples__ [@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example examples]]
-[def __amort_example__ [@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization Amortization]]
+[def __examples__ [@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/release/libs/cgi/example examples]]
+[def __amort_example__ [@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/cgi/branches/release/libs/cgi/example/acgi/amortization Amortization]]
 
 
 [def __GET__ `GET` ]
@@ -52,7 +52,7 @@
 [def __PUT__ `PUT` ]
 
 
-[def __Service__ [@http://asio.sourceforge.net/boost_asio_0_3_8/libs/asio/doc/html/boost_asio/reference/Service.html Service]]
+[def __Service__ [@http://asio.sourceforge.net/boost_asio_0_3_9/libs/asio/doc/html/boost_asio/reference/Service.html Service]]
 
 [/def __boost_thread__ #link#to#boost#thread#docs#]
 [/def __IoService__ #link#to#io#service#docs#]
@@ -117,4 +117,4 @@
 
 [include:server_support user_guide/server_support.qbk]
 
-[/include acknowledgements.qbk]
+[include acknowledgements.qbk]

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/future_development.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/future_development.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/future_development.qbk 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -13,13 +13,13 @@
 
 [h4 SCGI support.]
 
-Due to configuration issues, this isn't functional yet.
+I haven't managed to get apache/lighttpd configured properly for SCGI, so this isn't functional yet.
 
 [h4 FastCGI support.]
 
 FastCGI support is essential to any modern CGI library. There is currently ['no] known FastCGI library for C or C++ that aims to implement the complete [@http://www.fastcgi.com/devkit/doc/fcgi-spec.html FastCGI 1.0] specification. Providing support for multiplexing FastCGI daemons is one of this library's major goals.
 
-There are a couple of issues that have yet to be worked out, but in general the new framework is known to 'fit' with all the details of FastCGI and should lend itself to an efficient implementation. It's only partially working at the moment.
+There are a couple of issues that have yet to be worked out, but FastCGI is working in a basic way now.
 
 [h4 Access to error output streams]
 
@@ -106,32 +106,14 @@
 
 [h4 Support for environment Passed on Command Line]
 
-See section 4.4 of [@http://www.ietf.org/rfc/rfc3875].
+See section 4.4 of [@http://www.ietf.org/rfc/rfc3875]. Should be easy to do by modifying the `acgi::service` class.
 
 [h4 Support for Multi-part POST Forms]
 
-
-
-[h4 `operator[]` Overloading]
-
-What is currently:
-``
-request req;
-std::string a( req.form_("a") );
-map& forms = req.form_();
-``
-could become:
-``
-request req;
-std::string a(req[form_, "a"]);
-map& forms = req[form_];
-a = req[form_]["a"]; // better to the above, plus is more 'standard'
-``
+This has been added to the CGI part of the library, but it's very ugly and hackish. The idea is to create a `form_parser` class that can be used both internally and externally to parse multipart forms.
 
 [/h4 Removing aCGI/CGI Divide]
 
-[/h4 Support for wide characters]
-
-[/The library generally works on octets, but there should be some way to ]
+[/h4 Unicode Support]
 
 [endsect]

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/introduction.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/introduction.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/introduction.qbk 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -22,11 +22,15 @@
 
   return_(req, resp, 0); // write the response and 'return 0;'
 }
+``
 
 Example request:
+``
 example.com/program_name?name=Mr.+Allison
+``
 
-Output:
+Output (as viewed in a web browser):
+``
 Hello there, Universe. -- Mr. Allison
 
 ``
@@ -39,7 +43,7 @@
 
 [h4 Concepts]
 
-The library provides abstractions which hide details of the vastly different specifications of CGI, FastCGI and SCGI. The main abstractions are, briefly:
+The library provides abstractions which hide details of the varying specifications of CGI, FastCGI and SCGI. The main abstractions are, briefly:
 
 [table
 [
@@ -72,17 +76,23 @@
 
 [h4 Protcols]
 
-[:['See __protocol_details__ for more.]]
+[:['See __protocol_details__ for more.]] [/ **FIXME** ]
 
-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].
+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 ['dynamic web pages].
 
-FastCGI was then developed as a means of allowing much more scalable CGI-like programs to be written. In fact, the FastCGI specification implies scalability was the main motivation for the protocol. Communication with the server 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 all incoming requests concurrently.
+[tip If you're new to CGI, have a look at this: [@http://hoohoo.ncsa.uiuc.edu/cgi/]]
+
+__FastCGI__ was then developed as a means of allowing much more scalable CGI-like programs to be written. In fact, the FastCGI specification implies scalability was the main motivation for the protocol. Communication with the server 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 all incoming requests concurrently.
+
+[note
+ Some initial benchmarks show that simple FastCGI programs are 3-5x faster than their CGI counterparts. When using database connections and/or HTML templates, the gap should get even bigger.
+]
 
-SCGI is essentially a simpler version - hence [*S]imple[*CGI] - of FastCGI but is still a significant step up from vanilla CGI, mainly because 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 and/or you may not have that option.
+__SCGI__ is essentially a simpler version of FastCGI - hence [*S]imple[*CGI] - but is still a significant step up from vanilla CGI, mainly because 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 and/or you may not have that option. [/ **FIXME**] SCGI support isn't included yet.
 
 [h4 Multiple Requests per Process]
 
-So I keep harping on about this, that's because it removes so many limitations of traditional CGI programming. Your programs can become servers, capable of handling an arbitrary number of requests with 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.
+Having persistent processes is very handy. It removes so many of the limitations of traditional CGI programming; suddenly CGI programs aren't so different to desktop applications. CGI 'scripts' become FastCGI servers, capable of handling an arbitrary number of requests with 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.
 
 The downside is added complexity: managing multiple requests and having to keep a tight reign on memory/resource consumption.
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/preface.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/preface.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/preface.qbk 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -23,7 +23,7 @@
 
 [h3 Motivation]
 
-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.
+C++ may not be the most common language used for CGI programming, but it is a powerful one that can be used to produce scalable, maintainable and uncompromisingly efficient applications.
 
 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:
 
@@ -33,7 +33,7 @@
 
 * Millions of lines of C++ code can be reused to reduce development/testing times.
 
-* 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.
+* 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.
 
 * C++ is ['fast]. You can rest assured that the language will never be a bottleneck for your applications.
 
@@ -45,23 +45,47 @@
 
 The generally poor support for CGI programming for C++ - most libraries are either unmaintained, or don't take advantage of modern C++ capabilities - has driven the development of this library. [-moremoremore]
 
-[h3 How to use this manual]
+[section:using 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 (['since this [*is not] a Boost library]) 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 half-intentional (['since this [*is not] a Boost library]). It's 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.
-
 [h4 Naming Conventions]
 
+[h5 Headers]
+
+[table What Headers to Include
+ [[Protocol] [`#include` line]]
+ [[All] [`#include <boost/cgi.hpp>`]]
+ [[CGI] [`#include <boost/cgi/cgi.hpp>`]]
+ [[aCGI] [`#include <boost/cgi/acgi.hpp>`]]
+ [[FastCGI] [`#include <boost/cgi/fcgi.hpp>`]]
+]
+
+[h5 Namespaces]
+
+The classes/functions that are shared between protocols are in the `cgi::common` namespace. Using the above headers dumps these into the relevant namespace.
+
+[table
+ [[Protocol] [`namespace`]]
+ [[CGI] [`namespace boost::cgi`
+ `namespace cgi::cgi`]]
+ [[aCGI] [`namespace boost::acgi`
+ `namespace cgi::acgi`]]
+ [[FastCGI] [`namespace boost::fcgi`
+ `namespace cgi::fcgi`]]
+]
+
 [h5 Macros]
 
 Macros are prefixed with `BOOST_CGI_*` .
 
+[/ **FIXME**] There aren't any tested public macros yet, when there are they will be listed here.
+
 [h5 Code snippets]
 
-As you are probably used to, it is assumed that code snippets in this manual have the correct `#include`s and "`using namespace cgi;`" prepended to them. Information about the correct headers to include can be found [link __headers__ here].
+As you are probably used to, it is assumed that code snippets in this manual have the correct `#include`s and "`using namespace boost::<protocol>;`" prepended to them.
 
 [h3 Comments and Support]
 
@@ -71,4 +95,6 @@
 
 or thereabouts.
 
+[endsect][/ using]
+
 [endsect]

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/user_guide.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/user_guide.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/user_guide.qbk 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -13,15 +13,13 @@
 
 [include:server_config user_guide/server_configuration.qbk]
 
-[include:headers user_guide/headers.qbk]
-
 [endsect]
 
 [/include:protocols user_guide/protocols.qbk]
 
 [/include:tutorial user_guide/tutorial.qbk]
 
-[include:examples user_guide/examples.qbk]
+[include:examples ../../example/doc.qbk]
 
 [include user_guide/tutorial/tutorial.qbk]
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/user_guide/examples.qbk
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/user_guide/examples.qbk (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/doc/src/user_guide/examples.qbk 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -1,76 +1 @@
 
-[section Examples]
-
-[template example_link[protocol example_name link_text] [@../../example/\ [protocol]/[example_name]/main.cpp [link_text]]]
-
-The examples can be built by going into their directory and typing `bjam`. If you have a server set up and wish to test the applications behind them, you can automatically copy them to your server's cgi-bin (or fcgi-bin or scgi-bin) one of two ways:
-
-* `bjam install --cgi-bin=/usr/lib/cgi-bin` - installs the program (or set of programs) into `/usr/lib/cgi-bin` [*iff] they are a CGI program. If you want to install examples in the `/libs/cgi/example/fcgi/` directory, for instance, type the above but replace `--cgi-bin` to `--fcgi-bin`.
-
-* set the environment variable `BOOST_CGI_BIN_PATH` (or `BOOST_FCGI_BIN_PATH`/`BOOST_SCGI_BIN_PATH`) and just type `bjam install`. The example(s) will be installed into the relevant directory.
-
-[note
- The command line option will override the environment variable, so you can use the environment variables for default installation.
-]
-
-[section aCGI]
-
-[import ../../../example/cgi/echo/main.cpp]
-
-Linky: [example_link acgi..echo..aCGI Echo example]
-
-[@../../../example/cgi/echo/main.cpp]
-
-[file]
-
-[endsect] [/ acgi]
-
-[section CGI]
-
-[endsect] [/ cgi]
-
-[section FastCGI]
-
-[def __fcgi_hello_world__ ../../../example/fcgi/hello_world/main.cpp]
-[def __fcgi_echo__ ../../../example/fcgi/echo/main.cpp]
-
-[section "Hello, world."]
-
-[import ../../../example/fcgi/hello_world/main.cpp]
-
-Click to see the [link __fcgi_hello_world__ source file]
-
-[file]
-
-[endsect] [/ hello_world]
-
-[section Echo]
-
-[/import __fcgi_echo__]
-
-[template call_import[protocol_t example_name]
-[import ../../example/\ [protocol_t]/[name]/main.cpp]
-]
-
-[call_import fcgi..amortization]
-
-[template import_example[protocol name]
-
-[import ../../example/[protocol]/[name]/main.cpp]
-
-Click to see the [@../../../example/[protocol]/[name]/main.cpp source file].
-
-]
-
-[import_example fcgi..echo]
-
-Click to see the [/example_link[fcgi..echo..source file]].
-
-[fcgi_echo]
-
-[endsect] [/ echo]
-
-[endsect] [/ fastcgi]
-
-[endsect]
-

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -4,32 +4,45 @@
 # (See accompanying file LICENSE_1_0.txt or copy
 # at http://www.boost.org/LICENSE_1_0.txt)
 
-project boost.cgi.examples
- : requirements
+project boost/cgi/example
+: requirements
       <library>/boost/system/
       <library>/boost/thread/
   ;
 
-# Install all of the acgi examples
-install acgi
+# Build all of the cgi examples
+build-project cgi ;
+# Build all of the acgi examples
+build-project acgi ;
+# Build all of the fcgi examples
+build-project fcgi ;
+
+install cgi-install
+ : # sources
+ cgi//install
+ :
+ <location>$(cgi-bin)
+ ;
+
+install acgi-install
  : # sources
    acgi//install
  :
    <location>$(cgi-bin)
  ;
 
-explicit acgi ;
+install fcgi-install
+ :
+ fcgi//install
+ :
+ <location>$(fcgi-bin)
+ ;
+
+alias install : cgi//install acgi//install fcgi//install ;
+
+explicit cgi-install ;
+explicit acgi-install ;
+explicit fcgi-install ;
+
+explicit install ;
 
-#install examples
-# : # the sources
-# ecgi
-# acgi
-# #reply
-# : <location>/var/www/cgi-bin
-# ;
-
-#install scgi
-# : # the sources
-# scgi
-# : <location>/var/www/scgi-bin
-# ;

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -4,18 +4,25 @@
 # (See accompanying file LICENSE_1_0.txt or copy
 # at http://www.boost.org/LICENSE_1_0.txt)
 
-project boost.cgi.examples.acgi ;
+project boost/cgi/example/acgi ;
 
-# Install all acgi examples to the user-provided variable "cgi-bin"
+# By default, just build the examples
+build-project hello_world ;
+build-project echo ;
+build-project cookie_game ;
+build-project amortization ;
+
+# If the user explicitly passes "install" on the command line, build the
+# CGI examples and copy them to $(cgi-bin)
 install install
   :
     hello_world
     echo
     cookie_game
- login
+ amortization
   :
     <location>$(cgi-bin)
   ;
 
-# Only install example if you use `bjam install' or equivalent
 explicit install ;
+

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -5,7 +5,7 @@
 # at http://www.boost.org/LICENSE_1_0.txt)
 
 # A symbolic name for this project.
-project boost.cgi.examples.acgi.amortization ;
+project boost/cgi/example/acgi/amortization ;
 
 import os ;
 
@@ -30,7 +30,7 @@
   ;
 
 # Our install rule (builds binaries and copies them to <location>)
-install install
+install install-app
  :
    acgi_amort
    acgi_amort.tpl
@@ -48,5 +48,15 @@
    <location>$(htdocs)
  ;
 
+explicit install-app ;
+explicit install-extra ;
+
+install install
+ :
+ install-app
+ install-extra
+ ;
+
 # Only install example if you use `bjam install' or equivalent
 explicit install ;
+

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/amortization/main.cpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -7,6 +7,8 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[acgi_amort
+//
 // Amortization Calculator
 // -----------------------
 //
@@ -116,7 +118,8 @@
     // header - followed by a blank line - first though!).
     std::string output;
     tmpl->Expand(&output, &dict);
- std::cout<< output;
+ std::cout<< "Content-type: text/html\r\n\r\n"
+ << output;
   }else
   if (arg == "2")
   {
@@ -124,32 +127,37 @@
     // Should be expensive, but doesn't seem to impact performance hugely...
     std::string output;
     tmpl->Expand(&output, &dict);
- resp<< output;
+ resp<< content_type("text/html")
+ << output;
   }else
-// if (arg == "3")
-// {
-// // Expand the string to a vector<const_buffer>, which should minimise any
-// // copying of data. This requires a modified version of Google.cTemplate, but
-// // doesn't seem to add anything to performance. Will have to check if there's a
-// // better way to do it.
-// std::string s;
-// std::vector<boost::asio::const_buffer> out;
-//
-// tmpl->Expand(&s, &out, &dict);
-// write(req.client(), out);
-// }else
+ // if (arg == "3")
+ // {
+ // // Expand the string to a vector<const_buffer>, which should minimise any
+ // // copying of data. This requires a modified version of Google.cTemplate, but
+ // // doesn't seem to add anything to performance. Will have to check if there's a
+ // // better way to do it.
+ // std::string s;
+ // std::vector<boost::asio::const_buffer> out;
+ //
+ // tmpl->Expand(&s, &out, &dict);
+ // write(req.client(), out);
+ // }else
   if (arg == "4")
   {
     // Write the output directly to the request's client.
+ std::string headers("Content-type: text/html\r\n\r\n");
+ write(req.client(), buffer(headers));
     std::string output;
     tmpl->Expand(&output, &dict);
     write(req.client(), buffer(output));
   }else
- if (arg == "5")
+ if (arg == "5")
   {
     // An alternative to { arg == "1" }, which seems to be slightly faster.
     std::string output;
     tmpl->Expand(&output, &dict);
+ const char* headers = "Content-type: text/html\r\n\r\n";
+ std::cout.write(headers, strlen(headers));
     std::cout.write(output.c_str(), output.size());
   }else
   {
@@ -160,7 +168,6 @@
 int main()
 {
   try{
- std::cout<< "Content-type: text/html\r\n\r\n"; // just for debugging
     service s;
     request req(s);
     req.load(true);
@@ -174,4 +181,5 @@
       << "ERROR!! BOOM!";
   }
 }
+//]
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -4,15 +4,14 @@
 # (See accompanying file LICENSE_1_0.txt or copy
 # at http://www.boost.org/LICENSE_1_0.txt)
 
-project boost.cgi.examples.acgi.cookie_game
- ;
+project boost/cgi/example/acgi/cookie_game ;
 
-exe acgi : main.cpp ;
+exe acgi_cookie_game : main.cpp /boost/regex/ ;
 
 # Our install rule (builds binaries and copies them to <location>)
 install install
   :
- acgi
+ acgi_cookie_game
   :
     <location>$(cgi-bin)
   ;

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/cookie_game/main.cpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -1,6 +1,5 @@
 #include <boost/cgi/acgi.hpp>
 #include <boost/cgi/response.hpp>
-#include <iostream>
 
 #define SCRIPT_NAME "acgi_cookie_game"
 
@@ -60,7 +59,7 @@
   }
 
   // First, see if they have a cookie set
- std::string& name = req.cookie()["name"];
+ std::string name = req[cookie_data]["name"];
   if (!name.empty())
   {
     resp<< header("Content-type", "text/html")
@@ -71,7 +70,7 @@
   }
 
   // Now we'll check if they sent us a name in a form
- name = req.form("name");
+ name = req[form_data]["name"];
   if (!name.empty())
   {
     resp<< header("Content-type", "text/html")
@@ -88,11 +87,8 @@
       << "Hello there, Universe.<p />"
       << "What's your name?<br />";
 
- std::cerr<< std::endl << "name = " << req.POST("name") << std::endl;
- std::cerr.flush();
-
   resp<< "<form method='POST'>"
- "<input name='name' type='text' value='" << req.form("name") << "'>"
+ "<input name='name' type='text' value='" << req[form_data]["name"] << "'>"
          "</input>"
          "<input type='submit'></input>"
          "</form>"

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -4,17 +4,21 @@
 # (See accompanying file LICENSE_1_0.txt or copy
 # at http://www.boost.org/LICENSE_1_0.txt)
 
-exe acgi_form_test
- : main.cpp
+project boost/cgi/example/acgi/echo ;
+
+exe acgi_echo
+ :
+ main.cpp
     /boost/regex/
     /boost/thread/
   ;
 
 # Our install rule (builds binaries and copies them to <location>)
 install install
- : acgi_form_test
  :
- <location>$(cgi-bin)
+ acgi_echo
+ :
+ <location>$(cgi-bin)
  ;
 
 # Only install example if you use `bjam install' or equivalent

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/echo/main.cpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -7,6 +7,8 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[acgi_echo
+//
 // This example simply echoes all variables back to the user. ie.
 // the environment and the parsed GET, POST and cookie variables.
 // Note that GET and cookie variables come from the environment
@@ -15,19 +17,18 @@
 
 #include <boost/cgi/acgi.hpp>
 #include <fstream>
-//#include <google/template.h>
 
 using namespace std;
 using namespace boost::acgi;
 
 // This function writes the title and map contents to the ostream in an
 // HTML-encoded format (to make them easier on the eye).
-template<typename MapT, typename OStreamT>
-void show_map_contents(MapT& m, OStreamT& os, const std::string& title)
+template<typename OStreamT, typename MapT>
+void show_map_contents(OStreamT& os, MapT& m, const std::string& title)
 {
   os<< "<h3>" << title << "</h3>";
   if (m.empty()) os<< "NONE<br />";
- for (typename MapT::iterator i = m.begin(); i != m.end(); ++i)
+ for (typename MapT::const_iterator i = m.begin(); i != m.end(); ++i)
   {
     os<< "<b>" << i->first << "</b> = <i>" << i->second << "</i><br />";
   }
@@ -52,7 +53,7 @@
       {
         response resp;
         resp
- << content_type("text/plain")
+ << content_type("text/html")
         << "Error " << ec.value() << ": " << ec.message() << "<p />"
            "--Original message follows--"
            "<p />";
@@ -70,37 +71,45 @@
               "<input type=hidden name=cmd value=multipart_test />"
               "<br />"
               "<input type=submit value=submit />"
- "</form><p />"
- "boundary marker = " << req.boundary_marker() << "<p />";
+ "</form><p />";
 
- show_map_contents(req.GET(), resp, "GET Variables");
- show_map_contents(req.POST(), resp, "POST Variables");
- show_map_contents(req.cookie(), resp, "Cookie Variables");
- show_map_contents(req.env(), resp, "Environment Variables");
+ show_map_contents(resp, req[get_data], "GET Variables");
+ show_map_contents(resp, req[post_data], "POST Variables");
+ show_map_contents(resp, req[cookie_data], "Cookie Variables");
+ show_map_contents(resp, req[env_data], "Environment Variables");
 
- //resp<< content_type("text/html");
- resp.send(req.client());
+ return_(resp, req, 0); // All ok.
 
- }catch(boost::system::error_code& ec){
+ }
+ catch(boost::system::system_error& ec)
+ { // This is the type of error this library throws.
       response resp;
- resp<< content_type("text/plain") << "Error " << ec.value() << ": "
- << ec.message();
- }catch(std::exception& e){
+ resp<< content_type("text/plain") << "Error " << ec.code() << ": "
+ << ec.what()
+ << http::internal_server_error; // note the status_code
+ return_(resp, req, 1);
+ }
+ catch(std::exception* e)
+ {
       response resp;
- resp<< content_type("text/plain") << "Error: " << e.what();
+ resp<< content_type("text/plain") << "Error: " << e->what()
+ << http::internal_server_error;
       return_(resp, req, 2);
     }
 
+ // The request object will be destroyed before the next exception handlers
+ // are reached.
+
   }catch(std::exception* e){
- std::cout
+ std::cerr
     << content_type("text/plain").content
     << "Exception: " << e->what();
- //resp.send(req.client());
     return 3;
   }catch(...){
- std::cout<< content_type("text/plain").content
+ std::cerr<< content_type("text/plain").content
              << "Unknown error.";
     return 4;
   }
- return 0;
 }
+//]
+

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -4,8 +4,7 @@
 # (See accompanying file LICENSE_1_0.txt or copy
 # at http://www.boost.org/LICENSE_1_0.txt)
 
-project boost.cgi.examples.acgi.hello_world
- ;
+project boost/cgi/example/acgi/hello_world ;
 
 exe acgi_hello_world : main.cpp /boost/regex/ ;
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/acgi/hello_world/main.cpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -7,6 +7,8 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[acgi_hello_world
+//
 // The simplest CGI program, outputs only "Hello there, universe."
 //
 
@@ -30,3 +32,5 @@
   // Leave this function, after sending the response and closing the request.
   return_(resp, req, 0); // Note the underscore: returns "0" to the OS.
 }
+//]
+

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -4,35 +4,18 @@
 # (See accompanying file LICENSE_1_0.txt or copy
 # at http://www.boost.org/LICENSE_1_0.txt)
 
-import os ;
-
-project boost/cgi/example/cgi
- : build-dir ../../../../bin.v2
- ;
-
-local BOOST_ROOT = [ os.environ BOOST_ROOT ] ;
-
-
-exe ecgi
+# By default, just build the examples
+build-project hello_world ;
+build-project echo ;
+
+# If the user explicitly passes "install" on the command line, build the
+# CGI examples and copy them to $(cgi-bin)
+install install
   :
- main.cpp
+ hello_world
+ echo
   :
- <include>$(BOOST_ROOT)
- <include>../../../../
- <library>../../util/system//boost_system
- #<library>l:/usr/local/lib/libboost_system.a
- <define>BOOST_ALL_NO_LIB=1
- <define>_CRT_SECURE_NO_DEPRECATE=1
- <define>_SCL_SECURE_NO_WARNINGS
- <define>_CRT_SECURE_NO_WARNINGS
- <toolset>gcc:<linkflags>-lpthread
+ <location>$(cgi-bin)
   ;
 
-# uncomment this if you want to test the example on your machine
-#install _
-# : ecgi
-# : # this is where the compiled executable will be copied
-# # set this to your server's /cgi-bin/
-# <location>/var/www/cgi-bin
-# ;
-
+explicit install ;

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -4,25 +4,21 @@
 # (See accompanying file LICENSE_1_0.txt or copy
 # at http://www.boost.org/LICENSE_1_0.txt)
 
+project boost/cgi/example/cgi/echo ;
+
 exe cgi_echo
   : main.cpp
     /boost/thread/
     /boost/regex/
   ;
 
-local LOCATION = $(cgi-bin) ;
-if ! $(LOCATION)
-{
- LOCATION = . ;
-}
-
 
 # Our install rule (builds binaries and copies them to <location>)
 install install
- : cgi_echo
  :
+ cgi_echo
  :
- <location>$(LOCATION)
+ <location>$(cgi-bin)
  ;
 
 # Only install example if you use `bjam install' or equivalent

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/cgi/echo/main.cpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -7,43 +7,46 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[cgi_echo
+//
 // This example simply echoes all variables back to the user. ie.
 // the environment and the parsed GET, POST and cookie variables.
 // Note that GET and cookie variables come from the environment
 // variables QUERY_STRING and HTTP_COOKIE respectively.
 //
 
-//[file
 #include <boost/cgi/cgi.hpp>
 
-using namespace std;
 using namespace boost::cgi;
 
+//
 // This function writes the title and map contents to the ostream in an
 // HTML-encoded format (to make them easier on the eye).
-template<typename MapT, typename OStreamT>
-void show_map_contents(MapT& m, OStreamT& os, const std::string& title)
+//
+template<typename OStreamT, typename MapT>
+void show_map_contents(OStreamT& os, MapT& m, const std::string& title)
 {
   os<< "<h3>" << title << "</h3>";
- if (m.empty()) os<< "NONE<br />";
- for (typename MapT::iterator i = m.begin(); i != m.end(); ++i)
- {
- os<< "<b>" << i->first << "</b> = <i>" << i->second << "</i><br />";
- }
+
+ if (m.empty())
+ os<< "NONE<br />";
+ else
+ for (typename MapT::const_iterator i = m.begin(); i != m.end(); ++i)
+ os<< "<b>" << i->first << "</b> = <i>"
+ << i->second << "</i><br />";
 }
 
 int main()
 {
- request req;
-
- req.load(true); // The 'true' means parse STDIN data too.
-
+ request req; // A basic CGI request auto-parses everything (including POST data).
   response resp;
 
- show_map_contents(req.env(), resp, "Environment Variables");
- show_map_contents(req.GET(), resp, "GET Variables");
- show_map_contents(req.POST(), resp, "POST Variables");
- show_map_contents(req.cookie(), resp, "Cookie Variables");
+ resp<< "Request id = " << req.id() << "<p/>";
+
+ show_map_contents(resp, req[env_data], "Environment Variables");
+ show_map_contents(resp, req[get_data], "GET Variables");
+ show_map_contents(resp, req[post_data], "POST Variables");
+ show_map_contents(resp, req[cookie_data], "Cookie Variables");
 
   // Note that this (and any other) HTTP header can go either before or after
   // the response contents.

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/main.cpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -7,6 +7,8 @@
 //
 ////////////////////////////////////////////////////////////////
 //
+//[fcgi_amort
+//
 // Amortization Calculator
 // -----------------------
 //
@@ -185,7 +187,8 @@
   try{
 
     service s;
- acceptor a(s, true);
+ acceptor a(s, true); // The true means default-initialise.
+ // Unfortunately this only works on linux w. apache for now.
 
     accept_requests(a);
     
@@ -199,4 +202,5 @@
     std::cerr<< "ERROR!! BOOM!" << std::endl;
   }
 }
+//]
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -1,5 +1,5 @@
 
-project cgi.examples.fcgi.echo ;
+project boost/cgi/example/fcgi/echo ;
 
 exe fcgi_echo : main.cpp ;
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/main.cpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -27,10 +27,12 @@
 // This is a file to put internal logging info into
 #define LOG_FILE "/var/www/log/fcgi_echo.txt"
 
+//
 // This function writes the title and map contents to the ostream in an
 // HTML-encoded format (to make them easier on the eye).
+//
 template<typename Map, typename OStream>
-void format_map(Map& m, OStream& os, const std::string& title)
+void format_map(OStream& os, Map& m, const std::string& title)
 {
   os<< "<h2>" << title << "</h2>";
   if (m.empty()) os<< "NONE<br />";
@@ -42,45 +44,63 @@
 }
 
 /// This function accepts and handles a single request.
-template<typename Service, typename Acceptor, typename LogStream>
-int handle_request(Service& s, Acceptor& a, LogStream& of)
+template<typename Request, typename LogStream>
+int handle_request(Request& req, LogStream& of)
 {
- // First we construct a `request` object.
- request req(s); // This is in a protocol-specific state at the moment.
-
- of<< "Constructed request" << endl;
   boost::system::error_code ec;
   
- // The program blocks here until a request arrives.
- a.accept(req, ec);
-
   of<< "Called accept" << endl;
   // Result should be "Success".
   of<< "Accept had result: " << ec.message() << endl;
 
+ //
   // Load in the request data so we can access it easily.
+ //
   req.load(ec, true); // The 'true' means read and parse STDIN (ie. POST) data.
 
+ //
   // Construct a `response` object (makes writing/sending responses easier).
+ //
   response resp;
 
+ //
   // Responses in CGI programs require at least a 'Content-type' header. The
   // library provides helpers for several common headers:
+ //
   resp<< content_type("text/html")
   // You can also stream text to a response object.
- << "Hello there, universe!<p />";
+ << "Hello there, universe!<p />"
+ << "Request id = " << req.id() << "<p />"
+ << "<form method=POST enctype='multipart/form-data'>"
+ "<input type=text name=name value='" << req.POST("name") << "' />"
+ "<br />"
+ "<input type=text name=hello value='" << req.POST("hello") << "' />"
+ "<br />"
+ "<input type=file name=user_file />"
+ "<input type=hidden name=cmd value=multipart_test />"
+ "<br />"
+ "<input type=submit value=submit />"
+ "</form><p />";
 
+ //
   // Use the function defined above to show some of the request data.
- format_map(req.env(), resp, "Environment Variables");
- format_map(req.GET(), resp, "GET Variables");
- format_map(req.cookie(), resp, "Cookie Variables");
+ //
+ format_map(resp, req[env_data], "Environment Variables");
+ format_map(resp, req[get_data], "GET Variables");
+ format_map(resp, req[post_data], "POST Variables");
+ format_map(resp, req[cookie_data], "Cookie Variables");
 
+ //
   // Response headers can be added at any time before send/flushing it:
+ //
   resp<< "<content-length == " << content_length(resp.content_length())
- << content_length(resp.content_length());
+ << content_length(resp.content_length()) << ">";
 
+ //
+ //
   // This funky macro finishes up:
   return_(resp, req, 0);
+ //
   // It is equivalent to the below, where the third argument is represented by
   // `program_status`:
   //
@@ -89,6 +109,7 @@
   // return program_status;
   //
   // Note: in this case `program_status == 0`.
+ //
 }
 
 int main()
@@ -110,15 +131,27 @@
   // Make an `acceptor` for accepting requests through.
   acceptor a(s);
 
+ //
   // After the initial setup, we can enter a loop to handle one request at a
   // time until there's an error of some sort.
+ //
   int ret(0);
   for (;;)
   {
- ret = handle_request(s, a, of);
- of<< "handle_request() returned: " << ret << endl;
- if (ret)
- break;
+ request req(s);
+ //
+ // Now we enter another loop that reuses the request's connection (and
+ // memory - makes things more efficient). You should always do this for
+ // now; this requirement will be removed in future.
+ //
+ for (;;)
+ {
+ a.accept(req);
+ ret = handle_request(req, of);
+ of<< "handle_request() returned: " << ret << endl;
+ if (ret)
+ break;
+ }
   }
   
   return ret;

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/Jamfile.v2 (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/Jamfile.v2 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -9,6 +9,7 @@
     <library>/boost/test//boost_unit_test_framework/
     <library>/boost/system/
     <library>/boost/thread/
+ <library>/boost/regex/
   ;
 
 #local rule run-test( name )
@@ -24,11 +25,16 @@
     
     [ run cookie.cpp ]
     [ run response.cpp ]
+ [ run cgi_simple_request.cpp ]
+ [ run acgi_simple_request.cpp ]
+ [ run name_test.cpp ]
+ [ run map_test.cpp ]
   ;
 
 test-suite wget_test
   :
- [ run wget.cpp : "--log_level=message" ]
+ #[ run wget.cpp : "--log_level=message" ]
+ [ run hello_world.cpp /boost/filesystem/ ]
   ;
 
 explicit wget_test ;

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/response.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/response.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/test/run/response.cpp 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -1,4 +1,15 @@
-// Test the cgi::response class works as advertised
+// -- response.hpp --
+//
+// Copyright (c) Darren Garvey 2007-2008.
+// 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)
+//
+////////////////////////////////////////////////////////////////
+//
+// Test the cgi::response class works as advertised.
+//
+
 #define BOOST_TEST_MODULE response_test
 #include <boost/test/unit_test.hpp>
 

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/project-root.jam
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/project-root.jam (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/project-root.jam 2008-05-17 11:54:44 EDT (Sat, 17 May 2008)
@@ -1,11 +1,8 @@
 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 ] ;
@@ -27,27 +24,67 @@
 #
 # Note that the command line will override the environment variable!
 #############################################################################
-local rule get-bin-dir ( bin-name : envvar )
+local rule get-bin-dir ( protocol )
 {
- local bin-dir = [ MATCH "^--$(bin-name)=(.*)" : [ modules.peek : ARGV ] ] ;
+ local bin-dir = [ MATCH "^--$(protocol:L)-bin=(.*)" : [ modules.peek : ARGV ] ] ;
   if $(bin-dir)
   {
     return $(bin-dir) ;
   }
   else
   {
- bin-dir = [ os.environ $(envvar) ] ;
+ bin-dir = [ os.environ "BOOST_$(protocol:U)_BIN_PATH" ] ;
     if $(bin-dir)
     {
       return $(bin-dir) ;
     }
- return $(top)/$(bin-name) ;
+ else
+ {
+ return "$(top)/$(protocol:L)-bin" ;
+ }
+ }
+}
+
+path-constant cgi-bin : [ get-bin-dir "cgi" ] ;
+path-constant fcgi-bin : [ get-bin-dir "fcgi" ] ;
+path-constant scgi-bin : [ get-bin-dir "scgi" ] ;
+
+#############################################################################
+# Rule to extract the directory for web documents (some servers call it
+# the htdocs folder). The amortization examples will want this to be set.
+#
+# User can pass either:
+#
+# --htdocs=/path/to/htdocs
+#
+# on the bjam command line OR set the environment variable:
+#
+# BOOST_CGI_HTDOCS_PATH
+#
+# Note that the command line will override the environment variable!
+#############################################################################
+local rule get-htdocs-dir ( )
+{
+ local dir = [ MATCH "^--htdocs=(.*)" : [ modules.peek : ARGV ] ] ;
+ if $(dir)
+ {
+ return $(dir) ;
+ }
+ else
+ {
+ dir = [ os.environ "BOOST_CGI_HTDOCS_PATH" ] ;
+ if $(dir)
+ {
+ return $(dir) ;
+ }
+ else
+ {
+ return "$(top)/htdocs" ;
+ }
   }
 }
 
-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" ] ;
+path-constant htdocs : [ get-htdocs-dir ] ;
 
 
 use-project /boost/ : $(boost-root) ;
@@ -60,7 +97,6 @@
   : 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