From f4ec16c2c5c36a968dab832ea83727277a3e4fd2 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Sat, 16 Apr 2016 10:54:17 -0500 Subject: [PATCH] Inboarding cpp-netlib --- CMakeLists.txt | 20 +- cpp-netlib/.clang-format | 38 + cpp-netlib/.gitignore | 11 + cpp-netlib/.travis.yml | 55 + cpp-netlib/.ycm_extra_conf.py | 72 + cpp-netlib/CMakeLists.txt | 150 + cpp-netlib/LICENSE_1_0.txt | 23 + cpp-netlib/RATIONALE.txt | 64 + cpp-netlib/README.rst | 160 + cpp-netlib/boost/mime.hpp | 832 +++++ cpp-netlib/boost/network.hpp | 17 + cpp-netlib/boost/network/constants.hpp | 140 + cpp-netlib/boost/network/detail/debug.hpp | 27 + .../boost/network/detail/directive_base.hpp | 34 + .../boost/network/detail/wrapper_base.hpp | 41 + .../boost/network/include/http/client.hpp | 13 + .../boost/network/include/http/server.hpp | 13 + cpp-netlib/boost/network/include/message.hpp | 14 + cpp-netlib/boost/network/message.hpp | 135 + .../boost/network/message/directives.hpp | 36 + .../directives/detail/string_directive.hpp | 59 + .../directives/detail/string_value.hpp | 33 + .../network/message/directives/header.hpp | 76 + .../message/directives/remove_header.hpp | 48 + .../boost/network/message/message_concept.hpp | 66 + .../network/message/modifiers/add_header.hpp | 54 + .../boost/network/message/modifiers/body.hpp | 35 + .../message/modifiers/clear_headers.hpp | 55 + .../network/message/modifiers/destination.hpp | 41 + .../message/modifiers/remove_header.hpp | 65 + .../network/message/modifiers/source.hpp | 40 + .../boost/network/message/traits/body.hpp | 43 + .../network/message/traits/destination.hpp | 42 + .../boost/network/message/traits/headers.hpp | 56 + .../boost/network/message/traits/source.hpp | 41 + .../boost/network/message/transformers.hpp | 53 + .../message/transformers/selectors.hpp | 55 + .../network/message/transformers/to_lower.hpp | 86 + .../network/message/transformers/to_upper.hpp | 86 + cpp-netlib/boost/network/message/wrappers.hpp | 19 + .../boost/network/message/wrappers/body.hpp | 105 + .../network/message/wrappers/destination.hpp | 42 + .../network/message/wrappers/headers.hpp | 101 + .../boost/network/message/wrappers/source.hpp | 41 + cpp-netlib/boost/network/message_fwd.hpp | 18 + cpp-netlib/boost/network/protocol.hpp | 16 + cpp-netlib/boost/network/protocol/http.hpp | 19 + .../protocol/http/algorithms/linearize.hpp | 192 ++ .../boost/network/protocol/http/client.hpp | 72 + .../protocol/http/client/async_impl.hpp | 109 + .../http/client/connection/async_base.hpp | 80 + .../http/client/connection/async_normal.hpp | 509 +++ .../connection/async_protocol_handler.hpp | 356 +++ .../client/connection/connection_delegate.hpp | 37 + .../connection_delegate_factory.hpp | 62 + .../client/connection/normal_delegate.hpp | 54 + .../client/connection/normal_delegate.ipp | 57 + .../http/client/connection/ssl_delegate.hpp | 76 + .../http/client/connection/ssl_delegate.ipp | 113 + .../http/client/connection/sync_base.hpp | 302 ++ .../http/client/connection/sync_normal.hpp | 134 + .../http/client/connection/sync_ssl.hpp | 184 ++ .../network/protocol/http/client/facade.hpp | 174 ++ .../network/protocol/http/client/macros.hpp | 19 + .../network/protocol/http/client/options.hpp | 181 ++ .../network/protocol/http/client/pimpl.hpp | 90 + .../protocol/http/client/sync_impl.hpp | 99 + .../boost/network/protocol/http/errors.hpp | 31 + .../network/protocol/http/impl/message.ipp | 299 ++ .../network/protocol/http/impl/parser.ipp | 807 +++++ .../network/protocol/http/impl/request.hpp | 231 ++ .../protocol/http/impl/request_parser.ipp | 262 ++ .../network/protocol/http/impl/response.ipp | 522 ++++ .../boost/network/protocol/http/message.hpp | 137 + .../protocol/http/message/async_message.hpp | 158 + .../http/message/directives/major_version.hpp | 41 + .../http/message/directives/method.hpp | 23 + .../http/message/directives/minor_version.hpp | 41 + .../http/message/directives/status.hpp | 76 + .../message/directives/status_message.hpp | 27 + .../protocol/http/message/directives/uri.hpp | 26 + .../http/message/directives/version.hpp | 26 + .../network/protocol/http/message/header.hpp | 99 + .../protocol/http/message/header/name.hpp | 41 + .../protocol/http/message/header/value.hpp | 51 + .../protocol/http/message/header_concept.hpp | 38 + .../protocol/http/message/message_base.hpp | 33 + .../protocol/http/message/modifiers/body.hpp | 77 + .../http/message/modifiers/clear_headers.hpp | 52 + .../http/message/modifiers/destination.hpp | 95 + .../http/message/modifiers/headers.hpp | 60 + .../http/message/modifiers/major_version.hpp | 33 + .../http/message/modifiers/method.hpp | 31 + .../http/message/modifiers/minor_version.hpp | 33 + .../http/message/modifiers/source.hpp | 87 + .../http/message/modifiers/status.hpp | 47 + .../http/message/modifiers/status_message.hpp | 47 + .../protocol/http/message/modifiers/uri.hpp | 31 + .../http/message/modifiers/version.hpp | 49 + .../protocol/http/message/traits/status.hpp | 36 + .../http/message/traits/status_message.hpp | 40 + .../protocol/http/message/traits/version.hpp | 52 + .../protocol/http/message/wrappers/anchor.hpp | 38 + .../protocol/http/message/wrappers/body.hpp | 64 + .../http/message/wrappers/destination.hpp | 35 + .../http/message/wrappers/headers.hpp | 123 + .../protocol/http/message/wrappers/helper.hpp | 58 + .../protocol/http/message/wrappers/host.hpp | 42 + .../http/message/wrappers/major_version.hpp | 41 + .../protocol/http/message/wrappers/method.hpp | 43 + .../http/message/wrappers/minor_version.hpp | 41 + .../protocol/http/message/wrappers/path.hpp | 42 + .../protocol/http/message/wrappers/port.hpp | 62 + .../http/message/wrappers/protocol.hpp | 38 + .../protocol/http/message/wrappers/query.hpp | 43 + .../protocol/http/message/wrappers/ready.hpp | 47 + .../protocol/http/message/wrappers/source.hpp | 29 + .../protocol/http/message/wrappers/status.hpp | 50 + .../http/message/wrappers/status_message.hpp | 58 + .../protocol/http/message/wrappers/uri.hpp | 41 + .../http/message/wrappers/version.hpp | 47 + .../boost/network/protocol/http/parser.hpp | 352 +++ .../protocol/http/parser/incremental.hpp | 312 ++ .../http/policies/async_connection.hpp | 111 + .../protocol/http/policies/async_resolver.hpp | 91 + .../http/policies/pooled_connection.hpp | 236 ++ .../http/policies/simple_connection.hpp | 156 + .../protocol/http/policies/sync_resolver.hpp | 73 + .../boost/network/protocol/http/request.hpp | 84 + .../network/protocol/http/request_concept.hpp | 115 + .../network/protocol/http/request_parser.hpp | 108 + .../boost/network/protocol/http/response.hpp | 100 + .../protocol/http/response_concept.hpp | 62 + .../boost/network/protocol/http/server.hpp | 62 + .../protocol/http/server/async_connection.hpp | 674 ++++ .../protocol/http/server/async_server.hpp | 188 ++ .../protocol/http/server/impl/parsers.ipp | 74 + .../network/protocol/http/server/options.hpp | 210 ++ .../network/protocol/http/server/request.hpp | 51 + .../protocol/http/server/request_parser.hpp | 229 ++ .../http/server/socket_options_base.hpp | 62 + .../protocol/http/server/storage_base.hpp | 39 + .../protocol/http/server/sync_connection.hpp | 233 ++ .../protocol/http/server/sync_server.hpp | 134 + .../http/support/client_or_server.hpp | 41 + .../protocol/http/support/is_client.hpp | 29 + .../network/protocol/http/support/is_http.hpp | 29 + .../protocol/http/support/is_keepalive.hpp | 32 + .../protocol/http/support/is_server.hpp | 29 + .../protocol/http/support/is_simple.hpp | 29 + .../protocol/http/support/sync_only.hpp | 30 + .../boost/network/protocol/http/tags.hpp | 71 + .../boost/network/protocol/http/traits.hpp | 18 + .../http/traits/connection_keepalive.hpp | 25 + .../http/traits/connection_policy.hpp | 61 + .../protocol/http/traits/delegate_factory.hpp | 40 + .../protocol/http/traits/impl/chunk_cache.ipp | 32 + .../protocol/http/traits/impl/content.ipp | 46 + .../protocol/http/traits/impl/cookie_name.ipp | 27 + .../http/traits/impl/cookie_value.ipp | 27 + .../http/traits/impl/cookies_container.ipp | 30 + .../protocol/http/traits/impl/delimiters.ipp | 41 + .../protocol/http/traits/impl/header_name.ipp | 27 + .../http/traits/impl/header_value.ipp | 27 + .../protocol/http/traits/impl/headers.ipp | 85 + .../http/traits/impl/headers_container.ipp | 51 + .../protocol/http/traits/impl/method.ipp | 27 + .../http/traits/impl/post_content.ipp | 27 + .../http/traits/impl/query_container.ipp | 30 + .../protocol/http/traits/impl/query_name.ipp | 27 + .../http/traits/impl/query_string.ipp | 27 + .../protocol/http/traits/impl/query_value.ipp | 27 + .../http/traits/impl/request_methods.ipp | 50 + .../protocol/http/traits/impl/resource.ipp | 27 + .../http/traits/impl/response_code.ipp | 45 + .../http/traits/impl/response_message.ipp | 80 + .../http/traits/impl/status_message.ipp | 27 + .../protocol/http/traits/message_traits.hpp | 65 + .../protocol/http/traits/parser_traits.hpp | 71 + .../network/protocol/http/traits/resolver.hpp | 44 + .../protocol/http/traits/resolver_policy.hpp | 37 + .../network/protocol/http/traits/vector.hpp | 37 + .../boost/network/protocol/stream_handler.hpp | 188 ++ cpp-netlib/boost/network/support/is_async.hpp | 27 + .../network/support/is_default_string.hpp | 27 + .../network/support/is_default_wstring.hpp | 27 + cpp-netlib/boost/network/support/is_http.hpp | 26 + .../boost/network/support/is_keepalive.hpp | 26 + cpp-netlib/boost/network/support/is_pod.hpp | 26 + .../boost/network/support/is_simple.hpp | 26 + cpp-netlib/boost/network/support/is_sync.hpp | 26 + cpp-netlib/boost/network/support/is_tcp.hpp | 28 + cpp-netlib/boost/network/support/is_udp.hpp | 29 + .../boost/network/support/pod_or_normal.hpp | 29 + .../boost/network/support/sync_only.hpp | 30 + cpp-netlib/boost/network/tags.hpp | 68 + cpp-netlib/boost/network/traits/char.hpp | 37 + .../network/traits/headers_container.hpp | 33 + cpp-netlib/boost/network/traits/istream.hpp | 40 + .../boost/network/traits/istringstream.hpp | 40 + .../boost/network/traits/ostream_iterator.hpp | 34 + .../boost/network/traits/ostringstream.hpp | 41 + cpp-netlib/boost/network/traits/string.hpp | 48 + cpp-netlib/boost/network/traits/vector.hpp | 30 + cpp-netlib/boost/network/uri.hpp | 11 + cpp-netlib/boost/network/uri/accessors.hpp | 95 + cpp-netlib/boost/network/uri/builder.hpp | 151 + cpp-netlib/boost/network/uri/config.hpp | 18 + cpp-netlib/boost/network/uri/decode.hpp | 92 + .../boost/network/uri/detail/uri_parts.hpp | 87 + cpp-netlib/boost/network/uri/directives.hpp | 39 + .../network/uri/directives/authority.hpp | 32 + .../boost/network/uri/directives/fragment.hpp | 37 + .../boost/network/uri/directives/host.hpp | 34 + .../boost/network/uri/directives/path.hpp | 51 + .../boost/network/uri/directives/port.hpp | 44 + .../boost/network/uri/directives/query.hpp | 63 + .../boost/network/uri/directives/scheme.hpp | 48 + .../network/uri/directives/user_info.hpp | 36 + cpp-netlib/boost/network/uri/encode.hpp | 153 + cpp-netlib/boost/network/uri/schemes.hpp | 29 + cpp-netlib/boost/network/uri/uri.hpp | 375 +++ cpp-netlib/boost/network/uri/uri.ipp | 255 ++ cpp-netlib/boost/network/uri/uri_io.hpp | 22 + .../boost/network/utils/base64/encode-io.hpp | 270 ++ .../boost/network/utils/base64/encode.hpp | 418 +++ .../boost/network/utils/thread_pool.hpp | 110 + cpp-netlib/boost/network/version.hpp | 22 + cpp-netlib/cppnetlibConfig.cmake.in | 24 + cpp-netlib/cppnetlibConfigVersion.cmake.in | 11 + cpp-netlib/index.html | 25 + cpp-netlib/libs/mime/To-Do.txt | 16 + cpp-netlib/libs/mime/doc/mime.qbk | 58 + cpp-netlib/libs/mime/doc/quick_start.qbk | 11 + .../libs/mime/example/basic_parsing.cpp | 127 + cpp-netlib/libs/mime/example/basic_usage.cpp | 70 + cpp-netlib/libs/mime/test/CMakeLists.txt | 16 + .../mime/test/TestMessages/.gitattributes | 1 + .../libs/mime/test/TestMessages/00000001 | 40 + .../libs/mime/test/TestMessages/00000019 | 81 + .../libs/mime/test/TestMessages/00000431 | 140 + .../libs/mime/test/TestMessages/00000975 | 115 + .../mime/test/TestMessages/0019-NoBoundary | 80 + cpp-netlib/libs/mime/test/mime-roundtrip.cpp | 118 + cpp-netlib/libs/mime/test/mime-structure.cpp | 123 + cpp-netlib/libs/mime/test/mimeParse.py | 52 + cpp-netlib/libs/network/benchmarks/README.rst | 3 + cpp-netlib/libs/network/build/CMakeLists.txt | 6 + cpp-netlib/libs/network/doc/.gitignore | 1 + cpp-netlib/libs/network/doc/_ext/adjusts.py | 11 + .../network/doc/_static/Button-Info-icon.png | Bin 0 -> 3499 bytes .../doc/_static/Button-Warning-icon.png | Bin 0 -> 2911 bytes .../libs/network/doc/_static/cpp-netlib.css | 721 +++++ .../libs/network/doc/_static/ftp_uri.png | Bin 0 -> 25570 bytes .../libs/network/doc/_static/http_uri.png | Bin 0 -> 20719 bytes .../libs/network/doc/_static/mailto_uri.png | Bin 0 -> 10220 bytes .../network/doc/_static/orange-background.jpg | Bin 0 -> 283722 bytes .../libs/network/doc/_static/pygments.css | 69 + .../network/doc/_static/reset-fonts-grids.css | 8 + cpp-netlib/libs/network/doc/_static/uri.svg | 650 ++++ cpp-netlib/libs/network/doc/conf.py | 126 + cpp-netlib/libs/network/doc/contents.rst | 17 + cpp-netlib/libs/network/doc/examples.rst | 27 + .../network/doc/examples/http/atom_reader.rst | 78 + .../doc/examples/http/hello_world_client.rst | 94 + .../doc/examples/http/hello_world_server.rst | 139 + .../network/doc/examples/http/http_client.rst | 125 + .../network/doc/examples/http/simple_wget.rst | 110 + .../doc/examples/http/twitter_search.rst | 117 + .../libs/network/doc/getting_started.rst | 262 ++ cpp-netlib/libs/network/doc/history.rst | 54 + cpp-netlib/libs/network/doc/html/.buildinfo | 4 + .../doc/html/.doctrees/contents.doctree | Bin 0 -> 3791 bytes .../doc/html/.doctrees/environment.pickle | Bin 0 -> 79612 bytes .../doc/html/.doctrees/examples.doctree | Bin 0 -> 6990 bytes .../examples/http/atom_reader.doctree | Bin 0 -> 10118 bytes .../examples/http/hello_world_client.doctree | Bin 0 -> 11170 bytes .../examples/http/hello_world_server.doctree | Bin 0 -> 18574 bytes .../examples/http/http_client.doctree | Bin 0 -> 18372 bytes .../examples/http/simple_wget.doctree | Bin 0 -> 14966 bytes .../examples/http/twitter_search.doctree | Bin 0 -> 14747 bytes .../html/.doctrees/getting_started.doctree | Bin 0 -> 56216 bytes .../doc/html/.doctrees/history.doctree | Bin 0 -> 13079 bytes .../doc/html/.doctrees/in_depth.doctree | Bin 0 -> 5332 bytes .../doc/html/.doctrees/in_depth/http.doctree | Bin 0 -> 31204 bytes .../in_depth/http_client_tags.doctree | Bin 0 -> 9826 bytes .../html/.doctrees/in_depth/message.doctree | Bin 0 -> 52801 bytes .../doc/html/.doctrees/in_depth/uri.doctree | Bin 0 -> 33862 bytes .../network/doc/html/.doctrees/index.doctree | Bin 0 -> 21893 bytes .../doc/html/.doctrees/reference.doctree | Bin 0 -> 4509 bytes .../.doctrees/reference/http_client.doctree | Bin 0 -> 106074 bytes .../.doctrees/reference/http_request.doctree | Bin 0 -> 84869 bytes .../.doctrees/reference/http_response.doctree | Bin 0 -> 126547 bytes .../.doctrees/reference/http_server.doctree | Bin 0 -> 109045 bytes .../doc/html/.doctrees/references.doctree | Bin 0 -> 9643 bytes .../doc/html/.doctrees/techniques.doctree | Bin 0 -> 3856 bytes .../.doctrees/techniques/directives.doctree | Bin 0 -> 17073 bytes .../.doctrees/techniques/polymorphism.doctree | Bin 0 -> 11112 bytes .../techniques/tag_metafunctions.doctree | Bin 0 -> 29085 bytes .../doc/html/.doctrees/whats_new.doctree | Bin 0 -> 61078 bytes .../libs/network/doc/html/_images/boost.png | Bin 0 -> 13364 bytes .../libs/network/doc/html/_images/ftp_uri.png | Bin 0 -> 25570 bytes .../network/doc/html/_images/http_uri.png | Bin 0 -> 20719 bytes .../network/doc/html/_images/mailto_uri.png | Bin 0 -> 10220 bytes .../network/doc/html/_sources/contents.txt | 17 + .../network/doc/html/_sources/examples.txt | 27 + .../_sources/examples/http/atom_reader.txt | 78 + .../examples/http/hello_world_client.txt | 94 + .../examples/http/hello_world_server.txt | 139 + .../_sources/examples/http/http_client.txt | 125 + .../_sources/examples/http/simple_wget.txt | 110 + .../_sources/examples/http/twitter_search.txt | 117 + .../doc/html/_sources/getting_started.txt | 262 ++ .../network/doc/html/_sources/history.txt | 54 + .../network/doc/html/_sources/in_depth.txt | 15 + .../doc/html/_sources/in_depth/http.txt | 180 ++ .../_sources/in_depth/http_client_tags.txt | 42 + .../doc/html/_sources/in_depth/message.txt | 233 ++ .../doc/html/_sources/in_depth/uri.txt | 151 + .../libs/network/doc/html/_sources/index.txt | 124 + .../network/doc/html/_sources/reference.txt | 16 + .../html/_sources/reference/http_client.txt | 475 +++ .../html/_sources/reference/http_request.txt | 254 ++ .../html/_sources/reference/http_response.txt | 309 ++ .../html/_sources/reference/http_server.txt | 559 ++++ .../network/doc/html/_sources/references.txt | 25 + .../network/doc/html/_sources/techniques.txt | 12 + .../html/_sources/techniques/directives.txt | 92 + .../html/_sources/techniques/polymorphism.txt | 92 + .../_sources/techniques/tag_metafunctions.txt | 172 ++ .../network/doc/html/_sources/whats_new.txt | 229 ++ .../doc/html/_static/Button-Info-icon.png | Bin 0 -> 3499 bytes .../doc/html/_static/Button-Warning-icon.png | Bin 0 -> 2911 bytes .../network/doc/html/_static/ajax-loader.gif | Bin 0 -> 673 bytes .../libs/network/doc/html/_static/basic.css | 537 ++++ .../libs/network/doc/html/_static/boost.png | Bin 0 -> 13364 bytes .../doc/html/_static/comment-bright.png | Bin 0 -> 3500 bytes .../doc/html/_static/comment-close.png | Bin 0 -> 3578 bytes .../libs/network/doc/html/_static/comment.png | Bin 0 -> 3445 bytes .../network/doc/html/_static/cpp-netlib.css | 721 +++++ .../libs/network/doc/html/_static/default.css | 256 ++ .../network/doc/html/_static/dialog-note.png | Bin 0 -> 1582 bytes .../doc/html/_static/dialog-seealso.png | Bin 0 -> 1502 bytes .../network/doc/html/_static/dialog-todo.png | Bin 0 -> 1334 bytes .../network/doc/html/_static/dialog-topic.png | Bin 0 -> 1910 bytes .../doc/html/_static/dialog-warning.png | Bin 0 -> 1391 bytes .../libs/network/doc/html/_static/doctools.js | 238 ++ .../network/doc/html/_static/down-pressed.png | Bin 0 -> 368 bytes .../libs/network/doc/html/_static/down.png | Bin 0 -> 363 bytes .../libs/network/doc/html/_static/epub.css | 310 ++ .../libs/network/doc/html/_static/file.png | Bin 0 -> 392 bytes .../network/doc/html/_static/footerbg.png | Bin 0 -> 333 bytes .../libs/network/doc/html/_static/ftp_uri.png | Bin 0 -> 25570 bytes .../network/doc/html/_static/headerbg.png | Bin 0 -> 203 bytes .../network/doc/html/_static/http_uri.png | Bin 0 -> 20719 bytes .../libs/network/doc/html/_static/ie6.css | 7 + .../libs/network/doc/html/_static/jquery.js | 2 + .../network/doc/html/_static/mailto_uri.png | Bin 0 -> 10220 bytes .../network/doc/html/_static/middlebg.png | Bin 0 -> 2797 bytes .../libs/network/doc/html/_static/minus.png | Bin 0 -> 199 bytes .../doc/html/_static/orange-background.jpg | Bin 0 -> 283722 bytes .../libs/network/doc/html/_static/plus.png | Bin 0 -> 199 bytes .../network/doc/html/_static/pygments.css | 62 + .../libs/network/doc/html/_static/pyramid.css | 342 ++ .../doc/html/_static/reset-fonts-grids.css | 8 + .../network/doc/html/_static/searchtools.js | 622 ++++ .../libs/network/doc/html/_static/sidebar.js | 148 + .../network/doc/html/_static/transparent.gif | Bin 0 -> 49 bytes .../network/doc/html/_static/underscore.js | 31 + .../network/doc/html/_static/up-pressed.png | Bin 0 -> 372 bytes .../libs/network/doc/html/_static/up.png | Bin 0 -> 363 bytes .../libs/network/doc/html/_static/uri.svg | 650 ++++ .../network/doc/html/_static/websupport.js | 808 +++++ .../libs/network/doc/html/contents.html | 290 ++ .../libs/network/doc/html/examples.html | 136 + .../doc/html/examples/http/atom_reader.html | 182 ++ .../examples/http/hello_world_client.html | 199 ++ .../examples/http/hello_world_server.html | 240 ++ .../doc/html/examples/http/http_client.html | 213 ++ .../doc/html/examples/http/simple_wget.html | 210 ++ .../html/examples/http/twitter_search.html | 216 ++ .../libs/network/doc/html/genindex.html | 92 + .../network/doc/html/getting_started.html | 357 +++ cpp-netlib/libs/network/doc/html/history.html | 156 + .../libs/network/doc/html/in_depth.html | 132 + .../libs/network/doc/html/in_depth/http.html | 311 ++ .../doc/html/in_depth/http_client_tags.html | 139 + .../network/doc/html/in_depth/message.html | 399 +++ .../libs/network/doc/html/in_depth/uri.html | 295 ++ cpp-netlib/libs/network/doc/html/index.html | 210 ++ cpp-netlib/libs/network/doc/html/objects.inv | Bin 0 -> 512 bytes .../libs/network/doc/html/reference.html | 142 + .../doc/html/reference/http_client.html | 667 ++++ .../doc/html/reference/http_request.html | 443 +++ .../doc/html/reference/http_response.html | 476 +++ .../doc/html/reference/http_server.html | 759 +++++ .../libs/network/doc/html/references.html | 123 + cpp-netlib/libs/network/doc/html/search.html | 101 + .../libs/network/doc/html/searchindex.js | 1 + .../libs/network/doc/html/techniques.html | 116 + .../doc/html/techniques/directives.html | 191 ++ .../doc/html/techniques/polymorphism.html | 189 ++ .../html/techniques/tag_metafunctions.html | 265 ++ .../libs/network/doc/html/whats_new.html | 342 ++ cpp-netlib/libs/network/doc/in_depth.rst | 15 + cpp-netlib/libs/network/doc/in_depth/http.rst | 180 ++ .../network/doc/in_depth/http_client_tags.rst | 42 + .../libs/network/doc/in_depth/message.rst | 233 ++ cpp-netlib/libs/network/doc/in_depth/uri.rst | 151 + cpp-netlib/libs/network/doc/index.rst | 124 + cpp-netlib/libs/network/doc/make.bat | 113 + cpp-netlib/libs/network/doc/reference.rst | 16 + .../network/doc/reference/http_client.rst | 475 +++ .../network/doc/reference/http_request.rst | 254 ++ .../network/doc/reference/http_response.rst | 309 ++ .../network/doc/reference/http_server.rst | 559 ++++ cpp-netlib/libs/network/doc/references.rst | 25 + cpp-netlib/libs/network/doc/techniques.rst | 12 + .../network/doc/techniques/directives.rst | 92 + .../network/doc/techniques/polymorphism.rst | 92 + .../doc/techniques/tag_metafunctions.rst | 172 ++ cpp-netlib/libs/network/doc/whats_new.rst | 229 ++ .../libs/network/example/CMakeLists.txt | 162 + cpp-netlib/libs/network/example/atom/atom.cpp | 95 + cpp-netlib/libs/network/example/atom/atom.hpp | 112 + cpp-netlib/libs/network/example/atom/main.cpp | 38 + .../libs/network/example/http/fileserver.cpp | 187 ++ ...llo_world_async_server_with_work_queue.cpp | 187 ++ .../example/http/hello_world_client.cpp | 43 + .../example/http/hello_world_server.cpp | 64 + .../libs/network/example/http/one_liner.cpp | 22 + .../libs/network/example/http/ssl/dh512.pem | 12 + .../libs/network/example/http/ssl/server.pem | 53 + .../network/example/http/ssl/ssl_server.cpp | 112 + .../libs/network/example/http_client.cpp | 86 + .../libs/network/example/http_client1.cpp | 24 + .../libs/network/example/rapidxml/license.txt | 52 + .../libs/network/example/rapidxml/manual.html | 406 +++ .../network/example/rapidxml/rapidxml.hpp | 2746 +++++++++++++++++ .../example/rapidxml/rapidxml_iterators.hpp | 133 + .../example/rapidxml/rapidxml_print.hpp | 432 +++ .../example/rapidxml/rapidxml_utils.hpp | 104 + cpp-netlib/libs/network/example/rss/main.cpp | 37 + cpp-netlib/libs/network/example/rss/rss.cpp | 73 + cpp-netlib/libs/network/example/rss/rss.hpp | 77 + .../libs/network/example/simple_wget.cpp | 57 + .../libs/network/example/trivial_google.cpp | 18 + .../example/twitter/rapidjson/document.h | 806 +++++ .../example/twitter/rapidjson/filestream.h | 46 + .../twitter/rapidjson/internal/pow10.h | 54 + .../twitter/rapidjson/internal/stack.h | 82 + .../twitter/rapidjson/internal/strfunc.h | 24 + .../example/twitter/rapidjson/prettywriter.h | 152 + .../example/twitter/rapidjson/rapidjson.h | 512 +++ .../example/twitter/rapidjson/reader.h | 664 ++++ .../example/twitter/rapidjson/stringbuffer.h | 49 + .../example/twitter/rapidjson/writer.h | 224 ++ .../libs/network/example/twitter/search.cpp | 51 + .../libs/network/example/uri_builder.cpp | 20 + .../libs/network/experiment/CMakeLists.txt | 18 + .../experiment/utils/base64-standalone.hpp | 423 +++ .../utils/base64-stateful_buffer.hpp | 215 ++ .../utils/base64-stateful_iterator.hpp | 167 + .../utils/base64-stateful_transform.hpp | 169 + .../experiment/utils/base64-stateless.hpp | 97 + .../utils/iterators/iterator_with_state.hpp | 77 + .../iterators/stateful_base64_from_binary.hpp | 67 + .../iterators/stateful_transform_width.hpp | 206 ++ .../iterators/transform_width_with_state.hpp | 230 ++ .../experiment/utils_base64_experiment.cpp | 120 + .../experiment/utils_base64_experiment.ipp | 48 + .../experiment/utils_base64_experiment.txt | 55 + cpp-netlib/libs/network/src/CMakeLists.txt | 54 + cpp-netlib/libs/network/src/client.cpp | 17 + .../src/server_request_parsers_impl.cpp | 10 + cpp-netlib/libs/network/src/uri/schemes.cpp | 60 + cpp-netlib/libs/network/src/uri/uri.cpp | 6 + cpp-netlib/libs/network/test/CMakeLists.txt | 46 + .../test/client_server_include_failure.cpp | 22 + .../libs/network/test/http/CMakeLists.txt | 93 + .../test/http/client_constructor_test.cpp | 34 + .../http/client_get_different_port_test.cpp | 24 + .../test/http/client_get_streaming_test.cpp | 46 + .../network/test/http/client_get_test.cpp | 53 + .../test/http/client_get_timeout_test.cpp | 67 + .../test/http/client_include_inlined.cpp | 22 + .../http/client_localhost_normal_test.cpp | 366 +++ .../test/http/client_localhost_ssl_test.cpp | 341 ++ .../libs/network/test/http/client_types.hpp | 41 + .../network/test/http/http_test_server.hpp | 158 + .../test/http/message_async_ready_test.cpp | 18 + .../libs/network/test/http/message_test.cpp | 167 + .../http/request_incremental_parser_test.cpp | 141 + .../test/http/request_linearize_test.cpp | 70 + .../http/response_incremental_parser_test.cpp | 361 +++ .../libs/network/test/http/server_async.cpp | 52 + .../test/http/server_async_less_copy.cpp | 61 + .../server_async_run_stop_concurrency.cpp | 154 + .../test/http/server_constructor_test.cpp | 83 + .../test/http/server_header_parser_test.cpp | 55 + .../network/test/http/server_hello_world.cpp | 51 + .../test/http/server_include_inlined.cpp | 60 + .../libs/network/test/http/tag_types.hpp | 21 + .../test/http_server_async_less_copy.cpp | 74 + .../libs/network/test/httplib_acceptance.py | 81 + cpp-netlib/libs/network/test/message_test.cpp | 177 ++ .../network/test/message_transform_test.cpp | 39 + cpp-netlib/libs/network/test/server/boost.jpg | Bin 0 -> 4550 bytes .../libs/network/test/server/certificate.pem | 13 + .../network/test/server/cgi-bin/cgisupport.py | 42 + .../network/test/server/cgi-bin/echo_body.py | 20 + .../test/server/cgi-bin/echo_headers.py | 21 + .../test/server/cgi-bin/multiline-header.py | 44 + .../test/server/cgi-bin/requestinfo.py | 56 + .../libs/network/test/server/cgi-bin/sleep.py | 8 + .../libs/network/test/server/cgi_server.py | 34 + .../network/test/server/http_test_server.py | 34 + .../network/test/server/https_test_server.py | 49 + cpp-netlib/libs/network/test/server/key.pem | 15 + cpp-netlib/libs/network/test/server/test.xml | 4 + .../libs/network/test/uri/CMakeLists.txt | 38 + .../network/test/uri/relative_uri_test.cpp | 18 + .../test/uri/uri_builder_stream_test.cpp | 121 + .../network/test/uri/uri_builder_test.cpp | 134 + .../network/test/uri/uri_encoding_test.cpp | 49 + cpp-netlib/libs/network/test/uri/uri_test.cpp | 581 ++++ .../libs/network/test/utils_base64_test.cpp | 203 ++ .../libs/network/test/utils_thread_pool.cpp | 46 + cpp-netlib/package.sh | 43 + 529 files changed, 57236 insertions(+), 10 deletions(-) create mode 100644 cpp-netlib/.clang-format create mode 100644 cpp-netlib/.gitignore create mode 100644 cpp-netlib/.travis.yml create mode 100644 cpp-netlib/.ycm_extra_conf.py create mode 100644 cpp-netlib/CMakeLists.txt create mode 100644 cpp-netlib/LICENSE_1_0.txt create mode 100644 cpp-netlib/RATIONALE.txt create mode 100644 cpp-netlib/README.rst create mode 100644 cpp-netlib/boost/mime.hpp create mode 100644 cpp-netlib/boost/network.hpp create mode 100644 cpp-netlib/boost/network/constants.hpp create mode 100644 cpp-netlib/boost/network/detail/debug.hpp create mode 100644 cpp-netlib/boost/network/detail/directive_base.hpp create mode 100644 cpp-netlib/boost/network/detail/wrapper_base.hpp create mode 100644 cpp-netlib/boost/network/include/http/client.hpp create mode 100644 cpp-netlib/boost/network/include/http/server.hpp create mode 100644 cpp-netlib/boost/network/include/message.hpp create mode 100644 cpp-netlib/boost/network/message.hpp create mode 100644 cpp-netlib/boost/network/message/directives.hpp create mode 100644 cpp-netlib/boost/network/message/directives/detail/string_directive.hpp create mode 100644 cpp-netlib/boost/network/message/directives/detail/string_value.hpp create mode 100644 cpp-netlib/boost/network/message/directives/header.hpp create mode 100644 cpp-netlib/boost/network/message/directives/remove_header.hpp create mode 100644 cpp-netlib/boost/network/message/message_concept.hpp create mode 100644 cpp-netlib/boost/network/message/modifiers/add_header.hpp create mode 100644 cpp-netlib/boost/network/message/modifiers/body.hpp create mode 100644 cpp-netlib/boost/network/message/modifiers/clear_headers.hpp create mode 100644 cpp-netlib/boost/network/message/modifiers/destination.hpp create mode 100644 cpp-netlib/boost/network/message/modifiers/remove_header.hpp create mode 100644 cpp-netlib/boost/network/message/modifiers/source.hpp create mode 100644 cpp-netlib/boost/network/message/traits/body.hpp create mode 100644 cpp-netlib/boost/network/message/traits/destination.hpp create mode 100644 cpp-netlib/boost/network/message/traits/headers.hpp create mode 100644 cpp-netlib/boost/network/message/traits/source.hpp create mode 100644 cpp-netlib/boost/network/message/transformers.hpp create mode 100644 cpp-netlib/boost/network/message/transformers/selectors.hpp create mode 100644 cpp-netlib/boost/network/message/transformers/to_lower.hpp create mode 100644 cpp-netlib/boost/network/message/transformers/to_upper.hpp create mode 100644 cpp-netlib/boost/network/message/wrappers.hpp create mode 100644 cpp-netlib/boost/network/message/wrappers/body.hpp create mode 100644 cpp-netlib/boost/network/message/wrappers/destination.hpp create mode 100644 cpp-netlib/boost/network/message/wrappers/headers.hpp create mode 100644 cpp-netlib/boost/network/message/wrappers/source.hpp create mode 100644 cpp-netlib/boost/network/message_fwd.hpp create mode 100644 cpp-netlib/boost/network/protocol.hpp create mode 100644 cpp-netlib/boost/network/protocol/http.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/algorithms/linearize.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/async_impl.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/async_base.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/async_normal.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/async_protocol_handler.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/connection_delegate.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/normal_delegate.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/normal_delegate.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/ssl_delegate.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/ssl_delegate.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/sync_base.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/sync_normal.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/connection/sync_ssl.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/facade.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/macros.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/options.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/pimpl.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/client/sync_impl.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/errors.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/impl/message.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/impl/parser.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/impl/request.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/impl/request_parser.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/impl/response.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/message.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/async_message.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/directives/major_version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/directives/method.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/directives/minor_version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/directives/status.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/directives/status_message.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/directives/uri.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/directives/version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/header.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/header/name.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/header/value.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/header_concept.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/message_base.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/body.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/clear_headers.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/destination.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/headers.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/major_version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/method.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/minor_version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/source.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/status.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/status_message.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/uri.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/modifiers/version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/traits/status.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/traits/status_message.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/traits/version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/anchor.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/body.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/destination.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/headers.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/helper.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/host.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/major_version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/method.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/minor_version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/path.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/port.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/protocol.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/query.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/ready.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/source.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/status.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/status_message.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/uri.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/message/wrappers/version.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/parser.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/parser/incremental.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/policies/async_connection.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/policies/async_resolver.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/policies/pooled_connection.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/policies/simple_connection.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/policies/sync_resolver.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/request.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/request_concept.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/request_parser.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/response.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/response_concept.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server/async_connection.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server/async_server.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server/impl/parsers.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/server/options.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server/request.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server/request_parser.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server/socket_options_base.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server/storage_base.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server/sync_connection.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/server/sync_server.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/support/client_or_server.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/support/is_client.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/support/is_http.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/support/is_keepalive.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/support/is_server.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/support/is_simple.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/support/sync_only.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/tags.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/traits.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/connection_keepalive.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/connection_policy.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/delegate_factory.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/chunk_cache.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/content.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/cookie_name.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/cookie_value.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/cookies_container.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/delimiters.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/header_name.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/header_value.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/headers.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/headers_container.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/method.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/post_content.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/query_container.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/query_name.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/query_string.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/query_value.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/request_methods.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/resource.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/response_code.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/response_message.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/impl/status_message.ipp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/message_traits.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/parser_traits.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/resolver.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/resolver_policy.hpp create mode 100644 cpp-netlib/boost/network/protocol/http/traits/vector.hpp create mode 100644 cpp-netlib/boost/network/protocol/stream_handler.hpp create mode 100644 cpp-netlib/boost/network/support/is_async.hpp create mode 100644 cpp-netlib/boost/network/support/is_default_string.hpp create mode 100644 cpp-netlib/boost/network/support/is_default_wstring.hpp create mode 100644 cpp-netlib/boost/network/support/is_http.hpp create mode 100644 cpp-netlib/boost/network/support/is_keepalive.hpp create mode 100644 cpp-netlib/boost/network/support/is_pod.hpp create mode 100644 cpp-netlib/boost/network/support/is_simple.hpp create mode 100644 cpp-netlib/boost/network/support/is_sync.hpp create mode 100644 cpp-netlib/boost/network/support/is_tcp.hpp create mode 100644 cpp-netlib/boost/network/support/is_udp.hpp create mode 100644 cpp-netlib/boost/network/support/pod_or_normal.hpp create mode 100644 cpp-netlib/boost/network/support/sync_only.hpp create mode 100644 cpp-netlib/boost/network/tags.hpp create mode 100644 cpp-netlib/boost/network/traits/char.hpp create mode 100644 cpp-netlib/boost/network/traits/headers_container.hpp create mode 100644 cpp-netlib/boost/network/traits/istream.hpp create mode 100644 cpp-netlib/boost/network/traits/istringstream.hpp create mode 100644 cpp-netlib/boost/network/traits/ostream_iterator.hpp create mode 100644 cpp-netlib/boost/network/traits/ostringstream.hpp create mode 100644 cpp-netlib/boost/network/traits/string.hpp create mode 100644 cpp-netlib/boost/network/traits/vector.hpp create mode 100644 cpp-netlib/boost/network/uri.hpp create mode 100644 cpp-netlib/boost/network/uri/accessors.hpp create mode 100644 cpp-netlib/boost/network/uri/builder.hpp create mode 100644 cpp-netlib/boost/network/uri/config.hpp create mode 100644 cpp-netlib/boost/network/uri/decode.hpp create mode 100644 cpp-netlib/boost/network/uri/detail/uri_parts.hpp create mode 100644 cpp-netlib/boost/network/uri/directives.hpp create mode 100644 cpp-netlib/boost/network/uri/directives/authority.hpp create mode 100644 cpp-netlib/boost/network/uri/directives/fragment.hpp create mode 100644 cpp-netlib/boost/network/uri/directives/host.hpp create mode 100644 cpp-netlib/boost/network/uri/directives/path.hpp create mode 100644 cpp-netlib/boost/network/uri/directives/port.hpp create mode 100644 cpp-netlib/boost/network/uri/directives/query.hpp create mode 100644 cpp-netlib/boost/network/uri/directives/scheme.hpp create mode 100644 cpp-netlib/boost/network/uri/directives/user_info.hpp create mode 100644 cpp-netlib/boost/network/uri/encode.hpp create mode 100644 cpp-netlib/boost/network/uri/schemes.hpp create mode 100644 cpp-netlib/boost/network/uri/uri.hpp create mode 100644 cpp-netlib/boost/network/uri/uri.ipp create mode 100644 cpp-netlib/boost/network/uri/uri_io.hpp create mode 100644 cpp-netlib/boost/network/utils/base64/encode-io.hpp create mode 100644 cpp-netlib/boost/network/utils/base64/encode.hpp create mode 100644 cpp-netlib/boost/network/utils/thread_pool.hpp create mode 100644 cpp-netlib/boost/network/version.hpp create mode 100644 cpp-netlib/cppnetlibConfig.cmake.in create mode 100644 cpp-netlib/cppnetlibConfigVersion.cmake.in create mode 100644 cpp-netlib/index.html create mode 100644 cpp-netlib/libs/mime/To-Do.txt create mode 100644 cpp-netlib/libs/mime/doc/mime.qbk create mode 100644 cpp-netlib/libs/mime/doc/quick_start.qbk create mode 100644 cpp-netlib/libs/mime/example/basic_parsing.cpp create mode 100644 cpp-netlib/libs/mime/example/basic_usage.cpp create mode 100644 cpp-netlib/libs/mime/test/CMakeLists.txt create mode 100644 cpp-netlib/libs/mime/test/TestMessages/.gitattributes create mode 100644 cpp-netlib/libs/mime/test/TestMessages/00000001 create mode 100644 cpp-netlib/libs/mime/test/TestMessages/00000019 create mode 100644 cpp-netlib/libs/mime/test/TestMessages/00000431 create mode 100644 cpp-netlib/libs/mime/test/TestMessages/00000975 create mode 100644 cpp-netlib/libs/mime/test/TestMessages/0019-NoBoundary create mode 100644 cpp-netlib/libs/mime/test/mime-roundtrip.cpp create mode 100644 cpp-netlib/libs/mime/test/mime-structure.cpp create mode 100755 cpp-netlib/libs/mime/test/mimeParse.py create mode 100644 cpp-netlib/libs/network/benchmarks/README.rst create mode 100644 cpp-netlib/libs/network/build/CMakeLists.txt create mode 100644 cpp-netlib/libs/network/doc/.gitignore create mode 100644 cpp-netlib/libs/network/doc/_ext/adjusts.py create mode 100644 cpp-netlib/libs/network/doc/_static/Button-Info-icon.png create mode 100644 cpp-netlib/libs/network/doc/_static/Button-Warning-icon.png create mode 100644 cpp-netlib/libs/network/doc/_static/cpp-netlib.css create mode 100644 cpp-netlib/libs/network/doc/_static/ftp_uri.png create mode 100644 cpp-netlib/libs/network/doc/_static/http_uri.png create mode 100644 cpp-netlib/libs/network/doc/_static/mailto_uri.png create mode 100644 cpp-netlib/libs/network/doc/_static/orange-background.jpg create mode 100644 cpp-netlib/libs/network/doc/_static/pygments.css create mode 100644 cpp-netlib/libs/network/doc/_static/reset-fonts-grids.css create mode 100644 cpp-netlib/libs/network/doc/_static/uri.svg create mode 100644 cpp-netlib/libs/network/doc/conf.py create mode 100644 cpp-netlib/libs/network/doc/contents.rst create mode 100644 cpp-netlib/libs/network/doc/examples.rst create mode 100644 cpp-netlib/libs/network/doc/examples/http/atom_reader.rst create mode 100644 cpp-netlib/libs/network/doc/examples/http/hello_world_client.rst create mode 100644 cpp-netlib/libs/network/doc/examples/http/hello_world_server.rst create mode 100644 cpp-netlib/libs/network/doc/examples/http/http_client.rst create mode 100644 cpp-netlib/libs/network/doc/examples/http/simple_wget.rst create mode 100644 cpp-netlib/libs/network/doc/examples/http/twitter_search.rst create mode 100644 cpp-netlib/libs/network/doc/getting_started.rst create mode 100644 cpp-netlib/libs/network/doc/history.rst create mode 100644 cpp-netlib/libs/network/doc/html/.buildinfo create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/contents.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/environment.pickle create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/examples.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/examples/http/atom_reader.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/examples/http/hello_world_client.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/examples/http/hello_world_server.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/examples/http/http_client.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/examples/http/simple_wget.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/examples/http/twitter_search.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/getting_started.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/history.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/in_depth.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/in_depth/http.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/in_depth/http_client_tags.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/in_depth/message.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/in_depth/uri.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/index.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/reference.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/reference/http_client.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/reference/http_request.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/reference/http_response.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/reference/http_server.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/references.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/techniques.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/techniques/directives.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/techniques/polymorphism.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/techniques/tag_metafunctions.doctree create mode 100644 cpp-netlib/libs/network/doc/html/.doctrees/whats_new.doctree create mode 100644 cpp-netlib/libs/network/doc/html/_images/boost.png create mode 100644 cpp-netlib/libs/network/doc/html/_images/ftp_uri.png create mode 100644 cpp-netlib/libs/network/doc/html/_images/http_uri.png create mode 100644 cpp-netlib/libs/network/doc/html/_images/mailto_uri.png create mode 100644 cpp-netlib/libs/network/doc/html/_sources/contents.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/examples.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/examples/http/atom_reader.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/examples/http/hello_world_client.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/examples/http/hello_world_server.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/examples/http/http_client.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/examples/http/simple_wget.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/examples/http/twitter_search.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/getting_started.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/history.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/in_depth.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/in_depth/http.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/in_depth/http_client_tags.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/in_depth/message.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/in_depth/uri.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/index.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/reference.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/reference/http_client.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/reference/http_request.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/reference/http_response.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/reference/http_server.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/references.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/techniques.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/techniques/directives.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/techniques/polymorphism.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/techniques/tag_metafunctions.txt create mode 100644 cpp-netlib/libs/network/doc/html/_sources/whats_new.txt create mode 100644 cpp-netlib/libs/network/doc/html/_static/Button-Info-icon.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/Button-Warning-icon.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/ajax-loader.gif create mode 100644 cpp-netlib/libs/network/doc/html/_static/basic.css create mode 100644 cpp-netlib/libs/network/doc/html/_static/boost.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/comment-bright.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/comment-close.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/comment.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/cpp-netlib.css create mode 100644 cpp-netlib/libs/network/doc/html/_static/default.css create mode 100644 cpp-netlib/libs/network/doc/html/_static/dialog-note.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/dialog-seealso.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/dialog-todo.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/dialog-topic.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/dialog-warning.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/doctools.js create mode 100644 cpp-netlib/libs/network/doc/html/_static/down-pressed.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/down.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/epub.css create mode 100644 cpp-netlib/libs/network/doc/html/_static/file.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/footerbg.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/ftp_uri.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/headerbg.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/http_uri.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/ie6.css create mode 100644 cpp-netlib/libs/network/doc/html/_static/jquery.js create mode 100644 cpp-netlib/libs/network/doc/html/_static/mailto_uri.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/middlebg.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/minus.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/orange-background.jpg create mode 100644 cpp-netlib/libs/network/doc/html/_static/plus.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/pygments.css create mode 100644 cpp-netlib/libs/network/doc/html/_static/pyramid.css create mode 100644 cpp-netlib/libs/network/doc/html/_static/reset-fonts-grids.css create mode 100644 cpp-netlib/libs/network/doc/html/_static/searchtools.js create mode 100644 cpp-netlib/libs/network/doc/html/_static/sidebar.js create mode 100644 cpp-netlib/libs/network/doc/html/_static/transparent.gif create mode 100644 cpp-netlib/libs/network/doc/html/_static/underscore.js create mode 100644 cpp-netlib/libs/network/doc/html/_static/up-pressed.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/up.png create mode 100644 cpp-netlib/libs/network/doc/html/_static/uri.svg create mode 100644 cpp-netlib/libs/network/doc/html/_static/websupport.js create mode 100644 cpp-netlib/libs/network/doc/html/contents.html create mode 100644 cpp-netlib/libs/network/doc/html/examples.html create mode 100644 cpp-netlib/libs/network/doc/html/examples/http/atom_reader.html create mode 100644 cpp-netlib/libs/network/doc/html/examples/http/hello_world_client.html create mode 100644 cpp-netlib/libs/network/doc/html/examples/http/hello_world_server.html create mode 100644 cpp-netlib/libs/network/doc/html/examples/http/http_client.html create mode 100644 cpp-netlib/libs/network/doc/html/examples/http/simple_wget.html create mode 100644 cpp-netlib/libs/network/doc/html/examples/http/twitter_search.html create mode 100644 cpp-netlib/libs/network/doc/html/genindex.html create mode 100644 cpp-netlib/libs/network/doc/html/getting_started.html create mode 100644 cpp-netlib/libs/network/doc/html/history.html create mode 100644 cpp-netlib/libs/network/doc/html/in_depth.html create mode 100644 cpp-netlib/libs/network/doc/html/in_depth/http.html create mode 100644 cpp-netlib/libs/network/doc/html/in_depth/http_client_tags.html create mode 100644 cpp-netlib/libs/network/doc/html/in_depth/message.html create mode 100644 cpp-netlib/libs/network/doc/html/in_depth/uri.html create mode 100644 cpp-netlib/libs/network/doc/html/index.html create mode 100644 cpp-netlib/libs/network/doc/html/objects.inv create mode 100644 cpp-netlib/libs/network/doc/html/reference.html create mode 100644 cpp-netlib/libs/network/doc/html/reference/http_client.html create mode 100644 cpp-netlib/libs/network/doc/html/reference/http_request.html create mode 100644 cpp-netlib/libs/network/doc/html/reference/http_response.html create mode 100644 cpp-netlib/libs/network/doc/html/reference/http_server.html create mode 100644 cpp-netlib/libs/network/doc/html/references.html create mode 100644 cpp-netlib/libs/network/doc/html/search.html create mode 100644 cpp-netlib/libs/network/doc/html/searchindex.js create mode 100644 cpp-netlib/libs/network/doc/html/techniques.html create mode 100644 cpp-netlib/libs/network/doc/html/techniques/directives.html create mode 100644 cpp-netlib/libs/network/doc/html/techniques/polymorphism.html create mode 100644 cpp-netlib/libs/network/doc/html/techniques/tag_metafunctions.html create mode 100644 cpp-netlib/libs/network/doc/html/whats_new.html create mode 100644 cpp-netlib/libs/network/doc/in_depth.rst create mode 100644 cpp-netlib/libs/network/doc/in_depth/http.rst create mode 100644 cpp-netlib/libs/network/doc/in_depth/http_client_tags.rst create mode 100644 cpp-netlib/libs/network/doc/in_depth/message.rst create mode 100644 cpp-netlib/libs/network/doc/in_depth/uri.rst create mode 100644 cpp-netlib/libs/network/doc/index.rst create mode 100644 cpp-netlib/libs/network/doc/make.bat create mode 100644 cpp-netlib/libs/network/doc/reference.rst create mode 100644 cpp-netlib/libs/network/doc/reference/http_client.rst create mode 100644 cpp-netlib/libs/network/doc/reference/http_request.rst create mode 100644 cpp-netlib/libs/network/doc/reference/http_response.rst create mode 100644 cpp-netlib/libs/network/doc/reference/http_server.rst create mode 100644 cpp-netlib/libs/network/doc/references.rst create mode 100644 cpp-netlib/libs/network/doc/techniques.rst create mode 100644 cpp-netlib/libs/network/doc/techniques/directives.rst create mode 100644 cpp-netlib/libs/network/doc/techniques/polymorphism.rst create mode 100644 cpp-netlib/libs/network/doc/techniques/tag_metafunctions.rst create mode 100644 cpp-netlib/libs/network/doc/whats_new.rst create mode 100644 cpp-netlib/libs/network/example/CMakeLists.txt create mode 100644 cpp-netlib/libs/network/example/atom/atom.cpp create mode 100644 cpp-netlib/libs/network/example/atom/atom.hpp create mode 100644 cpp-netlib/libs/network/example/atom/main.cpp create mode 100644 cpp-netlib/libs/network/example/http/fileserver.cpp create mode 100644 cpp-netlib/libs/network/example/http/hello_world_async_server_with_work_queue.cpp create mode 100644 cpp-netlib/libs/network/example/http/hello_world_client.cpp create mode 100644 cpp-netlib/libs/network/example/http/hello_world_server.cpp create mode 100644 cpp-netlib/libs/network/example/http/one_liner.cpp create mode 100644 cpp-netlib/libs/network/example/http/ssl/dh512.pem create mode 100644 cpp-netlib/libs/network/example/http/ssl/server.pem create mode 100644 cpp-netlib/libs/network/example/http/ssl/ssl_server.cpp create mode 100644 cpp-netlib/libs/network/example/http_client.cpp create mode 100644 cpp-netlib/libs/network/example/http_client1.cpp create mode 100644 cpp-netlib/libs/network/example/rapidxml/license.txt create mode 100644 cpp-netlib/libs/network/example/rapidxml/manual.html create mode 100644 cpp-netlib/libs/network/example/rapidxml/rapidxml.hpp create mode 100644 cpp-netlib/libs/network/example/rapidxml/rapidxml_iterators.hpp create mode 100644 cpp-netlib/libs/network/example/rapidxml/rapidxml_print.hpp create mode 100644 cpp-netlib/libs/network/example/rapidxml/rapidxml_utils.hpp create mode 100644 cpp-netlib/libs/network/example/rss/main.cpp create mode 100644 cpp-netlib/libs/network/example/rss/rss.cpp create mode 100644 cpp-netlib/libs/network/example/rss/rss.hpp create mode 100644 cpp-netlib/libs/network/example/simple_wget.cpp create mode 100644 cpp-netlib/libs/network/example/trivial_google.cpp create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/document.h create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/filestream.h create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/internal/pow10.h create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/internal/stack.h create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/internal/strfunc.h create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/prettywriter.h create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/rapidjson.h create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/reader.h create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/stringbuffer.h create mode 100644 cpp-netlib/libs/network/example/twitter/rapidjson/writer.h create mode 100644 cpp-netlib/libs/network/example/twitter/search.cpp create mode 100644 cpp-netlib/libs/network/example/uri_builder.cpp create mode 100644 cpp-netlib/libs/network/experiment/CMakeLists.txt create mode 100644 cpp-netlib/libs/network/experiment/utils/base64-standalone.hpp create mode 100644 cpp-netlib/libs/network/experiment/utils/base64-stateful_buffer.hpp create mode 100644 cpp-netlib/libs/network/experiment/utils/base64-stateful_iterator.hpp create mode 100644 cpp-netlib/libs/network/experiment/utils/base64-stateful_transform.hpp create mode 100644 cpp-netlib/libs/network/experiment/utils/base64-stateless.hpp create mode 100644 cpp-netlib/libs/network/experiment/utils/iterators/iterator_with_state.hpp create mode 100644 cpp-netlib/libs/network/experiment/utils/iterators/stateful_base64_from_binary.hpp create mode 100644 cpp-netlib/libs/network/experiment/utils/iterators/stateful_transform_width.hpp create mode 100644 cpp-netlib/libs/network/experiment/utils/iterators/transform_width_with_state.hpp create mode 100644 cpp-netlib/libs/network/experiment/utils_base64_experiment.cpp create mode 100644 cpp-netlib/libs/network/experiment/utils_base64_experiment.ipp create mode 100644 cpp-netlib/libs/network/experiment/utils_base64_experiment.txt create mode 100644 cpp-netlib/libs/network/src/CMakeLists.txt create mode 100644 cpp-netlib/libs/network/src/client.cpp create mode 100644 cpp-netlib/libs/network/src/server_request_parsers_impl.cpp create mode 100644 cpp-netlib/libs/network/src/uri/schemes.cpp create mode 100644 cpp-netlib/libs/network/src/uri/uri.cpp create mode 100644 cpp-netlib/libs/network/test/CMakeLists.txt create mode 100644 cpp-netlib/libs/network/test/client_server_include_failure.cpp create mode 100644 cpp-netlib/libs/network/test/http/CMakeLists.txt create mode 100644 cpp-netlib/libs/network/test/http/client_constructor_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/client_get_different_port_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/client_get_streaming_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/client_get_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/client_get_timeout_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/client_include_inlined.cpp create mode 100644 cpp-netlib/libs/network/test/http/client_localhost_normal_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/client_localhost_ssl_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/client_types.hpp create mode 100644 cpp-netlib/libs/network/test/http/http_test_server.hpp create mode 100644 cpp-netlib/libs/network/test/http/message_async_ready_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/message_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/request_incremental_parser_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/request_linearize_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/response_incremental_parser_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/server_async.cpp create mode 100644 cpp-netlib/libs/network/test/http/server_async_less_copy.cpp create mode 100644 cpp-netlib/libs/network/test/http/server_async_run_stop_concurrency.cpp create mode 100644 cpp-netlib/libs/network/test/http/server_constructor_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/server_header_parser_test.cpp create mode 100644 cpp-netlib/libs/network/test/http/server_hello_world.cpp create mode 100644 cpp-netlib/libs/network/test/http/server_include_inlined.cpp create mode 100644 cpp-netlib/libs/network/test/http/tag_types.hpp create mode 100644 cpp-netlib/libs/network/test/http_server_async_less_copy.cpp create mode 100644 cpp-netlib/libs/network/test/httplib_acceptance.py create mode 100644 cpp-netlib/libs/network/test/message_test.cpp create mode 100644 cpp-netlib/libs/network/test/message_transform_test.cpp create mode 100644 cpp-netlib/libs/network/test/server/boost.jpg create mode 100644 cpp-netlib/libs/network/test/server/certificate.pem create mode 100755 cpp-netlib/libs/network/test/server/cgi-bin/cgisupport.py create mode 100755 cpp-netlib/libs/network/test/server/cgi-bin/echo_body.py create mode 100755 cpp-netlib/libs/network/test/server/cgi-bin/echo_headers.py create mode 100755 cpp-netlib/libs/network/test/server/cgi-bin/multiline-header.py create mode 100755 cpp-netlib/libs/network/test/server/cgi-bin/requestinfo.py create mode 100755 cpp-netlib/libs/network/test/server/cgi-bin/sleep.py create mode 100644 cpp-netlib/libs/network/test/server/cgi_server.py create mode 100644 cpp-netlib/libs/network/test/server/http_test_server.py create mode 100644 cpp-netlib/libs/network/test/server/https_test_server.py create mode 100644 cpp-netlib/libs/network/test/server/key.pem create mode 100644 cpp-netlib/libs/network/test/server/test.xml create mode 100644 cpp-netlib/libs/network/test/uri/CMakeLists.txt create mode 100644 cpp-netlib/libs/network/test/uri/relative_uri_test.cpp create mode 100644 cpp-netlib/libs/network/test/uri/uri_builder_stream_test.cpp create mode 100644 cpp-netlib/libs/network/test/uri/uri_builder_test.cpp create mode 100644 cpp-netlib/libs/network/test/uri/uri_encoding_test.cpp create mode 100644 cpp-netlib/libs/network/test/uri/uri_test.cpp create mode 100644 cpp-netlib/libs/network/test/utils_base64_test.cpp create mode 100644 cpp-netlib/libs/network/test/utils_thread_pool.cpp create mode 100755 cpp-netlib/package.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 0182195e..bc48b8bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,9 +46,6 @@ include_directories (${Boost_INCLUDE_DIR}) find_package (Qt5 REQUIRED COMPONENTS Core Gui Widgets Test ${PLATFORM_QT_PACKAGES}) include_directories (${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Test_INCLUDE_DIRS}) -find_package (cppnetlib) -include_directories (${CPPNETLIB_INCLUDE_DIRS}) - include_directories (${OPENCL_INCLUDE_DIRS}) add_library (ed25519 @@ -72,6 +69,9 @@ endif () add_subdirectory (gtest) include_directories ("gtest/include") +add_subdirectory (cpp-netlib) +include_directories ("cpp-netlib") + add_library (cryptopp cryptopp/3way.cpp cryptopp/adler32.cpp @@ -344,19 +344,19 @@ else (WIN32) set (PLATFORM_WALLET_LIBS) endif (WIN32) -target_link_libraries (core_test node secure lmdb xxhash ed25519 argon2 blake2 cryptopp gtest_main gtest ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_THREAD_LIBRARY} ${CPPNETLIB_LIBRARIES} ${PLATFORM_LIBS}) +target_link_libraries (core_test node secure lmdb xxhash ed25519 argon2 blake2 cryptopp gtest_main gtest cppnetlib-uri cppnetlib-server-parsers cppnetlib-client-connections ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) -target_link_libraries (slow_test node secure lmdb xxhash ed25519 argon2 blake2 cryptopp gtest_main gtest ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${CPPNETLIB_LIBRARIES} ${PLATFORM_LIBS}) +target_link_libraries (slow_test node secure lmdb xxhash ed25519 argon2 blake2 cryptopp gtest_main gtest cppnetlib-uri cppnetlib-server-parsers cppnetlib-client-connections ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) -target_link_libraries (rai_node node secure lmdb xxhash ed25519 argon2 blake2 cryptopp ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${CPPNETLIB_LIBRARIES} ${PLATFORM_LIBS}) +target_link_libraries (rai_node node secure lmdb xxhash ed25519 argon2 blake2 cryptopp cppnetlib-uri cppnetlib-server-parsers cppnetlib-client-connections ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) -target_link_libraries (rai_landing node secure lmdb xxhash ed25519 argon2 blake2 cryptopp ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_THREAD_LIBRARY} ${CPPNETLIB_LIBRARIES} ${PLATFORM_LIBS}) +target_link_libraries (rai_landing node secure lmdb xxhash ed25519 argon2 blake2 cryptopp cppnetlib-uri cppnetlib-server-parsers cppnetlib-client-connections ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS}) -target_link_libraries (qt_test node secure lmdb xxhash ed25519 qt argon2 blake2 cryptopp gtest ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${CPPNETLIB_LIBRARIES} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Test ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS}) +target_link_libraries (qt_test node secure lmdb xxhash ed25519 qt argon2 blake2 cryptopp gtest cppnetlib-uri cppnetlib-server-parsers cppnetlib-client-connections ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Test ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS}) -target_link_libraries (rai_wallet node secure lmdb xxhash ed25519 qt argon2 blake2 cryptopp ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${CPPNETLIB_LIBRARIES} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS} ${PLATFORM_WALLET_LIBS}) +target_link_libraries (rai_wallet node secure lmdb xxhash ed25519 qt argon2 blake2 cryptopp cppnetlib-uri cppnetlib-server-parsers cppnetlib-client-connections ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS} ${PLATFORM_WALLET_LIBS}) -target_link_libraries (qt_system node secure lmdb xxhash ed25519 qt argon2 blake2 cryptopp gtest ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${CPPNETLIB_LIBRARIES} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS}) +target_link_libraries (qt_system node secure lmdb xxhash ed25519 qt argon2 blake2 cryptopp gtest cppnetlib-uri cppnetlib-server-parsers cppnetlib-client-connections ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS}) set (CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE) if (APPLE) diff --git a/cpp-netlib/.clang-format b/cpp-netlib/.clang-format new file mode 100644 index 00000000..c82fea5e --- /dev/null +++ b/cpp-netlib/.clang-format @@ -0,0 +1,38 @@ +BasedOnStyle: Google +AccessModifierOffset: -1 +ConstructorInitializerIndentWidth: 4 +AlignEscapedNewlinesLeft: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakTemplateDeclarations: true +AlwaysBreakBeforeMultilineStrings: true +BreakBeforeBinaryOperators: false +BreakConstructorInitializersBeforeComma: false +BinPackParameters: true +ColumnLimit: 80 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +DerivePointerBinding: true +ExperimentalAutoDetectBinPacking: false +IndentCaseLabels: true +MaxEmptyLinesToKeep: 1 +ObjCSpaceBeforeProtocolList: false +PenaltyBreakComment: 60 +PenaltyBreakString: 1000 +PenaltyBreakFirstLessLess: 120 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerBindsToType: true +SpacesBeforeTrailingComments: 2 +Cpp11BracedListStyle: true +Standard: Auto +IndentWidth: 2 +TabWidth: 4 +UseTab: false +BreakBeforeBraces: Attach +IndentFunctionDeclarationAfterType: true +SpacesInParentheses: false +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false +SpaceAfterControlStatementKeyword: true diff --git a/cpp-netlib/.gitignore b/cpp-netlib/.gitignore new file mode 100644 index 00000000..f8f6375a --- /dev/null +++ b/cpp-netlib/.gitignore @@ -0,0 +1,11 @@ +*.cmake +*.swp +*.pyc +CMakeCache.txt +CMakeFiles +Makefile +Testing +*.gch +libs/mime/test/mime-roundtrip +*.a +_build diff --git a/cpp-netlib/.travis.yml b/cpp-netlib/.travis.yml new file mode 100644 index 00000000..3a6796d0 --- /dev/null +++ b/cpp-netlib/.travis.yml @@ -0,0 +1,55 @@ +language: + - cpp + +compiler: + - gcc + - clang + +env: + - BOOST_VER=1.54.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" + - BOOST_VER=1.54.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" + - BOOST_VER=1.54.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" + - BOOST_VER=1.54.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" + - BOOST_VER=1.55.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" + - BOOST_VER=1.55.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="ON" + - BOOST_VER=1.55.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" + - BOOST_VER=1.55.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="ON" + - BOOST_VER=1.54.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" + - BOOST_VER=1.54.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" + - BOOST_VER=1.54.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" + - BOOST_VER=1.54.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" + - BOOST_VER=1.55.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" + - BOOST_VER=1.55.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Release" ENABLE_HTTPS="OFF" + - BOOST_VER=1.55.0 BUILD_SHARED_LIBS="ON" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" + - BOOST_VER=1.55.0 BUILD_SHARED_LIBS="OFF" CMAKE_BUILD_TYPE="Debug" ENABLE_HTTPS="OFF" + +before_install: + - if [ "${CXX}" == "g++" ] || [ ${BUILD_SHARED_LIBS} = "OFF" ]; then + sudo add-apt-repository ppa:boost-latest/ppa --yes; + sudo apt-get update; + fi + - if [ "${CXX}" == "clang++" ] && [ ${BUILD_SHARED_LIBS} = "ON" ]; then + svn export http://svn.boost.org/svn/boost/tags/release/Boost_${BOOST_VER//./_} ../boost_${BOOST_VER//./_}; + export BOOST_ROOT=$TRAVIS_BUILD_DIR/../boost_${BOOST_VER//./_}; + fi + +install: + - if [ "${CXX}" == "g++" ] || [ ${BUILD_SHARED_LIBS} = "OFF" ]; then + sudo apt-get install libboost${BOOST_VER/%.0/}-all-dev; + fi + - if [ "${CXX}" == "clang++" ] && [ ${BUILD_SHARED_LIBS} = "ON" ]; then + cd $BOOST_ROOT; + ./bootstrap.sh --with-toolset=$CC; + ./b2 -j4 --stagedir=.; + cd -; + fi + +script: + - cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} + -DCPP-NETLIB_ENABLE_HTTPS=${ENABLE_HTTPS} + - make + - make test + +after_failure: + - cat Testing/Temporary/LastTest.log diff --git a/cpp-netlib/.ycm_extra_conf.py b/cpp-netlib/.ycm_extra_conf.py new file mode 100644 index 00000000..85cf36ad --- /dev/null +++ b/cpp-netlib/.ycm_extra_conf.py @@ -0,0 +1,72 @@ +# Copyright 2013 Google, Inc. +# Copyright 2013 Dean Michael Berris +# 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) +# +# Project-wide configuration for YouCompleteMe Vim plugin. +# +# Based off of Valloric's .ycm_conf_extra.py for YouCompleteMe: +# https://github.com/Valloric/YouCompleteMe/blob/master/cpp/ycm/.ycm_extra_conf.py +# + +import os +import ycm_core + +flags = [ + '-Wall', + '-Wextra', + '-Werror', + '-std=c++03', + '-isystem', + '.', + '-isystem', + '/usr/include', + '-isystem', + '/usr/include/c++/4.6', + '-isystem', + '/usr/include/clang/3.0/include', + '-isystem', + '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1', + '-I', + os.environ['BOOST_ROOT'], + # Always enable debugging for the project when building for semantic + # completion. + '-DBOOST_NETWORK_DEBUG', + ] + +def DirectoryOfThisScript(): + return os.path.dirname(os.path.abspath(__file__)) + + +def MakeRelativePathsInFlagsAbsolute(flags, working_directory): + if not working_directory: + return list(flags) + new_flags = [] + make_next_absolute = False + path_flags = ['-isystem', '-I', '-iquote', '--sysroot='] + for flag in flags: + new_flag = flag + if make_next_absolute: + make_next_absolute = False + if not flag.startswith('/'): + new_flag = os.path.join(working_directory, flag) + + for path_flag in path_flags: + if flag == path_flag: + make_next_absolute = True + break + if flag.startswith(path_flag): + path = flag[len(path_flag):] + new_flag = path_flag + os.path.join(working_directory, path) + break + + if new_flag: + new_flags.append(new_flag) + return new_flags + + +def FlagsForFile(filename): + relative_to = DirectoryOfThisScript() + final_flags = MakeRelativePathsInFlagsAbsolute(flags, relative_to) + return {'flags': final_flags, 'do_cache': True } diff --git a/cpp-netlib/CMakeLists.txt b/cpp-netlib/CMakeLists.txt new file mode 100644 index 00000000..aa0792d4 --- /dev/null +++ b/cpp-netlib/CMakeLists.txt @@ -0,0 +1,150 @@ +# Copyright (c) Dean Michael Berris 2010. +# 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) + +cmake_minimum_required(VERSION 2.8) +project(CPP-NETLIB) + +option( CPP-NETLIB_BUILD_SHARED_LIBS "Build cpp-netlib as shared libraries." OFF ) +option( CPP-NETLIB_BUILD_TESTS "Build the cpp-netlib project tests." OFF) +option( CPP-NETLIB_BUILD_EXPERIMENTS "Build the cpp-netlib project experiments." OFF) +option( CPP-NETLIB_BUILD_EXAMPLES "Build the cpp-netlib project examples." OFF) +option( CPP-NETLIB_ENABLE_HTTPS "Build cpp-netlib with support for https if OpenSSL is found." OFF) + +include(GNUInstallDirs) + +# determine install path for CMake config files +if(WIN32 AND NOT CYGWIN) + set(DEF_INSTALL_CMAKE_DIR CMake) +else() + set(DEF_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/cppnetlib) +endif() +set(INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") + +# Make relative cmake install path absolute (needed later on) +if(NOT IS_ABSOLUTE "${INSTALL_CMAKE_DIR}") + set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}") +endif() + + +if(CPP-NETLIB_BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + message (STATUS "Linking boost testing libs dynamically...") + set(Boost_USE_STATIC_LIBS OFF) + set(CPP-NETLIB_BUILD_SHARED_LIBS ON) + set(BUILD_SHARED_LIBS ON) + add_definitions(-DBOOST_TEST_DYN_LINK) +else() + set(Boost_USE_STATIC_LIBS ON) + set(CPP-NETLIB_BUILD_SHARED_LIBS OFF) + set(BUILD_SHARED_LIBS OFF) +endif() + +set(Boost_USE_MULTI_THREADED ON) +find_package( Boost 1.54.0 + REQUIRED unit_test_framework system regex date_time thread filesystem + program_options chrono atomic ) + +if (CPP-NETLIB_ENABLE_HTTPS) + find_package( OpenSSL ) +endif() + +find_package( Threads ) +set(CMAKE_VERBOSE_MAKEFILE true) + +set(CPPNETLIB_VERSION_MAJOR 0) # MUST bump this whenever we make ABI-incompatible changes +set(CPPNETLIB_VERSION_MINOR 11) +set(CPPNETLIB_VERSION_PATCH 1) +set(CPPNETLIB_VERSION_STRING ${CPPNETLIB_VERSION_MAJOR}.${CPPNETLIB_VERSION_MINOR}.${CPPNETLIB_VERSION_PATCH}) + +if (CMAKE_BUILD_TYPE MATCHES Debug) + add_definitions(-DBOOST_NETWORK_DEBUG) +endif() + +if (OPENSSL_FOUND) + add_definitions(-DBOOST_NETWORK_ENABLE_HTTPS) + include_directories(${OPENSSL_INCLUDE_DIR}) +endif() + +if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") +elseif (${CMAKE_CXX_COMPILER_ID} MATCHES Clang) + if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + # We want to link in C++11 mode if we're using Clang and on OS X. + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -ftemplate-depth=256 -std=c++11 -stdlib=libc++") + else() + # We just add the -Wall and a high enough template depth + # flag for Clang in other systems. + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -ftemplate-depth=256") + endif() +endif() + + +if (Boost_FOUND) + if (MSVC) + add_definitions(-D_SCL_SECURE_NO_WARNINGS) + endif(MSVC) + if (WIN32) + add_definitions(-D_WIN32_WINNT=0x0501) + endif(WIN32) + include_directories(${Boost_INCLUDE_DIRS}) + enable_testing() + add_subdirectory(libs/network/src) + if (CPP-NETLIB_BUILD_TESTS) + add_subdirectory(libs/network/test) + endif (CPP-NETLIB_BUILD_TESTS) + if (CPP-NETLIB_BUILD_EXPERIMENTS) + add_subdirectory(libs/network/experiment) + endif (CPP-NETLIB_BUILD_EXPERIMENTS) + if (NOT MSVC AND CPP-NETLIB_BUILD_TESTS) + add_subdirectory(libs/mime/test) + endif(NOT MSVC AND CPP-NETLIB_BUILD_TESTS) + if (CPP-NETLIB_BUILD_EXAMPLES) + add_subdirectory(libs/network/example) + endif (CPP-NETLIB_BUILD_EXAMPLES) +endif(Boost_FOUND) + +if (MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") +endif() + +enable_testing() + +install(DIRECTORY boost DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +### +## Export Targets +# (so cpp-netlib can be easily used by other CMake projects) +# [see http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file] + +# Add all targets to the build-tree export set +export(TARGETS cppnetlib-client-connections cppnetlib-server-parsers cppnetlib-uri + FILE "${PROJECT_BINARY_DIR}/cppnetlibTargets.cmake") +# Export the package for use from the build-tree +# (this registers the build-tree with a global CMake-registry) +export(PACKAGE cppnetlib) +# Create the cppnetlibConfig.cmake and cppnetlibConfigVersion files +file(RELATIVE_PATH REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}" + "${CMAKE_INSTALL_FULL_INCLUDEDIR}") +# ... for the build tree +set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" ${Boost_INCLUDE_DIRS}) +configure_file(cppnetlibConfig.cmake.in + "${PROJECT_BINARY_DIR}/cppnetlibConfig.cmake" @ONLY) +# ... for the install tree +set(CONF_INCLUDE_DIRS "\${CPPNETLIB_CMAKE_DIR}/${REL_INCLUDE_DIR}") +set(CONF_INCLUDE_DIRS ${CONF_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) +configure_file(cppnetlibConfig.cmake.in + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cppnetlibConfig.cmake" @ONLY) +# ... for both +configure_file(cppnetlibConfigVersion.cmake.in + "${PROJECT_BINARY_DIR}/cppnetlibConfigVersion.cmake" @ONLY) +# Install the cppnetlibConfig.cmake and cppnetlibConfigVersion.cmake +install(FILES + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cppnetlibConfig.cmake" + "${PROJECT_BINARY_DIR}/cppnetlibConfigVersion.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}" + COMPONENT dev) +# Install the export set for use with the install-tree +install(EXPORT cppnetlibTargets + DESTINATION "${INSTALL_CMAKE_DIR}" + COMPONENT dev) diff --git a/cpp-netlib/LICENSE_1_0.txt b/cpp-netlib/LICENSE_1_0.txt new file mode 100644 index 00000000..36b7cd93 --- /dev/null +++ b/cpp-netlib/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/cpp-netlib/RATIONALE.txt b/cpp-netlib/RATIONALE.txt new file mode 100644 index 00000000..c9e8960f --- /dev/null +++ b/cpp-netlib/RATIONALE.txt @@ -0,0 +1,64 @@ +C++ Networking Library +Goals and Scope + + +Objectives +---------- + + o Develop a high quality, portable, easy to use C++ networking library + + o Enable users to easily extend the library + + o Lower the barrier to entry for cross-platform network-aware C++ + applications + + +Goals +----- + + * Implement a simple message implementation which can be used in + network protocol-specific routines for inter-operability and + to provide a generic interface to manipulating network-oriented + messages. + + * Implement easy to use protocol client libraries such as (but not + limited to): + + - HTTP 1.0/1.1 + - (E)SMTP + - SNMP + - ICMP + + * Implement an easy to embed HTTP server container type that supports + most modern HTTP 1.1 features. + + * Implement an efficient easy to use URI class/parser. + + * Implement a fully compliant cross-platform asynchronous DNS resolver + either as a wrapper to external (C) libraries, or as hand-rolled + implementation. + + * Implement a MIME handler which builds message objects from either + data retrieved from the network or other sources and create + text/binary representations from existing message objects intended + for transport over the network. + + +Scope +----- + + * The library will provide a generic message class which is intended + to be the common message type used by the protocol libraries. + + * The library will only contain client implementations for the various + supported protocols. + + * The library will use only STL and Boost C++ library components, + utilities, and libraries throughout the implementation. + + * The library will strive to use C++ templates and template + metaprogramming techniques in order to not require the building of + external shared/static libraries. In other words, the library will be + header-only and compliant with the C++ standard. + + diff --git a/cpp-netlib/README.rst b/cpp-netlib/README.rst new file mode 100644 index 00000000..b0f21976 --- /dev/null +++ b/cpp-netlib/README.rst @@ -0,0 +1,160 @@ +C++ Network Library +=================== + +Introduction +------------ + +cpp-netlib is a collection of network related routines/implementations +geared towards providing a robust cross-platform networking library. +cpp-netlib offers the following implementations: + + * Common Message Type -- A generic message type which can be used + to encapsulate and store message related information, used by all + network implementations as the primary means of data exchange. + * Network protocol message parsers -- A collection of parsers which + generate message objects from strings. + * Adapters and Wrappers -- A collection of Adapters and wrappers aimed + towards making the message type STL friendly. + * Network protocol client and server implementations -- A collection + of network protocol implementations that include embeddable client + and server types. + +This library is released under the Boost Software License (please see +http://boost.org/LICENSE_1_0.txt or the accompanying LICENSE_1_0.txt file +for the full text. + +Downloading cpp-netlib +---------------------- + +You can find official release packages of the library at:: + + http://github.com/cpp-netlib/cpp-netlib/downloads + +Building and Installing +----------------------- + +Building with CMake +~~~~~~~~~~~~~~~~~~~ + +To build the libraries and run the tests with CMake, you will need to +have CMake version 2.8 or higher installed appropriately in your +system. + +:: + + $ cmake --version + cmake version 2.8.1 + +Inside the cpp-netlib directory, you can issue the following statements to +configure and generate the Makefiles, and build the tests:: + + $ cd ~/cpp-netlib # we're assuming it's where cpp-netlib is + $ cmake -DCMAKE_BUILD_TYPE=Debug \ + > -DCMAKE_C_COMPILER=clang \ + > -DCMAKE_CXX_COMPILER=clang++ \ + > . + +Once CMake is done with generating the Makefiles and configuring the project, +you can now build the tests and run them:: + + $ cd ~/cpp-netlib + $ make + $ make test + +If for some reason some of the tests fail, you can send the files in +``Testing/Temporary/`` as attachments to the cpp-netlib `developers mailing +list`_. + +.. _`developers mailing list`: cpp-netlib@googlegroups.com + +Building with Boost.Build +~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you don't already have Boost.Build set up on your system, follow the steps +indicated in the Boost Getting Started Guide [#]_ -- you will particularly want +to copy the ``bjam`` executable to a directory that is already in your ``PATH`` +so that you don't have to go hunting for it all the time. A good place to put it +is in ``/usr/local/bin``. + +.. [#] http://www.boost.org/doc/libs/release/more/getting_started/ + +Building and running the tests can be as simple as doing the following:: + + $ cd ~/cpp-netlib + $ bjam + +Doing this will already build all the tests and run them as they are built. In +case you encounter any problems and would like to report it to the developers, +please do the following:: + + $ cd ~/cpp-netlib + $ bjam 2>&1 >build-test.log + +And then attach the ``build-test.log`` file to the email you will send to the +cpp-netlib `developers mailing list`_. + +.. _`developers mailing list`: cpp-netlib@googlegroups.com + +Running Tests +------------- + +If you want to run the tests that come with cpp-netlib, there are a few things +you will need. These are: + + * A compiler (GCC 4.x, Clang 2.8, MSVC 2008) + * A build tool (CMake [#]_ recommended, Boost.Build also an option) + * OpenSSL headers (optional) + +.. note:: This assumes that you have cpp-netlib at the top-level of + your home directory. + [#] http://www.cmake.org/ + +Hacking on cpp-netlib +--------------------- + +cpp-netlib is being developed with the git_ distributed SCM system. +cpp-netlib is hosted on GitHub_ following the GitHub recommended practice of +forking the repository and submitting pull requests to the source repository. +You can read more about the forking_ process and submitting `pull requests`_ if +you're not familiar with either process yet. + +.. _git: http://git-scm.com/ +.. _GitHub: http://github.com/ +.. _forking: http://help.github.com/forking/ +.. _`pull requests`: http://help.github.com/pull-requests/ + +Because cpp-netlib is released under the `Boost Software License`_ it is +recommended that any file you make changes to bear your copyright notice +alongside the original authors' copyright notices on the file. Typically the +copyright notices are at the top of each file in the project. + +.. _`Boost Software License`: http://www.boost.org/LICENSE_1_0.txt + +At the time of writing, there are no coding conventions being followed but if +you write in the general style that is already existing in the project that +would be greatly appreciated. Copious amounts of comments will be called out, +but code that is not self-explanatory typically at least requires a rationale +documentation in comments explaining "why" the code is written that way. + +The main "upstream" repository is the one hosted by the original maintainer of +the project (Dean Michael Berris) at http://github.com/mikhailberis/cpp-netlib. +The "official" release repository is maintained at +http://github.com/cpp-netlib/cpp-netlib -- which is a fork of the upstream +repository. It is recommended that forks be made against the upstream repostory +and pull requests be submitted against the upstream repository so that patches +and other implementations can be curated by the original maintainer. + +Contact and Support +------------------- + +In case you have any questions or would like to make feature requests, you can +contact the development team through the `developers mailing list`_ +or by filing issues at http://github.com/cpp-netlib/cpp-netlib/issues. + +.. _`developers mailing list`: cpp-netlib@googlegroups.com + +You can reach the maintainers of the project through:: + + Dean Michael Berris (dberris@google.com) + + Glyn Matthews (glyn.matthews@gmail.com) diff --git a/cpp-netlib/boost/mime.hpp b/cpp-netlib/boost/mime.hpp new file mode 100644 index 00000000..e45d59c1 --- /dev/null +++ b/cpp-netlib/boost/mime.hpp @@ -0,0 +1,832 @@ +// +// Copyright Marshall Clow 2009-2010 +// 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 _BOOST_MIME_HPP +#define _BOOST_MIME_HPP + +#include +#include +#include +#include + +#include +#include +#include // pulls in all of Phoenix +#include +#include + +#include +#include +#include +#include + +// #define DUMP_MIME_DATA 1 + +namespace boost { +namespace mime { + +// Errors are reported using this exception class +class mime_parsing_error : public std::runtime_error { + public: + explicit mime_parsing_error(const std::string &msg) + : std::runtime_error(msg) {} +}; + +template +class basic_mime; + +namespace detail { + +static const char *k_crlf = "\015\012"; +static const char *k_package_name = "Proposed.Boost.Mime"; +static const char *k_package_version = "0.1"; +static const char *k_content_type_header = "Content-Type"; +static const char *k_mime_version_header = "Mime-Version"; + +struct default_types { + typedef std::string string_type; + // typedef std::pair < std::string, string_type > header_type; + typedef std::vector body_type; +}; + +template +struct find_mime_header { + find_mime_header(const char *str) : searchFor(str) {} + bool operator()(const std::pair &val) const { + return boost::iequals(val.first, searchFor); + } + + private: + const char *searchFor; +}; + +#ifdef DUMP_MIME_DATA +struct tracer { + tracer(const char *fn) : fn_(fn) { std::cout << "->" << fn_ << std::endl; } + ~tracer() { std::cout << "<-" << fn_ << std::endl; } + const char *fn_; +}; +#else +struct tracer { + tracer(const char *) {} + ~tracer() {} +}; +#endif + +// Parsing a Content-Type header +typedef std::pair phrase_t; +typedef std::vector phrase_container_t; +struct mime_content_type { + std::string type; + std::string sub_type; + phrase_container_t phrases; +}; + +namespace qi = boost::spirit::qi; +namespace phx = boost::phoenix; +using boost::spirit::_val; +using boost::spirit::_1; + +template +struct mime_header_parser : qi::grammar { + mime_header_parser() : mime_header_parser::base_type(mime_headerList) { + mime_headerList = *(mime_header) >> crlf; + mime_header = token >> qi::lit(':') >> value >> crlf; + token = qi::char_("a-zA-Z") >> *qi::char_("a-zA-Z_0-9\\-"); + + // In Classifieds/000001, a header begins with a CRLF + value = (valuePart[_val = _1] | qi::eps) >> + *(valueCont[_val += "\015\012" + _1]); + valueCont = crlf >> contWS[_val += _1] >> valuePart[_val += _1]; + valuePart = +qi::char_("\t -~"); + + contWS = +qi::char_(" \t"); + crlf = qi::lit(k_crlf); + + /* mime_headerList.name("mime-header-list"); + mime_header.name ("mime-header"); + token.name ("mime-token"); + valuePart.name ("mime-value-part"); + value.name ("mime-value"); + + qi::on_error ( mime_headerList, + std::cout + << phoenix::val("Error! Expecting ") + << qi::labels::_4 + << phoenix::val(" here: \"") + << phoenix::construct(qi::labels::_3, + qi::labels::_2) + << phoenix::val("\"") + << std::endl + ); + */ + } + + qi::rule mime_headerList; + qi::rule mime_header; + qi::rule token, value, valueCont, valuePart, contWS; + qi::rule crlf; +}; + +template +static Container read_headers(Iterator &begin, Iterator end) { + tracer t(__func__); + Container retVal; + + mime_header_parser mh_parser; + bool b = qi::parse(begin, end, mh_parser, retVal); + if (!b) throw mime_parsing_error("Failed to parse headers"); + +#ifdef DUMP_MIME_DATA + std::cout << "******Headers*******" << std::endl; + for (typename Container::const_iterator iter = retVal.begin(); + iter != retVal.end(); ++iter) { + std::string val = iter->second; + size_t idx; + while (std::string::npos != (idx = val.find(k_crlf))) + val.replace(idx, std::strlen(k_crlf), "\n"); + std::cout << iter->first << ": " << val << std::endl; + } + std::cout << std::endl << "******Headers*******" << std::endl; +#endif + + return retVal; +} + +// The structure of a Content-Type mime header is taken from RFC 2045 +// http://www.ietf.org/rfc/rfc2045.txt, section 5.1 + +template +struct mime_content_type_parser : qi::grammar { + mime_content_type_parser() + : mime_content_type_parser::base_type(content_type_header) { + content_type_header = *qi::lit(' ') >> part >> '/' >> sub_part >> *phrase; + + part = token | extension_token; + sub_part = token | extension_token; + + phrase = qi::lit(';') >> +ws >> attribute >> '=' >> value >> *ws; + ws = qi::char_(" \t") | line_sep | comment; + line_sep = qi::lexeme[qi::lit(k_crlf)]; + + attribute = token.alias(); + value = token | quoted_string; + + token = +(qi::char_(" -~") - qi::char_(" ()<>@,;:\\\"/[]?=")); + comment = qi::lit('(') >> +(qi::char_(" -~") - ')') >> qi::lit(')'); + quoted_string = qi::lit('"') >> +(qi::char_(" -~") - '"') >> qi::lit('"'); + extension_token = qi::char_("Xx") >> qi::lit('-') >> token; + } + + qi::rule content_type_header; + qi::rule phrase; + qi::rule part, sub_part, token, attribute, value, + quoted_string, extension_token; + qi::rule ws, line_sep, comment; +}; + +template +mime_content_type parse_content_type(const string_type &theHeader) { + tracer t(__func__); + mime_content_type retVal; + typename string_type::const_iterator first = theHeader.begin(); + mime_content_type_parser ct_parser; + bool b = qi::parse(first, theHeader.end(), ct_parser, retVal); + if (!b) throw mime_parsing_error("Failed to parse the 'Content-Type' header"); + + return retVal; +} + +template +static string_type get_ct_value(const string_type &ctString, const char *key) { + tracer t(__func__); + mime_content_type mc = parse_content_type(ctString); + for (phrase_container_t::const_iterator iter = mc.phrases.begin(); + iter != mc.phrases.end(); ++iter) + if (boost::iequals(iter->first, key)) return iter->second; + + throw std::runtime_error( + str(boost::format("Couldn't find Content-Type phrase (%s)") % key)); +} + +// Replace this with a spirit thing later. +// we're looking for '; boundary="".*' +std::string get_boundary(const std::string &ctString) { + tracer t(__func__); + return get_ct_value(ctString, "boundary"); +} + +// Read the body of a multipart +// Return a Container of containers, where the first is the actual +// body, +// and the rest are the sub-parts. +// Note that the body of the multipart can be empty. +// If this is the case, then the first separator need not have a crlf + +// if the marker is "abcde", we could have: +// Note that the separators are really CRLF--abcdeCRLF and +// CRLF--abcde--CRLF +// +// multipart body +// --abcde +// sub part #1 +// --abcde +// sub part #2 +// --abcde-- +// +// ** or ** +// In this case, the first separator is --abcdeCRLF +// +// --abcde (no multipart body!) +// sub part #1 +// --abcde +// sub part #2 +// --abcde-- + +typedef std::vector sub_part_t; +typedef std::vector sub_parts_t; + +template +struct multipart_body_type { + bool prolog_is_missing; + bodyContainer body_prolog; + sub_parts_t sub_parts; + bodyContainer body_epilog; +}; + +// Parse a mulitpart body. +// Either "--boundaryCRLF" -- in which case the body is empty +// or "CRLF--boundaryCRLF" -- in which +// case we return the sequence +// +// I am deliberately not checking for a termination separator here +template +struct multipart_body_parser : qi::grammar { + multipart_body_parser(const std::string &boundary, bool &isMissing) + : multipart_body_parser::base_type(mimeBody), m_is_missing(isMissing) { + m_is_missing = false; + // Thanks to Michael Caisse for the hint to get this working + mimeBody %= + bareSep[phx::ref(m_is_missing) = true] | (+(qi::char_ - sep) >> sep); + bareSep = qi::lit("--") >> boundary >> crlf; + sep = crlf >> bareSep; + crlf = qi::lit(k_crlf); + } + + bool &m_is_missing; + qi::rule mimeBody; + qi::rule bareSep, sep, crlf; +}; + +// Break up a multi-part into its' constituent sub parts. +template +struct multipart_part_parser : qi::grammar { + multipart_part_parser(const std::string &boundary) + : multipart_part_parser::base_type(mimeParts) { + mimeParts = (+(qi::char_ - sep) % (sep >> crlf)) > terminator; + sep = crlf >> qi::lit("--") >> boundary; + terminator = sep >> qi::lit("--") >> crlf; + crlf = qi::lit(k_crlf); + } + qi::rule mimeParts; + qi::rule sep, terminator, crlf; +}; + +template +static void read_multipart_body(Iterator &begin, Iterator end, + multipart_body_type &mp_body, + const std::string &separator) { + tracer t(__func__); + typedef bodyContainer innerC; + innerC mpBody; + multipart_body_parser mb_parser(separator, + mp_body.prolog_is_missing); + if (!qi::parse(begin, end, mb_parser, mp_body.body_prolog)) + throw mime_parsing_error("Failed to parse mime body(1)"); + + multipart_part_parser mp_parser(separator); + if (!qi::parse(begin, end, mp_parser, mp_body.sub_parts)) + throw mime_parsing_error("Failed to parse mime body(2)"); + std::copy(begin, end, std::back_inserter(mp_body.body_epilog)); + +#ifdef DUMP_MIME_DATA + std::cout << std::endl << ">>****Multipart Body*******" << std::endl; + std::cout << str(boost::format( + "Body size %d, sub part count = %d, trailer size " + "= %d %s") % + mp_body.body_prolog.size() % mp_body.sub_parts.size() % + mp_body.body_epilog.size() % + (mp_body.prolog_is_missing ? "(missing)" : "")) << std::endl; + std::cout << std::endl << "****** Multipart Body Prolog *******" << std::endl; + std::copy(mp_body.body_prolog.begin(), mp_body.body_prolog.end(), + std::ostream_iterator(std::cout)); + std::cout << std::endl << "****** Multipart Body Epilog *******" << std::endl; + std::copy(mp_body.body_epilog.begin(), mp_body.body_epilog.end(), + std::ostream_iterator(std::cout)); + std::cout << std::endl << "<<****Multipart Body*******" << std::endl; +#endif +} + +template +static Container read_simplepart_body(Iterator &begin, Iterator end) { + tracer t(__func__); + Container retVal; + std::copy(begin, end, std::back_inserter(retVal)); + +#ifdef DUMP_MIME_DATA + std::cout << std::endl << ">>****SinglePart Body*******" << std::endl; + std::cout << str(boost::format("Body size %d") % retVal.size()) << std::endl; + std::copy(retVal.begin(), retVal.end(), + std::ostream_iterator(std::cout)); + std::cout << std::endl << "<<****SinglePart Body*******" << std::endl; +#endif + return retVal; +} + +// FIXME: Need to break the headers at 80 chars... +template +void write_headers(std::ostream &out, const headerList &headers) { + if (headers.size() > 0) { + for (typename headerList::const_iterator iter = headers.begin(); + iter != headers.end(); ++iter) + out << iter->first << ':' << iter->second << detail::k_crlf; + } + out << detail::k_crlf; +} + +template +void write_body(std::ostream &out, const bodyContainer &body) { + std::copy(body.begin(), body.end(), std::ostream_iterator(out)); +} + +inline void write_boundary(std::ostream &out, std::string boundary, bool isLast, + bool leadingCR = true) { + if (leadingCR) out << detail::k_crlf; + out << "--" << boundary; + if (isLast) out << "--"; + out << detail::k_crlf; +} + +template +static boost::shared_ptr > parse_mime( + Iterator &begin, Iterator end, + const char *default_content_type = "text/plain"); +} + +template +class basic_mime { + public: + typedef enum { + simple_part, + multi_part, + message_part + } part_kind; + // Types for headers + typedef typename traits::string_type string_type; + typedef std::pair headerEntry; + typedef std::list headerList; + typedef typename headerList::iterator headerIter; + typedef typename headerList::const_iterator constHeaderIter; + + // Types for the parts + typedef boost::shared_ptr mimePtr; + typedef std::vector partList; + typedef typename partList::iterator partIter; + typedef typename partList::const_iterator constPartIter; + + // Type for the body + typedef typename traits::body_type bodyContainer; + typedef boost::shared_ptr mimeBody; + + // ----------------------------------------------------------- + // Constructors, destructor, assignment, and swap + // ----------------------------------------------------------- + + basic_mime(const char *type, const char *subtype) + : m_body_prolog_is_missing(false), + m_body(new bodyContainer), + m_body_epilog(new bodyContainer) { + if (NULL == type || NULL == subtype || 0 == std::strlen(type) || + 0 == std::strlen(subtype)) + throw std::runtime_error( + "Can't create a mime part w/o a type or subtype"); + + // We start with just two headers, "Content-Type:" and "Mime-Version" + // Everything else is optional. + m_part_kind = part_kind_from_string_pair(type, subtype); + std::string ctString = str(boost::format("%s/%s") % type % subtype); + set_header_value(detail::k_content_type_header, ctString); + set_header_value(detail::k_mime_version_header, + str(boost::format("1.0 (%s %s)") % detail::k_package_name % + detail::k_package_version)); + } + + basic_mime(const headerList &theHeaders, + const string_type &default_content_type) + : m_body_prolog_is_missing(false), + m_body(new bodyContainer), + m_body_epilog(new bodyContainer), + m_default_content_type(default_content_type) { + string_type ct = m_default_content_type; + + constHeaderIter found = std::find_if( + theHeaders.begin(), theHeaders.end(), + detail::find_mime_header(detail::k_content_type_header)); + if (found != theHeaders.end()) ct = found->second; + + detail::mime_content_type mct = detail::parse_content_type(ct); + m_part_kind = part_kind_from_string_pair(mct.type, mct.sub_type); + m_headers = theHeaders; + } + + basic_mime(const basic_mime &rhs) + : m_part_kind(rhs.m_part_kind), + m_headers(rhs.m_headers), + m_body_prolog_is_missing(rhs.m_body_prolog_is_missing), + m_body(new bodyContainer(*rhs.m_body)), + m_body_epilog(new bodyContainer(*rhs.m_body_epilog)), + /* m_subparts ( rhs.m_subparts ), */ m_default_content_type( + rhs.m_default_content_type) { + // Copy the parts -- not just the shared pointers + for (typename partList::const_iterator iter = rhs.subpart_begin(); + iter != rhs.subpart_end(); ++iter) + m_subparts.push_back(mimePtr(new basic_mime(**iter))); + } + + // Simple, copy constructor-based assignment + // If this is not efficient enough, then I can optimize it later + basic_mime &operator=(const basic_mime &rhs) { + basic_mime temp(rhs); + this->swap(temp); + return *this; + } + + void swap(basic_mime &rhs) throw() { + std::swap(m_part_kind, rhs.m_part_kind); + std::swap(m_headers, rhs.m_headers); + std::swap(m_body_prolog_is_missing, rhs.m_body_prolog_is_missing); + std::swap(m_body, rhs.m_body); + std::swap(m_body_epilog, rhs.m_body_epilog); + std::swap(m_subparts, rhs.m_subparts); + std::swap(m_default_content_type, rhs.m_default_content_type); + } + + ~basic_mime() {} + + // What kind of part is this (simple, multi, message) + part_kind get_part_kind() const { return m_part_kind; } + + // Sub-part information + // FIXME: Need some error checking here + // No sub-parts for simple parts, for example. + size_t part_count() const { return m_subparts.size(); } + + boost::shared_ptr operator[](std::size_t idx) const { + check_subpart_index(idx); + return m_subparts[idx]; + } + + void append_part(boost::shared_ptr newPart) { + check_subpart_append(); + m_subparts.push_back(newPart); + } + + partIter subpart_begin() { return m_subparts.begin(); } + partIter subpart_end() { return m_subparts.end(); } + constPartIter subpart_begin() const { return m_subparts.begin(); } + constPartIter subpart_end() const { return m_subparts.end(); } + + // Reading the raw headers + headerIter header_begin() { return m_headers.begin(); } + headerIter header_end() { return m_headers.end(); } + constHeaderIter header_begin() const { return m_headers.begin(); } + constHeaderIter header_end() const { return m_headers.end(); } + + // ----------------------------------------------------------- + // Header manipulation + // ----------------------------------------------------------- + + // The 'tag' part of the header is still a std::string + bool header_exists(const char *key) const { + return header_end() != find_header(key); + } + + string_type header_value(const char *key) const { + constHeaderIter found = find_header(key); + if (found == header_end()) + throw std::runtime_error("'header_value' not found"); + return found->second; + } + + void set_header_value(const char *key, const string_type &value, + bool replace = false) { + if (!replace) + m_headers.push_back(std::make_pair(std::string(key), value)); + else { + headerIter found = find_header(key); + if (found == m_headers.end()) + throw std::runtime_error("'header_value' not found - can't replace"); + found->second = value; + } + } + + string_type get_content_type_header() const { + constHeaderIter found = find_header(detail::k_content_type_header); + return found != header_end() ? found->second : m_default_content_type; + } + + string_type get_content_type() const { + detail::mime_content_type mct = + detail::parse_content_type(get_content_type_header()); + return string_type(mct.type) + '/' + mct.sub_type; + } + + // Special purpose helper routine + void append_phrase_to_content_type(const char *key, + const string_type &value) { + headerIter found = find_header(detail::k_content_type_header); + + // Create a Content-Type header if there isn't one + if (m_headers.end() == found) { + m_headers.push_back(std::make_pair( + std::string(detail::k_content_type_header), m_default_content_type)); + found = find_header(detail::k_content_type_header); + } + + detail::mime_content_type mct = detail::parse_content_type(found->second); + detail::phrase_container_t::const_iterator p_found = + std::find_if(mct.phrases.begin(), mct.phrases.end(), + detail::find_mime_header(key)); + if (p_found != mct.phrases.end()) + throw std::runtime_error("phrase already exists"); + found->second += str(boost::format("; %s=\"%s\"") % key % value); + } + + // Body get/set methods + mimeBody body() const { return m_body; } + mimeBody body_prolog() const { return m_body; } + mimeBody body_epilog() const { return m_body_epilog; } + + std::size_t body_size() const { return m_body->size(); } + + template + void set_body(Iterator begin, Iterator end) { + bodyContainer temp; + std::copy(begin, end, std::back_inserter(temp)); + m_body->swap(temp); + } + + void set_body(const char *contents, size_t sz) { + set_body(contents, contents + sz); + } + void set_body(std::istream &in) { + set_body(std::istream_iterator(in), std::istream_iterator()); + } + void set_body(const bodyContainer &new_body) { *m_body = new_body; } + + void set_multipart_prolog_is_missing(bool isMissing) { + m_body_prolog_is_missing = isMissing; + } + void set_body_prolog(const bodyContainer &new_body_prolog) { + *m_body = new_body_prolog; + } + void set_body_epilog(const bodyContainer &new_body_epilog) { + *m_body_epilog = new_body_epilog; + } + + // ----------------------------------------------------------- + // Output + // ----------------------------------------------------------- + void stream_out(std::ostream &out) { // called by operator << + if (m_part_kind == simple_part) { + detail::write_headers(out, m_headers); + detail::write_body(out, *m_body); + } else if (m_part_kind == message_part) { + if (m_subparts.size() != 1) + throw std::runtime_error( + "message part w/wrong number of sub-parts - should be 1"); + + detail::write_headers(out, m_headers); + m_subparts[0]->stream_out(out); + } else { // multi-part + // Find or invent a boundary string + std::string boundary; + try { + boundary = detail::get_boundary(get_content_type_header()); + } + catch (std::runtime_error &) { + // FIXME: Make boundary strings (more?) unique + boundary = str(boost::format("------=_NextPart-%s.%08ld") % + detail::k_package_name % std::clock()); + append_phrase_to_content_type("boundary", boundary); + } + + // If the body prolog is missing, we don't want a CRLF on the front + // of the first sub-part. + // Note that there's a (subtle) difference between an zero length + // body and a missing one. + // See the comments in the parser code for more information. + detail::write_headers(out, m_headers); + bool writeCR = body_prolog()->size() > 0 || !m_body_prolog_is_missing; + detail::write_body(out, *body_prolog()); + for (typename partList::const_iterator iter = m_subparts.begin(); + iter != m_subparts.end(); ++iter) { + detail::write_boundary(out, boundary, false, writeCR); + (*iter)->stream_out(out); + writeCR = true; + } + detail::write_boundary(out, boundary, true); + detail::write_body(out, *body_epilog()); + } + // out << detail::k_crlf; + } + + // Build a simple mime part + template + static basic_mime make_simple_part(const char *type, const char *subtype, + Iterator begin, Iterator end) { + basic_mime retval(type, subtype); + retval.set_body(begin, end); + return retval; + } + + // Build a mime part from a pair of iterators + template + static boost::shared_ptr > parse_mime(Iterator &begin, + Iterator end) { + return detail::parse_mime(begin, end); + } + + // Build a mime part from a stream + static boost::shared_ptr parse_mime(std::istream &in) { + boost::spirit::istream_iterator first(in); + boost::spirit::istream_iterator last; + return parse_mime(first, last); + } + + private: + basic_mime(); // Can't create a part w/o a type + + headerIter find_header(const char *key) { + return std::find_if(header_begin(), header_end(), + detail::find_mime_header(key)); + } + + constHeaderIter find_header(const char *key) const { + return std::find_if(header_begin(), header_end(), + detail::find_mime_header(key)); + } + + static part_kind part_kind_from_string_pair(const std::string &type, + const std::string &sub_type) { + if (boost::iequals(type, "multipart")) return multi_part; + + part_kind retVal = simple_part; + // I expect that this will get more complicated as time goes on.... + // + // message/delivery-status is a simple type. + // RFC 3464 defines message/delivery-status + // + // The body of a message/delivery-status consists of one or more + // "fields" formatted according to the ABNF of RFC 822 header + //"fields" + // (see [RFC822]). + if (boost::iequals(type, "message")) + if (!boost::iequals(sub_type, "delivery-status")) retVal = message_part; + return retVal; + } + + void check_subpart_index(size_t idx) const { + if (get_part_kind() == simple_part) + throw std::runtime_error("Simple Mime parts don't have sub-parts"); + else if (get_part_kind() == multi_part) { + if (idx >= m_subparts.size()) + throw std::runtime_error( + str(boost::format( + "Trying to access part %d (of %d) sub-part to a " + "multipart/xxx mime part") % + idx % m_subparts.size())); + } else { // message-part + if (get_part_kind() == message_part) + if (m_subparts.size() > 1) + throw std::runtime_error( + "How did a message/xxx mime parts get more than one " + "sub-part?"); + + if (idx >= m_subparts.size()) + throw std::runtime_error( + str(boost::format( + "Trying to access part %d (of %d) sub-part to a " + "message/xxx mime part") % + idx % m_subparts.size())); + } + } + + void check_subpart_append() const { + if (get_part_kind() == simple_part) + throw std::runtime_error("Simple Mime parts don't have sub-parts"); + else if (get_part_kind() == message_part) { + if (m_subparts.size() > 0) + throw std::runtime_error( + "Can't add a second sub-part to a message/xxx mime part"); + } + // else { /* Multi-part */ } // We can always add to a multi-part + } + + part_kind m_part_kind; + headerList m_headers; + bool m_body_prolog_is_missing; // only for multiparts + mimeBody m_body; + mimeBody m_body_epilog; // only for multiparts + partList m_subparts; // only for multiparts or message + string_type m_default_content_type; +}; + +namespace detail { + +template +static boost::shared_ptr > parse_mime( + Iterator &begin, Iterator end, const char *default_content_type) { + tracer t(__func__); + typedef typename boost::mime::basic_mime mime_part; + + shared_ptr retVal(new mime_part( + detail::read_headers(begin, end), + default_content_type)); + + std::string content_type = retVal->get_content_type(); + +#ifdef DUMP_MIME_DATA + std::cout << "Content-Type: " << content_type << std::endl; + std::cout << str(boost::format("retVal->get_part_kind () = %d") % + ((int)retVal->get_part_kind())) << std::endl; +#endif + + if (retVal->get_part_kind() == mime_part::simple_part) + retVal->set_body(detail::read_simplepart_body< + typename mime_part::bodyContainer, Iterator>(begin, end)); + else if (retVal->get_part_kind() == mime_part::message_part) { + // If we've got a message/xxxx, then there is no body, and we have + // a single + // embedded mime_part (which, of course, could be a multipart) + retVal->append_part(parse_mime(begin, end)); + } else /* multi_part */ { + // Find or invent a boundary string + std::string part_separator = + detail::get_boundary(retVal->get_content_type_header()); + const char *cont_type = boost::iequals(content_type, "multipart/digest") + ? "message/rfc822" + : "text/plain"; + + detail::multipart_body_type body_and_subParts; + detail::read_multipart_body(begin, end, body_and_subParts, part_separator); + + retVal->set_body_prolog(body_and_subParts.body_prolog); + retVal->set_multipart_prolog_is_missing( + body_and_subParts.prolog_is_missing); + for (typename sub_parts_t::const_iterator iter = + body_and_subParts.sub_parts.begin(); + iter != body_and_subParts.sub_parts.end(); ++iter) { + typedef typename sub_part_t::const_iterator iter_type; + iter_type b = iter->begin(); + iter_type e = iter->end(); + retVal->append_part(parse_mime(b, e, cont_type)); + } + retVal->set_body_epilog(body_and_subParts.body_epilog); + } + + return retVal; +} +} + +// ----------------------------------------------------------- +// +// Streaming +// +// ----------------------------------------------------------- + +template +inline std::ostream &operator<<(std::ostream &stream, + basic_mime &part) { + part.stream_out(stream); + return stream; +} + +template +inline std::ostream &operator<<(std::ostream &stream, + boost::shared_ptr > part) { + return stream << *part; +} +} +} + +BOOST_FUSION_ADAPT_STRUCT(boost::mime::detail::mime_content_type, + (std::string, type)(std::string, sub_type)( + boost::mime::detail::phrase_container_t, phrases)) + +#endif // _BOOST_MIME_HPP diff --git a/cpp-netlib/boost/network.hpp b/cpp-netlib/boost/network.hpp new file mode 100644 index 00000000..79399894 --- /dev/null +++ b/cpp-netlib/boost/network.hpp @@ -0,0 +1,17 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_HPP__ +#define __NETWORK_HPP__ + +// Include all headers in network/ +// Author: Dean Michael Berris +// Date: May 20, 2007 + +#include // message type implementation +#include // protocols implementation + +#endif // __NETWORK_HPP__ diff --git a/cpp-netlib/boost/network/constants.hpp b/cpp-netlib/boost/network/constants.hpp new file mode 100644 index 00000000..6aa7e45d --- /dev/null +++ b/cpp-netlib/boost/network/constants.hpp @@ -0,0 +1,140 @@ +#ifndef BOOST_NETWORK_CONSTANTS_HPP_20100808 +#define BOOST_NETWORK_CONSTANTS_HPP_20100808 + +// Copyright 2010 (C) Dean Michael Berris +// 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) + +#include +#include +#include + +namespace boost { +namespace network { + +namespace impl { +template +struct constants_narrow { + + static char const* crlf() { + static char crlf_[] = {'\r', '\n', 0}; + return crlf_; + } + + static char const* dot() { + static char dot_[] = {'.', 0}; + return dot_; + } + + static char dot_char() { return '.'; } + + static char const* http_slash() { + static char http_slash_[] = {'H', 'T', 'T', 'P', '/', 0}; + return http_slash_; + } + + static char const* space() { + static char space_[] = {' ', 0}; + return space_; + } + + static char space_char() { return ' '; } + + static char const* slash() { + static char slash_[] = {'/', 0}; + return slash_; + } + + static char slash_char() { return '/'; } + + static char const* host() { + static char host_[] = {'H', 'o', 's', 't', 0}; + return host_; + } + + static char const* colon() { + static char colon_[] = {':', 0}; + return colon_; + } + + static char colon_char() { return ':'; } + + static char const* accept() { + static char accept_[] = {'A', 'c', 'c', 'e', 'p', 't', 0}; + return accept_; + } + + static char const* default_accept_mime() { + static char mime_[] = {'*', '/', '*', 0}; + return mime_; + } + + static char const* accept_encoding() { + static char accept_encoding_[] = {'A', 'c', 'c', 'e', 'p', 't', '-', 'E', + 'n', 'c', 'o', 'd', 'i', 'n', 'g', 0}; + return accept_encoding_; + } + + static char const* default_accept_encoding() { + static char default_accept_encoding_[] = { + 'i', 'd', 'e', 'n', 't', 'i', 't', 'y', ';', 'q', '=', + '1', '.', '0', ',', ' ', '*', ';', 'q', '=', '0', 0}; + return default_accept_encoding_; + } + + static char const* user_agent() { + static char user_agent_[] = {'U', 's', 'e', 'r', '-', 'A', + 'g', 'e', 'n', 't', 0}; + return user_agent_; + } + + static char const* cpp_netlib_slash() { + static char cpp_netlib_slash_[] = {'c', 'p', 'p', '-', 'n', 'e', + 't', 'l', 'i', 'b', '/', 0}; + return cpp_netlib_slash_; + } + + static char question_mark_char() { return '?'; } + + static char hash_char() { return '#'; } + + static char const* connection() { + static char connection_[] = {'C', 'o', 'n', 'n', 'e', 'c', + 't', 'i', 'o', 'n', 0}; + return connection_; + } + + static char const* close() { + static char close_[] = {'C', 'l', 'o', 's', 'e', 0}; + return close_; + } + + static char const* https() { + static char https_[] = "https"; + return https_; + } +}; + +template +struct constants_wide { + + static wchar_t const* https() { + static wchar_t https_[] = L"https"; + return https_; + } +}; +} + +template +struct constants + : mpl::if_< + is_default_string, impl::constants_narrow, + typename mpl::if_, impl::constants_wide, + unsupported_tag >::type>::type {}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_CONSTANTS_HPP_20100808 diff --git a/cpp-netlib/boost/network/detail/debug.hpp b/cpp-netlib/boost/network/detail/debug.hpp new file mode 100644 index 00000000..093ca551 --- /dev/null +++ b/cpp-netlib/boost/network/detail/debug.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_NETWORK_DEBUG_HPP_20110410 +#define BOOST_NETWORK_DEBUG_HPP_20110410 + +// (c) Copyright 2011 Dean Michael Berris. +// 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) + +/** BOOST_NETWORK_MESSAGE is a debugging macro used by cpp-netlib to + print out network-related errors through standard error. This is + only useful when BOOST_NETWORK_DEBUG is turned on. Otherwise + the macro amounts to a no-op. +*/ +#ifdef BOOST_NETWORK_DEBUG +#include +#ifndef BOOST_NETWORK_MESSAGE +#define BOOST_NETWORK_MESSAGE(msg) \ + std::cerr << "[DEBUG " << __FILE__ << ':' << __LINE__ << "]: " << msg \ + << std::endl; +#endif +#else +#ifndef BOOST_NETWORK_MESSAGE +#define BOOST_NETWORK_MESSAGE(msg) +#endif +#endif + +#endif /* end of include guard: BOOST_NETWORK_DEBUG_HPP_20110410 */ diff --git a/cpp-netlib/boost/network/detail/directive_base.hpp b/cpp-netlib/boost/network/detail/directive_base.hpp new file mode 100644 index 00000000..e405642e --- /dev/null +++ b/cpp-netlib/boost/network/detail/directive_base.hpp @@ -0,0 +1,34 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_DETAIL_DIRECTIVE_BASE_HPP__ +#define __NETWORK_DETAIL_DIRECTIVE_BASE_HPP__ + +/** Defines the base type from which all directives inherit + * to allow friend access to message and other types' internals. + */ +namespace boost { +namespace network { +namespace detail { + +template +struct directive_base { + typedef Tag tag; + // explicit directive_base(basic_message & message_) + // : _message(message_) + protected: + ~directive_base() {}; // can only be extended + + // mutable basic_message & _message; +}; + +} // namespace detail + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_DETAIL_DIRECTIVE_BASE_HPP__ diff --git a/cpp-netlib/boost/network/detail/wrapper_base.hpp b/cpp-netlib/boost/network/detail/wrapper_base.hpp new file mode 100644 index 00000000..12793dfe --- /dev/null +++ b/cpp-netlib/boost/network/detail/wrapper_base.hpp @@ -0,0 +1,41 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_DETAIL_WRAPPER_BASE_HPP__ +#define __NETWORK_DETAIL_WRAPPER_BASE_HPP__ + +namespace boost { +namespace network { + +namespace detail { + +template +struct wrapper_base { + explicit wrapper_base(Message& message_) : _message(message_) {}; + + protected: + ~wrapper_base() {}; // for extending only + + Message& _message; +}; + +template +struct wrapper_base_const { + explicit wrapper_base_const(Message const& message_) : _message(message_) {} + + protected: + ~wrapper_base_const() {}; // for extending only + + Message const& _message; +}; + +} // namespace detail + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_DETAIL_WRAPPER_BASE_HPP__ diff --git a/cpp-netlib/boost/network/include/http/client.hpp b/cpp-netlib/boost/network/include/http/client.hpp new file mode 100644 index 00000000..3abc042e --- /dev/null +++ b/cpp-netlib/boost/network/include/http/client.hpp @@ -0,0 +1,13 @@ +#ifndef BOOST_NETWORK_INCLUDE_HTTP_CLIENT_HPP_ +#define BOOST_NETWORK_INCLUDE_HTTP_CLIENT_HPP_ + +// Copyright 2009 Dean Michael Berris +// 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) +// +// This is the modular include file for using the HTTP Client + +#include + +#endif // BOOST_NETWORK_INCLUDE_HTTP_CLIENT_HPP_ diff --git a/cpp-netlib/boost/network/include/http/server.hpp b/cpp-netlib/boost/network/include/http/server.hpp new file mode 100644 index 00000000..021eefe0 --- /dev/null +++ b/cpp-netlib/boost/network/include/http/server.hpp @@ -0,0 +1,13 @@ +#ifndef BOOST_NETWORK_INCLUDE_HTTP_SERVER_HPP_ +#define BOOST_NETWORK_INCLUDE_HTTP_SERVER_HPP_ + +// Copyright 2010 Dean Michael Berris +// 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) +// +// This is the modular include file for using the HTTP Client + +#include + +#endif diff --git a/cpp-netlib/boost/network/include/message.hpp b/cpp-netlib/boost/network/include/message.hpp new file mode 100644 index 00000000..77d10d42 --- /dev/null +++ b/cpp-netlib/boost/network/include/message.hpp @@ -0,0 +1,14 @@ +#ifndef BOOST_NETWORK_INCLUDE_MESSAGE_HPP_ +#define BOOST_NETWORK_INCLUDE_MESSAGE_HPP_ + +// Copyright 2009 Dean Michael Berris +// 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) +// +// This is the modular include file for using the basic message type + +#include +#include + +#endif // BOOST_NETWORK_INCLUDE_MESSAGE_HPP_ diff --git a/cpp-netlib/boost/network/message.hpp b/cpp-netlib/boost/network/message.hpp new file mode 100644 index 00000000..f0519d87 --- /dev/null +++ b/cpp-netlib/boost/network/message.hpp @@ -0,0 +1,135 @@ +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_HPP__ +#define __NETWORK_MESSAGE_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +/** message.hpp + * + * This header file implements the common message type which + * all networking implementations under the boost::network + * namespace. The common message type allows for easy message + * construction and manipulation suited for networked + * application development. + */ +namespace boost { +namespace network { + +/** The common message type. + */ +template +struct basic_message { + public: + typedef Tag tag; + + typedef typename headers_container::type headers_container_type; + typedef typename headers_container_type::value_type header_type; + typedef typename string::type string_type; + + basic_message() : _headers(), _body(), _source(), _destination() {} + + basic_message(const basic_message& other) + : _headers(other._headers), + _body(other._body), + _source(other._source), + _destination(other._destination) {} + + basic_message& operator=(basic_message rhs) { + rhs.swap(*this); + return *this; + } + + void swap(basic_message& other) { + std::swap(other._headers, _headers); + std::swap(other._body, _body); + std::swap(other._source, _source); + std::swap(other._destination, _destination); + } + + headers_container_type& headers() { return _headers; } + + void headers(headers_container_type const& headers_) const { + _headers = headers_; + } + + void add_header(typename headers_container_type::value_type const& pair_) + const { + _headers.insert(pair_); + } + + void remove_header(typename headers_container_type::key_type const& key) + const { + _headers.erase(key); + } + + headers_container_type const& headers() const { return _headers; } + + string_type& body() { return _body; } + + void body(string_type const& body_) const { _body = body_; } + + string_type const& body() const { return _body; } + + string_type& source() { return _source; } + + void source(string_type const& source_) const { _source = source_; } + + string_type const& source() const { return _source; } + + string_type& destination() { return _destination; } + + void destination(string_type const& destination_) const { + _destination = destination_; + } + + string_type const& destination() const { return _destination; } + + private: + friend struct detail::directive_base; + friend struct detail::wrapper_base >; + + mutable headers_container_type _headers; + mutable string_type _body; + mutable string_type _source; + mutable string_type _destination; +}; + +template +inline void swap(basic_message& left, basic_message& right) { + // swap for ADL + left.swap(right); +} + +// Commenting this out as we don't need to do this anymore. +// BOOST_CONCEPT_ASSERT((Message +// >)); +// BOOST_CONCEPT_ASSERT((Message +// >)); +typedef basic_message message; +typedef basic_message wmessage; + +} // namespace network +} // namespace boost + +#endif // __NETWORK_MESSAGE_HPP__ diff --git a/cpp-netlib/boost/network/message/directives.hpp b/cpp-netlib/boost/network/message/directives.hpp new file mode 100644 index 00000000..11db46af --- /dev/null +++ b/cpp-netlib/boost/network/message/directives.hpp @@ -0,0 +1,36 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_DIRECTIVES_HPP__ +#define __NETWORK_MESSAGE_DIRECTIVES_HPP__ + +#include +#include +#include + +namespace boost { +namespace network { + +template +inline basic_message& operator<<(basic_message& message_, + Directive const& directive) { + directive(message_); + return message_; +} + +BOOST_NETWORK_STRING_DIRECTIVE(source, source_, message.source(source_), + message.source = source_); +BOOST_NETWORK_STRING_DIRECTIVE(destination, destination_, + message.destination(destination_), + message.destination = destination_); +BOOST_NETWORK_STRING_DIRECTIVE(body, body_, message.body(body_), + message.body = body_); + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_MESSAGE_DIRECTIVES_HPP__ diff --git a/cpp-netlib/boost/network/message/directives/detail/string_directive.hpp b/cpp-netlib/boost/network/message/directives/detail/string_directive.hpp new file mode 100644 index 00000000..33d288a7 --- /dev/null +++ b/cpp-netlib/boost/network/message/directives/detail/string_directive.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_DIRECTIVE_HPP_20100915 +#define BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_DIRECTIVE_HPP_20100915 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * + * To create your own string directive, you can use the preprocessor macro + * BOOST_NETWORK_STRING_DIRECTIVE which takes three parameters: the name of + * the directive, a name for the variable to use in the directive visitor, + * and the body to be implemented in the visitor. An example directive for + * setting the source of a message would look something like this given the + * BOOST_NETWORK_STRING_DIRECTIVE macro: + * + * BOOST_NETWORK_STRING_DIRECTIVE(source, source_, + * message.source(source_) + * , message.source=source_); + * + */ + +#ifndef BOOST_NETWORK_STRING_DIRECTIVE +#define BOOST_NETWORK_STRING_DIRECTIVE(name, value, body, pod_body) \ + template \ + struct name##_directive { \ + ValueType const& value; \ + explicit name##_directive(ValueType const& value_) : value(value_) {} \ + name##_directive(name##_directive const& other) : value(other.value) {} \ + template class Message> \ + typename enable_if, void>::type operator()( \ + Message& message) const { \ + pod_body; \ + } \ + template class Message> \ + typename enable_if >, void>::type operator()( \ + Message& message) const { \ + body; \ + } \ + }; \ + \ + template \ + inline name##_directive name(T const& input) { \ + return name##_directive(input); \ + } +#endif /* BOOST_NETWORK_STRING_DIRECTIVE */ + +#endif /* BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_DIRECTIVE_HPP_20100915 \ + */ diff --git a/cpp-netlib/boost/network/message/directives/detail/string_value.hpp b/cpp-netlib/boost/network/message/directives/detail/string_value.hpp new file mode 100644 index 00000000..8a3fa7d2 --- /dev/null +++ b/cpp-netlib/boost/network/message/directives/detail/string_value.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_VALUE_HPP_20100915 +#define BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_VALUE_HPP_20100915 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace detail { + +template +struct string_value + : mpl::if_, boost::shared_future::type>, + typename mpl::if_< + mpl::or_, is_same, + is_same >, + typename string::type, unsupported_tag >::type> {}; + +} /* detail */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_MESSAGE_DIRECTIVES_DETAIL_STRING_VALUE_HPP_20100915 */ diff --git a/cpp-netlib/boost/network/message/directives/header.hpp b/cpp-netlib/boost/network/message/directives/header.hpp new file mode 100644 index 00000000..da1f8e2a --- /dev/null +++ b/cpp-netlib/boost/network/message/directives/header.hpp @@ -0,0 +1,76 @@ + +// Copyright Dean Michael Berris 2007-2010. +// 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 __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__ +#define __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +namespace impl { + +template +struct header_directive { + + explicit header_directive(KeyType const& header_name, + ValueType const& header_value) + : _header_name(header_name), _header_value(header_value) {}; + + template + struct pod_directive { + template + static void eval(Message const& message, T1 const& key, T2 const& value) { + typedef typename Message::headers_container_type::value_type value_type; + value_type value_ = {key, value}; + message.headers.insert(message.headers.end(), value_); + } + }; + + template + struct normal_directive { + template + static void eval(Message const& message, T1 const& key, T2 const& value) { + typedef typename Message::headers_container_type::value_type value_type; + message.add_header(value_type(key, value)); + } + }; + + template + struct directive_impl + : mpl::if_, + pod_directive, normal_directive >::type {}; + + template + void operator()(Message const& msg) const { + directive_impl::eval(msg, _header_name, _header_value); + } + + private: + KeyType const& _header_name; + ValueType const& _header_value; +}; + +} // namespace impl + +template +inline impl::header_directive header(T1 const& header_name, + T2 const& header_value) { + return impl::header_directive(header_name, header_value); +} +} // namespace network +} // namespace boost + +#endif // __NETWORK_MESSAGE_DIRECTIVES_HEADER_HPP__ diff --git a/cpp-netlib/boost/network/message/directives/remove_header.hpp b/cpp-netlib/boost/network/message/directives/remove_header.hpp new file mode 100644 index 00000000..0961436a --- /dev/null +++ b/cpp-netlib/boost/network/message/directives/remove_header.hpp @@ -0,0 +1,48 @@ + +// Copyright Dean Michael Berris 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 NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP +#define NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP + +#include + +namespace boost { +namespace network { + +template +struct basic_message; + +namespace impl { +template +struct remove_header_directive { + + explicit remove_header_directive(T header_name) + : header_name_(header_name) {}; + + template + void operator()(basic_message& msg) const { + msg.headers().erase(header_name_); + } + + private: + mutable T header_name_; +}; + +} // namespace impl + +inline impl::remove_header_directive remove_header( + std::string header_name) { + return impl::remove_header_directive(header_name); +} + +inline impl::remove_header_directive remove_header( + std::wstring header_name) { + return impl::remove_header_directive(header_name); +} +} // namespace network +} // namespace boost + +#endif // NETWORK_MESSAGE_DIRECTIVES_REMOVE_HEADER_HPP diff --git a/cpp-netlib/boost/network/message/message_concept.hpp b/cpp-netlib/boost/network/message/message_concept.hpp new file mode 100644 index 00000000..6abac861 --- /dev/null +++ b/cpp-netlib/boost/network/message/message_concept.hpp @@ -0,0 +1,66 @@ + +#ifndef BOOST_NETWORK_MESSAGE_MESSAGE_CONCEPT_HPP_20100903 +#define BOOST_NETWORK_MESSAGE_MESSAGE_CONCEPT_HPP_20100903 + +// Copyright (c) Glyn Matthews 2010. +// Copyright 2010 (c) Dean Michael Berris. +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +template +struct Message : DefaultConstructible, CopyConstructible, Assignable { + typedef typename M::string_type string_type; + typedef typename M::headers_container_type headers_container_type; + + BOOST_CONCEPT_USAGE(Message) { + M message_; + swap(message, message_); + + typedef typename traits::body::type body_type; + typedef typename traits::source::type source_type; + typedef typename traits::destination::type destination_type; + + headers_container_type headers_ = headers(message); + string_type body_ = body(message); + string_type source_ = source(message); + string_type destination_ = destination(message); + + message << source(source_type()) << destination(destination_type()) + << header(string_type(), string_type()) << body(body_type()); + + add_header(message, string_type(), string_type()); + remove_header(message, string_type()); + clear_headers(message); + source(message, source_type()); + destination(message, destination_type()); + body(message, body_type()); + + (void)headers_; + (void)body_; + (void)source_; + (void)destination_; + } + + private: + M message; +}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_MESSAGE_MESSAGE_CONCEPT_HPP_20100903 diff --git a/cpp-netlib/boost/network/message/modifiers/add_header.hpp b/cpp-netlib/boost/network/message/modifiers/add_header.hpp new file mode 100644 index 00000000..51889a68 --- /dev/null +++ b/cpp-netlib/boost/network/message/modifiers/add_header.hpp @@ -0,0 +1,54 @@ + +#ifndef BOOST_NETWORK_MESSAGE_MODIFIER_ADD_HEADER_HPP_20100824 +#define BOOST_NETWORK_MESSAGE_MODIFIER_ADD_HEADER_HPP_20100824 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +namespace impl { +template +inline typename enable_if< + mpl::and_ >, mpl::not_ > >, void>::type +add_header(Message& message, KeyType const& key, ValueType const& value, Tag) { + message.headers().insert(std::make_pair(key, value)); +} + +template +inline typename enable_if >, is_async >, + void>::type +add_header(Message& message, KeyType const& key, ValueType const& value, Tag) { + typedef typename Message::header_type header_type; + message.add_header(header_type(key, value)); +} + +template +inline typename enable_if, void>::type add_header( + Message& message, KeyType const& key, ValueType const& value, Tag) { + typename Message::header_type header = {key, value}; + message.headers.insert(message.headers.end(), header); +} +} + +template class Message, class KeyType, + class ValueType> +inline void add_header(Message& message, KeyType const& key, + ValueType const& value) { + impl::add_header(message, key, value, Tag()); +} + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_MESSAGE_MODIFIER_ADD_HEADER_HPP_20100824 diff --git a/cpp-netlib/boost/network/message/modifiers/body.hpp b/cpp-netlib/boost/network/message/modifiers/body.hpp new file mode 100644 index 00000000..1fc1d347 --- /dev/null +++ b/cpp-netlib/boost/network/message/modifiers/body.hpp @@ -0,0 +1,35 @@ +#ifndef BOOST_NETWORK_MODIFIERS_BODY_HPP_20100824 +#define BOOST_NETWORK_MODIFIERS_BODY_HPP_20100824 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include + +namespace boost { +namespace network { + +template class Message, class ValueType> +inline void body_impl(Message& message, ValueType const& body, tags::pod) { + message.body = body; +} + +template class Message, class ValueType> +inline void body_impl(Message& message, ValueType const& body, + tags::normal) { + message.body(body); +} + +template class Message, class ValueType> +inline void body(Message& message, ValueType const& body_) { + body_impl(message, body_, typename pod_or_normal::type()); +} + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_MODIFIERS_BODY_HPP_20100824 diff --git a/cpp-netlib/boost/network/message/modifiers/clear_headers.hpp b/cpp-netlib/boost/network/message/modifiers/clear_headers.hpp new file mode 100644 index 00000000..74991dc6 --- /dev/null +++ b/cpp-netlib/boost/network/message/modifiers/clear_headers.hpp @@ -0,0 +1,55 @@ +#ifndef BOOST_NETWORK_MESSAGE_MODIFIER_CLEAR_HEADERS_HPP_20100824 +#define BOOST_NETWORK_MESSAGE_MODIFIER_CLEAR_HEADERS_HPP_20100824 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +namespace impl { +template +inline typename enable_if< + mpl::and_ >, mpl::not_ > >, void>::type +clear_headers(Message const &message, Tag const &) { + (typename Message::headers_container_type()).swap(message.headers()); +} + +template +inline typename enable_if, void>::type clear_headers( + Message const &message, Tag const &) { + (typename Message::headers_container_type()).swap(message.headers); +} + +template +inline typename enable_if >, is_async >, + void>::type +clear_headers(Message const &message, Tag const &) { + boost::promise header_promise; + boost::shared_future headers_future( + header_promise.get_future()); + message.headers(headers_future); + header_promise.set_value(typename Message::headers_container_type()); +} + +} // namespace impl + +template class Message> +inline void clear_headers(Message const &message) { + impl::clear_headers(message, Tag()); +} + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_MESSAGE_MODIFIER_CLEAR_HEADERS_HPP_20100824 diff --git a/cpp-netlib/boost/network/message/modifiers/destination.hpp b/cpp-netlib/boost/network/message/modifiers/destination.hpp new file mode 100644 index 00000000..2d461ee6 --- /dev/null +++ b/cpp-netlib/boost/network/message/modifiers/destination.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_NETWORK_MESSAGE_MODIFIER_DESTINATION_HPP_20100824 +#define BOOST_NETWORK_MESSAGE_MODIFIER_DESTINATION_HPP_20100824 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include + +namespace boost { +namespace network { + +namespace impl { + +template +inline void destination(Message const &message, ValueType const &destination_, + Tag const &, mpl::false_ const &) { + message.destination(destination_); +} + +template +inline void destination(Message const &message, ValueType const &destination_, + Tag const &, mpl::true_ const &) { + message.destination(destination_); +} +} + +template class Message, class ValueType> +inline void destination(Message const &message, + ValueType const &destination_) { + impl::destination(message, destination_, Tag(), is_async()); +} + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_MESSAGE_MODIFIER_DESTINATION_HPP_20100824 diff --git a/cpp-netlib/boost/network/message/modifiers/remove_header.hpp b/cpp-netlib/boost/network/message/modifiers/remove_header.hpp new file mode 100644 index 00000000..57a94fef --- /dev/null +++ b/cpp-netlib/boost/network/message/modifiers/remove_header.hpp @@ -0,0 +1,65 @@ + +#ifndef BOOST_NETWORK_MESSAGE_MODIFIER_REMOVE_HEADER_HPP_20100824 +#define BOOST_NETWORK_MESSAGE_MODIFIER_REMOVE_HEADER_HPP_20100824 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +namespace impl { + +template +inline typename enable_if< + mpl::and_ >, mpl::not_ > >, void>::type +remove_header(Message& message, KeyType const& key, Tag) { + message.headers().erase(key); +} + +template +inline typename enable_if >, is_async >, + void>::type +remove_header(Message& message, KeyType const& key, Tag) { + message.remove_header(key); +} + +template +struct iequals_pred { + KeyType const& key; + iequals_pred(KeyType const& key) : key(key) {} + template + bool operator()(Header& other) const { + return boost::iequals(key, name(other)); + } +}; + +template +inline typename enable_if, void>::type remove_header( + Message& message, KeyType const& key, Tag) { + message.headers.erase( + boost::remove_if(message.headers, iequals_pred(key)), + message.headers.end()); +} + +} // namespace impl + +template class Message, class KeyType> +inline void remove_header(Message& message, KeyType const& key) { + impl::remove_header(message, key, Tag()); +} + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_MESSAGE_MODIFIER_REMOVE_HEADER_HPP_20100824 diff --git a/cpp-netlib/boost/network/message/modifiers/source.hpp b/cpp-netlib/boost/network/message/modifiers/source.hpp new file mode 100644 index 00000000..dfaca051 --- /dev/null +++ b/cpp-netlib/boost/network/message/modifiers/source.hpp @@ -0,0 +1,40 @@ + +#ifndef BOOST_NETWORK_MESSAGE_MODIFIER_SOURCE_HPP_20100824 +#define BOOST_NETWORK_MESSAGE_MODIFIER_SOURCE_HPP_20100824 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include + +namespace boost { +namespace network { + +namespace impl { + +template +inline void source(Message const &message, ValueType const &source_, + Tag const &, mpl::false_ const &) { + message.source(source_); +} + +template +inline void source(Message const &message, ValueType const &source_, + Tag const &, mpl::true_ const &) { + message.source(source_); +} + +} // namespace impl + +template class Message, class ValueType> +inline void source(Message const &message, ValueType const &source_) { + impl::source(message, source_, Tag(), is_async()); +} + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_MESSAGE_MODIFIER_SOURCE_HPP_20100824 diff --git a/cpp-netlib/boost/network/message/traits/body.hpp b/cpp-netlib/boost/network/message/traits/body.hpp new file mode 100644 index 00000000..17f682db --- /dev/null +++ b/cpp-netlib/boost/network/message/traits/body.hpp @@ -0,0 +1,43 @@ + +#ifndef BOOST_NETWORK_MESSAGE_TRAITS_BODY_HPP_20100903 +#define BOOST_NETWORK_MESSAGE_TRAITS_BODY_HPP_20100903 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +namespace traits { + +template +struct unsupported_tag; + +template +struct body + : mpl::if_< + is_async, + boost::shared_future::type>, + typename mpl::if_< + mpl::or_, + is_same, + is_same >, + typename string::type, + unsupported_tag >::type> {}; + +} // namespace traits + +} /* network */ + +} /* boost */ + +#endif // BOOST_NETWORK_MESSAGE_TRAITS_BODY_HPP_20100903 diff --git a/cpp-netlib/boost/network/message/traits/destination.hpp b/cpp-netlib/boost/network/message/traits/destination.hpp new file mode 100644 index 00000000..1016cdfb --- /dev/null +++ b/cpp-netlib/boost/network/message/traits/destination.hpp @@ -0,0 +1,42 @@ + +#ifndef BOOST_NETWORK_MESSAGE_TRAITS_DESTINATION_HPP_20100903 +#define BOOST_NETWORK_MESSAGE_TRAITS_DESTINATION_HPP_20100903 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +namespace traits { + +template +struct unsupported_tag; + +template +struct destination + : mpl::if_< + is_async, + boost::shared_future::type>, + typename mpl::if_< + mpl::or_, + is_same, + is_same >, + typename string::type, + unsupported_tag >::type> {}; + +} // namespace traits + +} /* network */ + +} /* boost */ + +#endif // BOOST_NETWORK_MESSAGE_TRAITS_DESTINATION_HPP_20100903 diff --git a/cpp-netlib/boost/network/message/traits/headers.hpp b/cpp-netlib/boost/network/message/traits/headers.hpp new file mode 100644 index 00000000..8f6f5549 --- /dev/null +++ b/cpp-netlib/boost/network/message/traits/headers.hpp @@ -0,0 +1,56 @@ + +#ifndef BOOST_NETWORK_MESSAGE_TRAITS_HEADERS_HPP_20100903 +#define BOOST_NETWORK_MESSAGE_TRAITS_HEADERS_HPP_20100903 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +namespace traits { + +template +struct unsupported_tag; + +template +struct header_key + : mpl::if_< + is_async, + boost::shared_future::type>, + typename mpl::if_< + mpl::or_, + is_same, + is_same >, + typename string::type, + unsupported_tag >::type> {}; + +template +struct header_value + : mpl::if_< + is_async, + boost::shared_future::type>, + typename mpl::if_< + mpl::or_, + is_same, + is_same >, + typename string::type, + unsupported_tag >::type> {}; + +} // namespace traits + +} /* network */ + +} /* boost */ + +#endif // BOOST_NETWORK_MESSAGE_TRAITS_HEADERS_HPP_20100903 diff --git a/cpp-netlib/boost/network/message/traits/source.hpp b/cpp-netlib/boost/network/message/traits/source.hpp new file mode 100644 index 00000000..f1b8c2fb --- /dev/null +++ b/cpp-netlib/boost/network/message/traits/source.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_NETWORK_MESSAGE_TRAITS_SOURCE_HPP_20100903 +#define BOOST_NETWORK_MESSAGE_TRAITS_SOURCE_HPP_20100903 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +namespace traits { + +template +struct unsupported_tag; + +template +struct source + : mpl::if_< + is_async, + boost::shared_future::type>, + typename mpl::if_< + mpl::or_, + is_same, + is_same >, + typename string::type, + unsupported_tag >::type> {}; + +} // namespace traits + +} /* network */ + +} /* boost */ + +#endif // BOOST_NETWORK_MESSAGE_TRAITS_SOURCE_HPP_20100903 diff --git a/cpp-netlib/boost/network/message/transformers.hpp b/cpp-netlib/boost/network/message/transformers.hpp new file mode 100644 index 00000000..0b990dfa --- /dev/null +++ b/cpp-netlib/boost/network/message/transformers.hpp @@ -0,0 +1,53 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_TRANSFORMERS_HPP__ +#define __NETWORK_MESSAGE_TRANSFORMERS_HPP__ + +/** transformers.hpp + * + * Pulls in all the transformers files. + */ +#include +#include +#include + +#include + +namespace boost { +namespace network { +namespace impl { +template +struct get_real_algorithm { + typedef typename boost::function_traits< + typename boost::remove_pointer::type>::result_type:: + template type::type>::result_type> type; +}; + +template +struct transform_impl : public get_real_algorithm::type {}; +} // namspace impl + +template +inline impl::transform_impl transform(Algorithm, + Selector) { + return impl::transform_impl(); +} + +template +inline basic_message& operator<<( + basic_message& msg_, + impl::transform_impl const& transformer) { + transformer(msg_); + return msg_; +} + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_MESSAGE_TRANSFORMERS_HPP__ diff --git a/cpp-netlib/boost/network/message/transformers/selectors.hpp b/cpp-netlib/boost/network/message/transformers/selectors.hpp new file mode 100644 index 00000000..4b7a3963 --- /dev/null +++ b/cpp-netlib/boost/network/message/transformers/selectors.hpp @@ -0,0 +1,55 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_TRANSFORMERS_SELECTORS_HPP__ +#define __NETWORK_MESSAGE_TRANSFORMERS_SELECTORS_HPP__ + +namespace boost { +namespace network { +namespace selectors { +struct source_selector; +struct destination_selector; +} // namespace selectors + +selectors::source_selector source_(selectors::source_selector); +selectors::destination_selector destination_(selectors::destination_selector); + +namespace selectors { +struct source_selector { + private: + source_selector() {}; + source_selector(source_selector const &) {}; + friend source_selector boost::network::source_(source_selector); +}; + +struct destination_selector { + private: + destination_selector() {}; + destination_selector(destination_selector const &) {}; + friend destination_selector boost::network::destination_( + destination_selector); +}; +} // namespace selectors + +typedef selectors::source_selector (*source_selector_t)( + selectors::source_selector); +typedef selectors::destination_selector (*destination_selector_t)( + selectors::destination_selector); + +inline selectors::source_selector source_(selectors::source_selector) { + return selectors::source_selector(); +} + +inline selectors::destination_selector destination_( + selectors::destination_selector) { + return selectors::destination_selector(); +} + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_MESSAGE_TRANSFORMERS_SELECTORS_HPP__ diff --git a/cpp-netlib/boost/network/message/transformers/to_lower.hpp b/cpp-netlib/boost/network/message/transformers/to_lower.hpp new file mode 100644 index 00000000..4979f1b1 --- /dev/null +++ b/cpp-netlib/boost/network/message/transformers/to_lower.hpp @@ -0,0 +1,86 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_TRANSFORMERS_TO_LOWER_HPP__ +#define __NETWORK_MESSAGE_TRANSFORMERS_TO_LOWER_HPP__ + +#include + +/** to_lower.hpp + * + * Implements the to_lower transformer. This applies + * the to_lower string algorithm to a string, which + * is selected by the appropriate selector. + * + * This defines a type, to be applied using template + * metaprogramming on the selected string target. + */ +namespace boost { +namespace network { + +namespace impl { + +template +struct to_lower_transformer {}; + +template <> +struct to_lower_transformer { + template + void operator()(basic_message &message_) const { + boost::to_lower(message_.source()); + } + + protected: + ~to_lower_transformer() {} +}; + +template <> +struct to_lower_transformer { + template + void operator()(basic_message &message_) const { + boost::to_lower(message_.destination()); + } + + protected: + ~to_lower_transformer() {}; +}; + +} // namespace impl + +namespace detail { +struct to_lower_placeholder_helper; +} + +detail::to_lower_placeholder_helper to_lower_( + detail::to_lower_placeholder_helper); + +namespace detail { + +struct to_lower_placeholder_helper { + template + struct type : public impl::to_lower_transformer {}; + + private: + to_lower_placeholder_helper() {} + to_lower_placeholder_helper(to_lower_placeholder_helper const &) {} + friend to_lower_placeholder_helper boost::network::to_lower_( + to_lower_placeholder_helper); +}; +} + +typedef detail::to_lower_placeholder_helper (*to_lower_placeholder)( + detail::to_lower_placeholder_helper); + +inline detail::to_lower_placeholder_helper to_lower_( + detail::to_lower_placeholder_helper) { + return detail::to_lower_placeholder_helper(); +} + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_MESSAGE_TRANSFORMERS_TO_LOWER_HPP__ diff --git a/cpp-netlib/boost/network/message/transformers/to_upper.hpp b/cpp-netlib/boost/network/message/transformers/to_upper.hpp new file mode 100644 index 00000000..6e41ef7f --- /dev/null +++ b/cpp-netlib/boost/network/message/transformers/to_upper.hpp @@ -0,0 +1,86 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_TRANSFORMERS_TO_UPPER_HPP__ +#define __NETWORK_MESSAGE_TRANSFORMERS_TO_UPPER_HPP__ + +#include + +/** to_upper.hpp + * + * Implements the to_upper transformer. This applies + * the to_upper string algorithm to a string, which + * is selected by the appropriate selector. + * + * This defines a type, to be applied using template + * metaprogramming on the selected string target. + */ +namespace boost { +namespace network { + +namespace impl { + +template +struct to_upper_transformer {}; + +template <> +struct to_upper_transformer { + template + void operator()(basic_message &message_) const { + boost::to_upper(message_.source()); + } + + protected: + ~to_upper_transformer() {}; +}; + +template <> +struct to_upper_transformer { + template + void operator()(basic_message &message_) const { + boost::to_upper(message_.destination()); + } + + protected: + ~to_upper_transformer() {}; +}; + +} // namespace impl + +namespace detail { +struct to_upper_placeholder_helper; +} + +detail::to_upper_placeholder_helper to_upper_( + detail::to_upper_placeholder_helper); + +namespace detail { + +struct to_upper_placeholder_helper { + template + struct type : public impl::to_upper_transformer {}; + + private: + to_upper_placeholder_helper() {} + to_upper_placeholder_helper(to_upper_placeholder_helper const &) {} + friend to_upper_placeholder_helper boost::network::to_upper_( + to_upper_placeholder_helper); +}; +} + +typedef detail::to_upper_placeholder_helper (*to_upper_placeholder)( + detail::to_upper_placeholder_helper); + +inline detail::to_upper_placeholder_helper to_upper_( + detail::to_upper_placeholder_helper) { + return detail::to_upper_placeholder_helper(); +} + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_MESSAGE_TRANSFORMERS_TO_UPPER_HPP__ diff --git a/cpp-netlib/boost/network/message/wrappers.hpp b/cpp-netlib/boost/network/message/wrappers.hpp new file mode 100644 index 00000000..47b87f05 --- /dev/null +++ b/cpp-netlib/boost/network/message/wrappers.hpp @@ -0,0 +1,19 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_WRAPPERS_HPP__ +#define __NETWORK_MESSAGE_WRAPPERS_HPP__ + +/** wrappers.hpp + * + * Pulls in all the wrapper header files. + */ +#include +#include +#include +#include + +#endif // __NETWORK_MESSAGE_WRAPPERS_HPP__ diff --git a/cpp-netlib/boost/network/message/wrappers/body.hpp b/cpp-netlib/boost/network/message/wrappers/body.hpp new file mode 100644 index 00000000..4dd1d5eb --- /dev/null +++ b/cpp-netlib/boost/network/message/wrappers/body.hpp @@ -0,0 +1,105 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ +#define __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ + +#include +#include +#include + +namespace boost { +namespace network { + +template +struct body_range { + typedef typename boost::iterator_range< + typename Message::string_type::const_iterator> type; +}; + +namespace impl { +template +struct body_wrapper : public detail::wrapper_base > { + typedef basic_message message_type; + typedef typename string::type string_type; + typedef detail::wrapper_base > wrapper_base; + + explicit body_wrapper(basic_message& message_) + : wrapper_base(message_) {}; + + operator string_type() const { + return string_type(wrapper_base::_message.body()); + }; + + std::size_t size() const { return wrapper_base::_message.body().size(); } + + operator boost::iterator_range< + typename boost::range_iterator::type>() const { + return boost::make_iterator_range(wrapper_base::_message.body()); + } + + typename string_type::const_iterator begin() const { + return wrapper_base::_message.body().begin(); + } + + typename string_type::const_iterator end() const { + return wrapper_base::_message.body().end(); + } +}; + +template +struct body_wrapper_const + : public detail::wrapper_base_const > { + typedef basic_message message_type; + typedef typename string::type string_type; + typedef detail::wrapper_base_const > wrapper_base; + + explicit body_wrapper_const(basic_message const& message_) + : wrapper_base(message_) {}; + + operator string_type() const { + return string_type(wrapper_base::_message.body()); + } + + std::size_t size() const { return wrapper_base::_message.body().size(); } + + operator boost::range_iterator() const { + return boost::make_iterator_range(wrapper_base::_message.body()); + } +}; + +template +inline std::ostream& operator<<(std::ostream& os, + body_wrapper const& body) { + os << static_cast::string_type>(body); + return os; +} + +template +inline std::ostream& operator<<(std::ostream& os, + body_wrapper_const const& body) { + os << static_cast::string_type>(body); + return os; +} + +} // namespace impl + +template +inline impl::body_wrapper const body(basic_message& message_) { + return impl::body_wrapper(message_); +} + +template +inline impl::body_wrapper_const const body( + basic_message const& message_) { + return impl::body_wrapper_const(message_); +} + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_MESSAGE_WRAPPERS_BODY_HPP__ diff --git a/cpp-netlib/boost/network/message/wrappers/destination.hpp b/cpp-netlib/boost/network/message/wrappers/destination.hpp new file mode 100644 index 00000000..fe11dffd --- /dev/null +++ b/cpp-netlib/boost/network/message/wrappers/destination.hpp @@ -0,0 +1,42 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_WRAPPERS_DESTINATION_HPP__ +#define __NETWORK_MESSAGE_WRAPPERS_DESTINATION_HPP__ + +#include + +namespace boost { +namespace network { + +namespace impl { +template +struct destination_wrapper + : public detail::wrapper_base > { + typedef Tag tag; + typedef basic_message message_type; + typedef typename string::type string_type; + typedef detail::wrapper_base > wrapper_base; + + explicit destination_wrapper(message_type& message_) + : wrapper_base(message_) {}; + + operator string_type() const { + return string_type(wrapper_base::_message.destination()); + }; +}; +} // namespace impl + +template +inline typename string::type destination(basic_message& message_) { + return impl::destination_wrapper(message_); +} + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_MESSAGE_WRAPPERS_DESTINATION_HPP__ diff --git a/cpp-netlib/boost/network/message/wrappers/headers.hpp b/cpp-netlib/boost/network/message/wrappers/headers.hpp new file mode 100644 index 00000000..5efeb94e --- /dev/null +++ b/cpp-netlib/boost/network/message/wrappers/headers.hpp @@ -0,0 +1,101 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__ +#define __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__ + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +/// Template metaprogram to get the range type for a message +template +struct headers_range { + typedef typename headers_container::type + headers_container_type; + typedef typename boost::iterator_range< + typename headers_container_type::const_iterator> type; +}; + +template +struct basic_message; + +/** headers wrapper for messages. + * + * This exposes an interface similar to a map, indexable + * using operator[] taking a string as the index and returns + * a range of iterators (std::pair) + * whose keys are all equal to the index string. + * + * This type is also convertible to a + * headers_range >::type + * Which allows for full range support. + * + * The type is also convertible to a + * headers_container::type + * Which copies the headers from the wrapped message. + * + */ +namespace impl { +template +struct headers_wrapper + : public detail::wrapper_base_const > { + typedef Tag tag; + typedef basic_message message_type; + typedef typename string::type string_type; + typedef typename headers_range::type range_type; + typedef typename headers_container::type headers_container_type; + typedef typename headers_container_type::const_iterator const_iterator; + typedef typename headers_container_type::iterator iterator; + typedef detail::wrapper_base_const > wrapper_base; + + explicit headers_wrapper(basic_message const& message_) + : wrapper_base(message_) {}; + + range_type operator[](string_type const& key) const { + return headers_wrapper::_message.headers().equal_range(key); + }; + + typename message_type::headers_container_type::size_type count( + string_type const& key) const { + return headers_wrapper::_message.headers().count(key); + }; + + const_iterator begin() const { + return headers_wrapper::_message.headers().begin(); + }; + + const_iterator end() const { + return headers_wrapper::_message.headers().end(); + }; + + operator range_type() { + return make_iterator_range(headers_wrapper::_message.headers().begin(), + headers_wrapper::_message.headers().end()); + }; + + operator headers_container_type() { + return headers_wrapper::_message.headers(); + } +}; +} // namespace impl + +/// Factory method to create the right wrapper object +template +inline impl::headers_wrapper headers(basic_message const& message_) { + return impl::headers_wrapper(message_); +} + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_MESSAGE_WRAPPERS_HEADERS_HPP__ diff --git a/cpp-netlib/boost/network/message/wrappers/source.hpp b/cpp-netlib/boost/network/message/wrappers/source.hpp new file mode 100644 index 00000000..40d7e9b3 --- /dev/null +++ b/cpp-netlib/boost/network/message/wrappers/source.hpp @@ -0,0 +1,41 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ +#define __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ + +#include + +namespace boost { +namespace network { + +namespace impl { +template +struct source_wrapper : public detail::wrapper_base > { + typedef Tag tag; + typedef basic_message message_type; + typedef typename string::type string_type; + typedef detail::wrapper_base > wrapper_base; + + explicit source_wrapper(basic_message& message_) + : wrapper_base(message_) {}; + + operator string_type() const { + return string_type(wrapper_base::_message.source()); + }; +}; +} // namespace impl + +template +inline typename string::type source(basic_message& message_) { + return impl::source_wrapper(message_); +} + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_MESSAGE_WRAPPERS_SOURCE_HPP__ diff --git a/cpp-netlib/boost/network/message_fwd.hpp b/cpp-netlib/boost/network/message_fwd.hpp new file mode 100644 index 00000000..08eaf46c --- /dev/null +++ b/cpp-netlib/boost/network/message_fwd.hpp @@ -0,0 +1,18 @@ +// Copyright (c) Glyn Matthews 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 __2008817MESSAGE_FWD_INC__ +#define __2008817MESSAGE_FWD_INC__ + +namespace boost { +namespace network { + +template +struct basic_message; + +} // namespace boost +} // namespace network + +#endif // __2008817MESSAGE_FWD_INC__ diff --git a/cpp-netlib/boost/network/protocol.hpp b/cpp-netlib/boost/network/protocol.hpp new file mode 100644 index 00000000..758e8aa1 --- /dev/null +++ b/cpp-netlib/boost/network/protocol.hpp @@ -0,0 +1,16 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_PROTOCOLS_20070908_1_HPP__ +#define __NETWORK_PROTOCOLS_20070908_1_HPP__ + +// Include all protocol implementation headers in protocol/* +// Author: Dean Michael Berris +// Date Created: Oct. 08, 2007 + +#include // include HTTP implementation + +#endif // __NETWORK_PROTOCOLS_20070908-1_HPP__ diff --git a/cpp-netlib/boost/network/protocol/http.hpp b/cpp-netlib/boost/network/protocol/http.hpp new file mode 100644 index 00000000..d3ede696 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http.hpp @@ -0,0 +1,19 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_PROTOCOL_HTTP_20070908_1_HPP__ +#define __NETWORK_PROTOCOL_HTTP_20070908_1_HPP__ + +// Include HTTP implementation headers +// Author: Dean Michael Berris +// Date Created: Oct. 08, 2007 + +#include +#include +#include +#include + +#endif // __NETWORK_PROTOCOL_HTTP_20070908-1_HPP__ diff --git a/cpp-netlib/boost/network/protocol/http/algorithms/linearize.hpp b/cpp-netlib/boost/network/protocol/http/algorithms/linearize.hpp new file mode 100644 index 00000000..d0347fd0 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/algorithms/linearize.hpp @@ -0,0 +1,192 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_ALGORITHMS_LINEARIZE_HPP_20101028 +#define BOOST_NETWORK_PROTOCOL_HTTP_ALGORITHMS_LINEARIZE_HPP_20101028 + +// Copyright 2010 Dean Michael Berris. +// Copyright 2014 Jussi Lyytinen +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct linearize_header { + typedef typename string::type string_type; + + template + struct result; + + template + struct result { + typedef string_type type; + }; + + template + BOOST_CONCEPT_REQUIRES(((Header::type>)), + (string_type)) + operator()(ValueType& header) { + typedef typename ostringstream::type output_stream; + typedef constants consts; + output_stream header_line; + header_line << name(header) << consts::colon() << consts::space() + << value(header) << consts::crlf(); + return header_line.str(); + } +}; + +template +BOOST_CONCEPT_REQUIRES(((ClientRequest)), (OutputIterator)) + linearize(Request const& request, + typename Request::string_type const& method, + unsigned version_major, unsigned version_minor, + OutputIterator oi) { + typedef typename Request::tag Tag; + typedef constants consts; + typedef typename string::type string_type; + static string_type http_slash = consts::http_slash(), + accept = consts::accept(), + accept_mime = consts::default_accept_mime(), + accept_encoding = consts::accept_encoding(), + default_accept_encoding = + consts::default_accept_encoding(), + crlf = consts::crlf(), host = consts::host(), + connection = consts::connection(), close = consts::close(); + boost::copy(method, oi); + *oi = consts::space_char(); + if (request.path().empty() || request.path()[0] != consts::slash_char()) + *oi = consts::slash_char(); + boost::copy(request.path(), oi); + if (!request.query().empty()) { + *oi = consts::question_mark_char(); + boost::copy(request.query(), oi); + } + if (!request.anchor().empty()) { + *oi = consts::hash_char(); + boost::copy(request.anchor(), oi); + } + *oi = consts::space_char(); + boost::copy(http_slash, oi); + string_type version_major_str = + boost::lexical_cast(version_major), + version_minor_str = + boost::lexical_cast(version_minor); + boost::copy(version_major_str, oi); + *oi = consts::dot_char(); + boost::copy(version_minor_str, oi); + boost::copy(crlf, oi); + + // We need to determine whether we've seen any of the following headers + // before setting the defaults. We use a bitset to keep track of the + // defaulted headers. + enum { + ACCEPT, + ACCEPT_ENCODING, + HOST, + CONNECTION, + MAX + }; + std::bitset found_headers; + static char const* defaulted_headers[][2] = { + {consts::accept(), consts::accept() + std::strlen(consts::accept())}, + {consts::accept_encoding(), + consts::accept_encoding() + std::strlen(consts::accept_encoding())}, + {consts::host(), consts::host() + std::strlen(consts::host())}, + {consts::connection(), + consts::connection() + std::strlen(consts::connection())}}; + + typedef typename headers_range::type headers_range; + typedef typename range_value::type headers_value; + BOOST_FOREACH(const headers_value & header, headers(request)) { + string_type header_name = name(header), header_value = value(header); + // Here we check that we have not seen an override to the defaulted + // headers. + for (int header_index = 0; header_index < MAX; ++header_index) + if (std::distance(header_name.begin(), header_name.end()) == + std::distance(defaulted_headers[header_index][0], + defaulted_headers[header_index][1]) && + std::equal(header_name.begin(), header_name.end(), + defaulted_headers[header_index][0], + algorithm::is_iequal())) + found_headers.set(header_index, true); + + // We ignore empty headers. + if (header_value.empty()) continue; + boost::copy(header_name, oi); + *oi = consts::colon_char(); + *oi = consts::space_char(); + boost::copy(header_value, oi); + boost::copy(crlf, oi); + } + + if (!found_headers[HOST]) { + boost::copy(host, oi); + *oi = consts::colon_char(); + *oi = consts::space_char(); + boost::copy(request.host(), oi); + boost::optional port_ = +#if (_MSC_VER >= 1600 && BOOST_VERSION > 105500) + port(request).as_optional(); +#else + port(request); +#endif + if (port_) { + string_type port_str = boost::lexical_cast(*port_); + *oi = consts::colon_char(); + boost::copy(port_str, oi); + } + boost::copy(crlf, oi); + } + + if (!found_headers[ACCEPT]) { + boost::copy(accept, oi); + *oi = consts::colon_char(); + *oi = consts::space_char(); + boost::copy(accept_mime, oi); + boost::copy(crlf, oi); + } + + if (version_major == 1u && version_minor == 1u && + !found_headers[ACCEPT_ENCODING]) { + boost::copy(accept_encoding, oi); + *oi = consts::colon_char(); + *oi = consts::space_char(); + boost::copy(default_accept_encoding, oi); + boost::copy(crlf, oi); + } + + if (!connection_keepalive::value && !found_headers[CONNECTION]) { + boost::copy(connection, oi); + *oi = consts::colon_char(); + *oi = consts::space_char(); + boost::copy(close, oi); + boost::copy(crlf, oi); + } + + boost::copy(crlf, oi); + typename body_range::type body_data = body(request).range(); + return boost::copy(body_data, oi); +} + +} /* http */ + +} /* net */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_ALGORITHMS_LINEARIZE_HPP_20101028 */ diff --git a/cpp-netlib/boost/network/protocol/http/client.hpp b/cpp-netlib/boost/network/protocol/http/client.hpp new file mode 100644 index 00000000..1e315a8f --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client.hpp @@ -0,0 +1,72 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_20091215 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_20091215 + +// Copyright Dean Michael Berris 2007-2010. +// 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) + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_client : basic_client_facade { + private: + typedef basic_client_facade + base_facade_type; + + public: + typedef basic_request request; + typedef basic_response response; + typedef typename string::type string_type; + typedef Tag tag_type; + typedef client_options options; + + // Constructors + // ================================================================= + // This constructor takes a single options argument of type + // client_options. See boost/network/protocol/http/client/options.hpp + // for more details. + explicit basic_client(options const& options) : base_facade_type(options) {} + + // This default constructor sets up the default options. + basic_client() : base_facade_type(options()) {} + // + // ================================================================= +}; + +#ifndef BOOST_NETWORK_HTTP_CLIENT_DEFAULT_TAG +#define BOOST_NETWORK_HTTP_CLIENT_DEFAULT_TAG tags::http_async_8bit_udp_resolve +#endif + +typedef basic_client client; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_20091215 diff --git a/cpp-netlib/boost/network/protocol/http/client/async_impl.hpp b/cpp-netlib/boost/network/protocol/http/client/async_impl.hpp new file mode 100644 index 00000000..1c0eb1fe --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/async_impl.hpp @@ -0,0 +1,109 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623 + +// Copyright Dean Michael Berris 2010. +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_client_impl; + +namespace impl { +template +struct async_client + : connection_policy::type { + typedef typename connection_policy::type + connection_base; + typedef typename resolver::type resolver_type; + typedef typename string::type string_type; + + typedef function const&, + system::error_code const&)> body_callback_function_type; + + typedef function body_generator_function_type; + + async_client(bool cache_resolved, bool follow_redirect, + bool always_verify_peer, int timeout, + boost::shared_ptr service, + optional const& certificate_filename, + optional const& verify_path, + optional const& certificate_file, + optional const& private_key_file, + optional const& ciphers, long ssl_options) + : connection_base(cache_resolved, follow_redirect, timeout), + service_ptr(service.get() + ? service + : boost::make_shared()), + service_(*service_ptr), + resolver_(service_), + sentinel_(new boost::asio::io_service::work(service_)), + certificate_filename_(certificate_filename), + verify_path_(verify_path), + certificate_file_(certificate_file), + private_key_file_(private_key_file), + ciphers_(ciphers), + ssl_options_(ssl_options), + always_verify_peer_(always_verify_peer) { + connection_base::resolver_strand_.reset( + new boost::asio::io_service::strand(service_)); + if (!service) + lifetime_thread_.reset(new boost::thread( + boost::bind(&boost::asio::io_service::run, &service_))); + } + + ~async_client() throw() { sentinel_.reset(); } + + void wait_complete() { + sentinel_.reset(); + if (lifetime_thread_.get()) { + lifetime_thread_->join(); + lifetime_thread_.reset(); + } + } + + basic_response const request_skeleton( + basic_request const& request_, string_type const& method, + bool get_body, body_callback_function_type callback, + body_generator_function_type generator) { + typename connection_base::connection_ptr connection_; + connection_ = connection_base::get_connection( + resolver_, request_, always_verify_peer_, certificate_filename_, + verify_path_, certificate_file_, private_key_file_, ciphers_, + ssl_options_); + return connection_->send_request(method, request_, get_body, callback, + generator); + } + + boost::shared_ptr service_ptr; + boost::asio::io_service& service_; + resolver_type resolver_; + boost::shared_ptr sentinel_; + boost::shared_ptr lifetime_thread_; + optional certificate_filename_; + optional verify_path_; + optional certificate_file_; + optional private_key_file_; + optional ciphers_; + long ssl_options_; + bool always_verify_peer_; +}; +} // namespace impl +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623 diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/async_base.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/async_base.hpp new file mode 100644 index 00000000..ada856a2 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/async_base.hpp @@ -0,0 +1,80 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ASYNC_CONNECTION_BASE_20100529 +#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ASYNC_CONNECTION_BASE_20100529 + +// Copryight 2013 Google, Inc. +// Copyright 2010 Dean Michael Berris +// Copyright 2010 (C) Sinefunc, Inc. +// 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) + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { +namespace impl { + +template +struct async_connection_base { + typedef async_connection_base this_type; + typedef typename resolver_policy::type resolver_base; + typedef typename resolver_base::resolver_type resolver_type; + typedef typename resolver_base::resolve_function resolve_function; + typedef typename string::type string_type; + typedef basic_request request; + typedef basic_response response; + typedef iterator_range char_const_range; + typedef function + body_callback_function_type; + typedef function body_generator_function_type; + typedef shared_ptr connection_ptr; + + // This is the factory function which constructs the appropriate async + // connection implementation with the correct delegate chosen based on + // the + // tag. + static connection_ptr new_connection( + resolve_function resolve, resolver_type &resolver, bool follow_redirect, + bool always_verify_peer, bool https, int timeout, + optional certificate_filename = optional(), + optional const &verify_path = optional(), + optional certificate_file = optional(), + optional private_key_file = optional(), + optional ciphers = optional(), + long ssl_options = 0) { + typedef http_async_connection + async_connection; + typedef typename delegate_factory::type delegate_factory_type; + connection_ptr temp; + temp.reset(new async_connection( + resolver, resolve, follow_redirect, timeout, + delegate_factory_type::new_connection_delegate( + resolver.get_io_service(), https, always_verify_peer, + certificate_filename, verify_path, certificate_file, + private_key_file, ciphers, ssl_options))); + BOOST_ASSERT(temp.get() != 0); + return temp; + } + + // This is the pure virtual entry-point for all asynchronous + // connections. + virtual response start(request const &request, string_type const &method, + bool get_body, body_callback_function_type callback, + body_generator_function_type generator) = 0; + + virtual ~async_connection_base() {} +}; + +} // namespace impl + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ASYNC_CONNECTION_BASE_20100529 diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/async_normal.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/async_normal.hpp new file mode 100644 index 00000000..f5590d7f --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/async_normal.hpp @@ -0,0 +1,509 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_CONNECTION_HPP_20100601 +#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_CONNECTION_HPP_20100601 + +// Copyright 2010 (C) Dean Michael Berris +// Copyright 2010 (C) Sinefunc, Inc. +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google,Inc. +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace network { +namespace http { +namespace impl { + +template +struct async_connection_base; + +namespace placeholders = boost::asio::placeholders; + +template +struct http_async_connection + : async_connection_base, + protected http_async_protocol_handler, + boost::enable_shared_from_this< + http_async_connection > { + typedef async_connection_base base; + typedef http_async_protocol_handler + protocol_base; + typedef typename base::resolver_type resolver_type; + typedef typename base::resolver_base::resolver_iterator resolver_iterator; + typedef typename base::resolver_base::resolver_iterator_pair + resolver_iterator_pair; + typedef typename base::response response; + typedef typename base::string_type string_type; + typedef typename base::request request; + typedef typename base::resolver_base::resolve_function resolve_function; + typedef typename base::body_callback_function_type + body_callback_function_type; + typedef typename base::body_generator_function_type + body_generator_function_type; + typedef http_async_connection this_type; + typedef typename delegate_factory::type delegate_factory_type; + typedef typename delegate_factory_type::connection_delegate_ptr + connection_delegate_ptr; + + http_async_connection(resolver_type& resolver, resolve_function resolve, + bool follow_redirect, int timeout, + connection_delegate_ptr delegate) + : timeout_(timeout), + timer_(resolver.get_io_service()), + is_timedout_(false), + follow_redirect_(follow_redirect), + resolver_(resolver), + resolve_(resolve), + request_strand_(resolver.get_io_service()), + delegate_(delegate) {} + + // This is the main entry point for the connection/request pipeline. + // We're + // overriding async_connection_base<...>::start(...) here which is + // called + // by the client. + virtual response start(request const& request, string_type const& method, + bool get_body, body_callback_function_type callback, + body_generator_function_type generator) { + response response_; + this->init_response(response_, get_body); + linearize(request, method, version_major, version_minor, + std::ostreambuf_iterator::type>( + &command_streambuf)); + this->method = method; + boost::uint16_t port_ = port(request); + string_type host_ = host(request); + boost::uint16_t source_port = request.source_port(); + + resolve_(resolver_, host_, port_, + request_strand_.wrap(boost::bind( + &this_type::handle_resolved, this_type::shared_from_this(), + host_, port_, source_port, get_body, callback, + generator, boost::arg<1>(), boost::arg<2>()))); + if (timeout_ > 0) { + timer_.expires_from_now(boost::posix_time::seconds(timeout_)); + timer_.async_wait(request_strand_.wrap( + boost::bind(&this_type::handle_timeout, this_type::shared_from_this(), + boost::arg<1>()))); + } + return response_; + } + + private: + http_async_connection(http_async_connection const&); // = delete + + void set_errors(boost::system::error_code const& ec) { + boost::system::system_error error(ec); + this->version_promise.set_exception(boost::copy_exception(error)); + this->status_promise.set_exception(boost::copy_exception(error)); + this->status_message_promise.set_exception(boost::copy_exception(error)); + this->headers_promise.set_exception(boost::copy_exception(error)); + this->source_promise.set_exception(boost::copy_exception(error)); + this->destination_promise.set_exception(boost::copy_exception(error)); + this->body_promise.set_exception(boost::copy_exception(error)); + this->timer_.cancel(); + } + + void handle_timeout(boost::system::error_code const& ec) { + if (!ec) delegate_->disconnect(); + is_timedout_ = true; + } + + void handle_resolved(string_type host, boost::uint16_t port, boost::uint16_t source_port, bool get_body, + body_callback_function_type callback, + body_generator_function_type generator, + boost::system::error_code const& ec, + resolver_iterator_pair endpoint_range) { + if (!ec && !boost::empty(endpoint_range)) { + // Here we deal with the case that there was an error encountered + // and + // that there's still more endpoints to try connecting to. + resolver_iterator iter = boost::begin(endpoint_range); + asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); + delegate_->connect( + endpoint, host, source_port, + request_strand_.wrap(boost::bind( + &this_type::handle_connected, this_type::shared_from_this(), host, + port, source_port, get_body, callback, generator, + std::make_pair(++iter, resolver_iterator()), + placeholders::error))); + } else { + set_errors(ec ? ec : boost::asio::error::host_not_found); + boost::iterator_range range; + if (callback) callback(range, ec); + } + } + + void handle_connected(string_type host, boost::uint16_t port, boost::uint16_t source_port, bool get_body, + body_callback_function_type callback, + body_generator_function_type generator, + resolver_iterator_pair endpoint_range, + boost::system::error_code const& ec) { + if (is_timedout_) { + set_errors(asio::error::timed_out); + } else if (!ec) { + BOOST_ASSERT(delegate_.get() != 0); + delegate_->write( + command_streambuf, + request_strand_.wrap(boost::bind( + &this_type::handle_sent_request, this_type::shared_from_this(), + get_body, callback, generator, placeholders::error, + placeholders::bytes_transferred))); + } else { + if (!boost::empty(endpoint_range)) { + resolver_iterator iter = boost::begin(endpoint_range); + asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port); + delegate_->connect( + endpoint, host, source_port, + request_strand_.wrap(boost::bind( + &this_type::handle_connected, this_type::shared_from_this(), + host, port, source_port, get_body, callback, generator, + std::make_pair(++iter, resolver_iterator()), + placeholders::error))); + } else { + set_errors(ec ? ec : boost::asio::error::host_not_found); + boost::iterator_range range; + if (callback) callback(range, ec); + } + } + } + + enum state_t { + version, + status, + status_message, + headers, + body + }; + + void handle_sent_request(bool get_body, body_callback_function_type callback, + body_generator_function_type generator, + boost::system::error_code const& ec, + std::size_t bytes_transferred) { + // TODO(dberris): review parameter necessity. + (void)bytes_transferred; + + if (!is_timedout_ && !ec) { + if (generator) { + // Here we write some more data that the generator provides, + // before + // we wait for data from the server. + string_type chunk; + if (generator(chunk)) { + // At this point this means we have more data to write, so we + // write + // it out. + std::copy(chunk.begin(), chunk.end(), + std::ostreambuf_iterator::type>( + &command_streambuf)); + delegate_->write( + command_streambuf, + request_strand_.wrap(boost::bind( + &this_type::handle_sent_request, + this_type::shared_from_this(), get_body, callback, generator, + placeholders::error, placeholders::bytes_transferred))); + return; + } + } + delegate_->read_some( + boost::asio::mutable_buffers_1(this->part.c_array(), + this->part.size()), + request_strand_.wrap(boost::bind( + &this_type::handle_received_data, this_type::shared_from_this(), + version, get_body, callback, placeholders::error, + placeholders::bytes_transferred))); + } else { + set_errors(is_timedout_ ? asio::error::timed_out : ec); + } + } + + void handle_received_data(state_t state, bool get_body, + body_callback_function_type callback, + boost::system::error_code const& ec, + std::size_t bytes_transferred) { + static const long short_read_error = 335544539; + bool is_ssl_short_read_error = +#ifdef BOOST_NETWORK_ENABLE_HTTPS + ec.category() == asio::error::ssl_category && + ec.value() == short_read_error; +#else + false && short_read_error; +#endif + if (!is_timedout_ && + (!ec || ec == boost::asio::error::eof || is_ssl_short_read_error)) { + logic::tribool parsed_ok; + size_t remainder; + switch (state) { + case version: + if (ec == boost::asio::error::eof) return; + parsed_ok = this->parse_version( + delegate_, + request_strand_.wrap(boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), version, get_body, callback, + placeholders::error, placeholders::bytes_transferred)), + bytes_transferred); + if (!parsed_ok || indeterminate(parsed_ok)) return; + case status: + if (ec == boost::asio::error::eof) return; + parsed_ok = this->parse_status( + delegate_, + request_strand_.wrap(boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), status, get_body, callback, + placeholders::error, placeholders::bytes_transferred)), + bytes_transferred); + if (!parsed_ok || indeterminate(parsed_ok)) return; + case status_message: + if (ec == boost::asio::error::eof) return; + parsed_ok = this->parse_status_message( + delegate_, request_strand_.wrap(boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), status_message, + get_body, callback, placeholders::error, + placeholders::bytes_transferred)), + bytes_transferred); + if (!parsed_ok || indeterminate(parsed_ok)) return; + case headers: + if (ec == boost::asio::error::eof) return; + // In the following, remainder is the number of bytes that + // remain + // in the buffer. We need this in the body processing to make + // sure + // that the data remaining in the buffer is dealt with before + // another call to get more data for the body is scheduled. + fusion::tie(parsed_ok, remainder) = this->parse_headers( + delegate_, + request_strand_.wrap(boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), headers, get_body, callback, + placeholders::error, placeholders::bytes_transferred)), + bytes_transferred); + + if (!parsed_ok || indeterminate(parsed_ok)) return; + + if (!get_body) { + // We short-circuit here because the user does not + // want to get the body (in the case of a HEAD + // request). + this->body_promise.set_value(""); + this->destination_promise.set_value(""); + this->source_promise.set_value(""); + this->part.assign('\0'); + this->response_parser_.reset(); + return; + } + + if (callback) { + // Here we deal with the spill-over data from the + // headers processing. This means the headers data + // has already been parsed appropriately and we're + // looking to treat everything that remains in the + // buffer. + typename protocol_base::buffer_type::const_iterator begin = + this->part_begin; + typename protocol_base::buffer_type::const_iterator end = begin; + std::advance(end, remainder); + + // We're setting the body promise here to an empty string + // because + // this can be used as a signaling mechanism for the user to + // determine that the body is now ready for processing, even + // though the callback is already provided. + this->body_promise.set_value(""); + + // The invocation of the callback is synchronous to allow us + // to + // wait before scheduling another read. + callback(make_iterator_range(begin, end), ec); + + delegate_->read_some( + boost::asio::mutable_buffers_1(this->part.c_array(), + this->part.size()), + request_strand_.wrap(boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), body, get_body, callback, + placeholders::error, placeholders::bytes_transferred))); + } else { + // Here we handle the body data ourself and append to an + // ever-growing string buffer. + this->parse_body( + delegate_, + request_strand_.wrap(boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), body, get_body, callback, + placeholders::error, placeholders::bytes_transferred)), + remainder); + } + return; + case body: + if (ec == boost::asio::error::eof || is_ssl_short_read_error) { + // Here we're handling the case when the connection has been + // closed from the server side, or at least that the end of + // file + // has been reached while reading the socket. This signals + // the end + // of the body processing chain. + if (callback) { + typename protocol_base::buffer_type::const_iterator + begin = this->part.begin(), + end = begin; + std::advance(end, bytes_transferred); + + // We call the callback function synchronously passing the + // error + // condition (in this case, end of file) so that it can + // handle + // it appropriately. + callback(make_iterator_range(begin, end), ec); + } else { + string_type body_string; + std::swap(body_string, this->partial_parsed); + body_string.append(this->part.begin(), bytes_transferred); + if (this->is_chunk_encoding) + this->body_promise.set_value(parse_chunk_encoding(body_string)); + else + this->body_promise.set_value(body_string); + } + // TODO set the destination value somewhere! + this->destination_promise.set_value(""); + this->source_promise.set_value(""); + this->part.assign('\0'); + this->response_parser_.reset(); + this->timer_.cancel(); + } else { + // This means the connection has not been closed yet and we + // want + // to get more + // data. + if (callback) { + // Here we have a body_handler callback. Let's invoke the + // callback from here and make sure we're getting more + // data + // right after. + typename protocol_base::buffer_type::const_iterator begin = + this->part.begin(); + typename protocol_base::buffer_type::const_iterator end = begin; + std::advance(end, bytes_transferred); + callback(make_iterator_range(begin, end), ec); + delegate_->read_some( + boost::asio::mutable_buffers_1(this->part.c_array(), + this->part.size()), + request_strand_.wrap(boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), body, get_body, callback, + placeholders::error, placeholders::bytes_transferred))); + } else { + // Here we don't have a body callback. Let's + // make sure that we deal with the remainder + // from the headers part in case we do have data + // that's still in the buffer. + this->parse_body( + delegate_, + request_strand_.wrap(boost::bind( + &this_type::handle_received_data, + this_type::shared_from_this(), body, get_body, callback, + placeholders::error, placeholders::bytes_transferred)), + bytes_transferred); + } + } + return; + default: + BOOST_ASSERT(false && "Bug, report this to the developers!"); + } + } else { + boost::system::system_error error(is_timedout_ ? asio::error::timed_out + : ec); + this->source_promise.set_exception(boost::copy_exception(error)); + this->destination_promise.set_exception(boost::copy_exception(error)); + switch (state) { + case version: + this->version_promise.set_exception(boost::copy_exception(error)); + case status: + this->status_promise.set_exception(boost::copy_exception(error)); + case status_message: + this->status_message_promise.set_exception( + boost::copy_exception(error)); + case headers: + this->headers_promise.set_exception(boost::copy_exception(error)); + case body: + if (!callback) { + // N.B. if callback is non-null, then body_promise has + // already been set to value "" to indicate body is + // handled by streaming handler so no exception should be set + this->body_promise.set_exception(boost::copy_exception(error)); + } + break; + default: + BOOST_ASSERT(false && "Bug, report this to the developers!"); + } + } + } + + string_type parse_chunk_encoding(string_type& body_string) { + string_type body; + string_type crlf = "\r\n"; + + typename string_type::iterator begin = body_string.begin(); + for (typename string_type::iterator iter = + std::search(begin, body_string.end(), crlf.begin(), crlf.end()); + iter != body_string.end(); + iter = + std::search(begin, body_string.end(), crlf.begin(), crlf.end())) { + string_type line(begin, iter); + if (line.empty()) break; + std::stringstream stream(line); + int len; + stream >> std::hex >> len; + std::advance(iter, 2); + if (!len) break; + if (len <= body_string.end() - iter) { + body.insert(body.end(), iter, iter + len); + std::advance(iter, len + 2); + } + begin = iter; + } + + return body; + } + + int timeout_; + boost::asio::deadline_timer timer_; + bool is_timedout_; + bool follow_redirect_; + resolver_type& resolver_; + resolve_function resolve_; + boost::asio::io_service::strand request_strand_; + connection_delegate_ptr delegate_; + boost::asio::streambuf command_streambuf; + string_type method; +}; + +} // namespace impl +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_CONNECTION_HPP_20100601 diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/async_protocol_handler.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/async_protocol_handler.hpp new file mode 100644 index 00000000..7c8792ae --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/async_protocol_handler.hpp @@ -0,0 +1,356 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_PROTOCOL_HANDLER_HPP_ +#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_PROTOCOL_HANDLER_HPP_ + +// Copyright 2010 (C) Dean Michael Berris +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { +namespace impl { + +template +struct http_async_protocol_handler { + protected: + typedef typename string::type string_type; + +#ifdef BOOST_NETWORK_DEBUG + struct debug_escaper { + string_type& string; + explicit debug_escaper(string_type& string_) : string(string_) {} + debug_escaper(debug_escaper const& other) : string(other.string) {} + void operator()(typename string_type::value_type input) { + if (!algorithm::is_print()(input)) { + typename ostringstream::type escaped_stream; + if (input == '\r') { + string.append("\\r"); + } else if (input == '\n') { + string.append("\\n"); + } else { + escaped_stream << "\\x" << static_cast(input); + string.append(escaped_stream.str()); + } + } else { + string.push_back(input); + } + } + }; +#endif + + template + void init_response(ResponseType& response_, bool get_body) { + // TODO(dberris): review parameter necessity. + (void)get_body; + + boost::shared_future source_future( + source_promise.get_future()); + source(response_, source_future); + + boost::shared_future destination_future( + destination_promise.get_future()); + destination(response_, destination_future); + + boost::shared_future::type> headers_future( + headers_promise.get_future()); + headers(response_, headers_future); + + boost::shared_future body_future(body_promise.get_future()); + body(response_, body_future); + + boost::shared_future version_future( + version_promise.get_future()); + version(response_, version_future); + + boost::shared_future status_future( + status_promise.get_future()); + status(response_, status_future); + + boost::shared_future status_message_future( + status_message_promise.get_future()); + status_message(response_, status_message_future); + } + + struct to_http_headers { + typedef typename string::type string_type; + template + string_type const operator()(U const& pair) const { + typedef typename ostringstream::type ostringstream_type; + typedef constants constants; + ostringstream_type header_line; + header_line << pair.first << constants::colon() << constants::space() + << pair.second << constants::crlf(); + return header_line.str(); + } + }; + + template + logic::tribool parse_version(Delegate& delegate_, Callback callback, + size_t bytes) { + logic::tribool parsed_ok; + part_begin = part.begin(); + typename buffer_type::const_iterator part_end = part.begin(); + std::advance(part_end, bytes); + typename boost::iterator_range + result_range, + input_range = boost::make_iterator_range(part_begin, part_end); + fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( + response_parser_type::http_version_done, input_range); + if (parsed_ok == true) { + string_type version; + std::swap(version, partial_parsed); + version.append(boost::begin(result_range), boost::end(result_range)); + algorithm::trim(version); + version_promise.set_value(version); + part_begin = boost::end(result_range); + } else if (parsed_ok == false) { +#ifdef BOOST_NETWORK_DEBUG + string_type escaped; + debug_escaper escaper(escaped); + std::for_each(part_begin, part_end, escaper); + BOOST_NETWORK_MESSAGE("[parser:" << response_parser_.state() + << "] buffer contents: \"" << escaped + << "\""); +#endif + std::runtime_error error("Invalid Version Part."); + version_promise.set_exception(boost::copy_exception(error)); + status_promise.set_exception(boost::copy_exception(error)); + status_message_promise.set_exception(boost::copy_exception(error)); + headers_promise.set_exception(boost::copy_exception(error)); + source_promise.set_exception(boost::copy_exception(error)); + destination_promise.set_exception(boost::copy_exception(error)); + body_promise.set_exception(boost::copy_exception(error)); + } else { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + part_begin = part.begin(); + delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), + callback); + } + return parsed_ok; + } + + template + logic::tribool parse_status(Delegate& delegate_, Callback callback, + size_t bytes) { + logic::tribool parsed_ok; + typename buffer_type::const_iterator part_end = part.begin(); + std::advance(part_end, bytes); + typename boost::iterator_range + result_range, + input_range = boost::make_iterator_range(part_begin, part_end); + fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( + response_parser_type::http_status_done, input_range); + if (parsed_ok == true) { + string_type status; + std::swap(status, partial_parsed); + status.append(boost::begin(result_range), boost::end(result_range)); + trim(status); + boost::uint16_t status_int = lexical_cast(status); + status_promise.set_value(status_int); + part_begin = boost::end(result_range); + } else if (parsed_ok == false) { +#ifdef BOOST_NETWORK_DEBUG + string_type escaped; + debug_escaper escaper(escaped); + std::for_each(part_begin, part_end, escaper); + BOOST_NETWORK_MESSAGE("[parser:" << response_parser_.state() + << "] buffer contents: \"" << escaped + << "\""); +#endif + std::runtime_error error("Invalid status part."); + status_promise.set_exception(boost::copy_exception(error)); + status_message_promise.set_exception(boost::copy_exception(error)); + headers_promise.set_exception(boost::copy_exception(error)); + source_promise.set_exception(boost::copy_exception(error)); + destination_promise.set_exception(boost::copy_exception(error)); + body_promise.set_exception(boost::copy_exception(error)); + } else { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + part_begin = part.begin(); + delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), + callback); + } + return parsed_ok; + } + + template + logic::tribool parse_status_message(Delegate& delegate_, Callback callback, + size_t bytes) { + logic::tribool parsed_ok; + typename buffer_type::const_iterator part_end = part.begin(); + std::advance(part_end, bytes); + typename boost::iterator_range + result_range, + input_range = boost::make_iterator_range(part_begin, part_end); + fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( + response_parser_type::http_status_message_done, input_range); + if (parsed_ok == true) { + string_type status_message; + std::swap(status_message, partial_parsed); + status_message.append(boost::begin(result_range), + boost::end(result_range)); + algorithm::trim(status_message); + status_message_promise.set_value(status_message); + part_begin = boost::end(result_range); + } else if (parsed_ok == false) { +#ifdef BOOST_NETWORK_DEBUG + string_type escaped; + debug_escaper escaper(escaped); + std::for_each(part_begin, part_end, escaper); + BOOST_NETWORK_MESSAGE("[parser:" << response_parser_.state() + << "] buffer contents: \"" << escaped + << "\""); +#endif + std::runtime_error error("Invalid status message part."); + status_message_promise.set_exception(boost::copy_exception(error)); + headers_promise.set_exception(boost::copy_exception(error)); + source_promise.set_exception(boost::copy_exception(error)); + destination_promise.set_exception(boost::copy_exception(error)); + body_promise.set_exception(boost::copy_exception(error)); + } else { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + part_begin = part.begin(); + delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), + callback); + } + return parsed_ok; + } + + void parse_headers_real(string_type& headers_part) { + typename boost::iterator_range + input_range = boost::make_iterator_range(headers_part), + result_range; + logic::tribool parsed_ok; + response_parser_type headers_parser( + response_parser_type::http_header_line_done); + typename headers_container::type headers; + std::pair header_pair; + while (!boost::empty(input_range)) { + fusion::tie(parsed_ok, result_range) = headers_parser.parse_until( + response_parser_type::http_header_colon, input_range); + if (headers_parser.state() != response_parser_type::http_header_colon) + break; + header_pair.first = + string_type(boost::begin(result_range), boost::end(result_range)); + input_range.advance_begin(boost::distance(result_range)); + fusion::tie(parsed_ok, result_range) = headers_parser.parse_until( + response_parser_type::http_header_line_done, input_range); + header_pair.second = + string_type(boost::begin(result_range), boost::end(result_range)); + input_range.advance_begin(boost::distance(result_range)); + + trim(header_pair.first); + if (header_pair.first.size() > 1) { + header_pair.first.erase(header_pair.first.size() - 1); + } + trim(header_pair.second); + headers.insert(header_pair); + } + // determine if the body parser will need to handle chunked encoding + typename headers_range >::type transfer_encoding_range = + headers.equal_range("Transfer-Encoding"); + is_chunk_encoding = + !boost::empty(transfer_encoding_range) && + boost::iequals(boost::begin(transfer_encoding_range)->second, + "chunked"); + headers_promise.set_value(headers); + } + + template + fusion::tuple parse_headers(Delegate& delegate_, + Callback callback, + size_t bytes) { + logic::tribool parsed_ok; + typename buffer_type::const_iterator part_end = part.begin(); + std::advance(part_end, bytes); + typename boost::iterator_range + result_range, + input_range = boost::make_iterator_range(part_begin, part_end); + fusion::tie(parsed_ok, result_range) = response_parser_.parse_until( + response_parser_type::http_headers_done, input_range); + if (parsed_ok == true) { + string_type headers_string; + std::swap(headers_string, partial_parsed); + headers_string.append(boost::begin(result_range), + boost::end(result_range)); + part_begin = boost::end(result_range); + this->parse_headers_real(headers_string); + } else if (parsed_ok == false) { +// We want to output the contents of the buffer that caused +// the error in debug builds. +#ifdef BOOST_NETWORK_DEBUG + string_type escaped; + debug_escaper escaper(escaped); + std::for_each(part_begin, part_end, escaper); + BOOST_NETWORK_MESSAGE("[parser:" << response_parser_.state() + << "] buffer contents: \"" << escaped + << "\" consumed length: " + << boost::distance(result_range)); +#endif + std::runtime_error error("Invalid header part."); + headers_promise.set_exception(boost::copy_exception(error)); + body_promise.set_exception(boost::copy_exception(error)); + source_promise.set_exception(boost::copy_exception(error)); + destination_promise.set_exception(boost::copy_exception(error)); + } else { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + part_begin = part.begin(); + delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), + callback); + } + return fusion::make_tuple( + parsed_ok, std::distance(boost::end(result_range), part_end)); + } + + template + void parse_body(Delegate& delegate_, Callback callback, size_t bytes) { + // TODO: we should really not use a string for the partial body + // buffer. + partial_parsed.append(part_begin, bytes); + part_begin = part.begin(); + delegate_->read_some( + boost::asio::mutable_buffers_1(part.c_array(), part.size()), callback); + } + + typedef response_parser response_parser_type; + // TODO: make 1024 go away and become a configurable value. + typedef boost::array::type, 1024> buffer_type; + + response_parser_type response_parser_; + boost::promise version_promise; + boost::promise status_promise; + boost::promise status_message_promise; + boost::promise::type> headers_promise; + boost::promise source_promise; + boost::promise destination_promise; + boost::promise body_promise; + buffer_type part; + typename buffer_type::const_iterator part_begin; + string_type partial_parsed; + bool is_chunk_encoding; +}; + +} /* impl */ + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_PROTOCOL_HANDLER_HPP_20101015 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/connection_delegate.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/connection_delegate.hpp new file mode 100644 index 00000000..79fa1ca4 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/connection_delegate.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_DELEGATE_HPP_ +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_DELEGATE_HPP_ + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +namespace boost { +namespace network { +namespace http { +namespace impl { + +struct connection_delegate { + virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, + function handler) = 0; + virtual void write( + asio::streambuf &command_streambuf, + function handler) = 0; + virtual void read_some( + asio::mutable_buffers_1 const &read_buffer, + function handler) = 0; + virtual void disconnect() = 0; + virtual ~connection_delegate() {} +}; + +} /* impl */ + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_CONNECTION_DELEGATE_HPP_ \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp new file mode 100644 index 00000000..425cc27e --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/connection_delegate_factory.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_DELEGATE_FACTORY_HPP_20110819 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_DELEGATE_FACTORY_HPP_20110819 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include +#include +#ifdef BOOST_NETWORK_ENABLE_HTTPS +#include +#endif /* BOOST_NETWORK_ENABLE_HTTPS */ + +namespace boost { +namespace network { +namespace http { +namespace impl { + +struct ssl_delegate; + +struct normal_delegate; + +template +struct connection_delegate_factory { + typedef shared_ptr connection_delegate_ptr; + typedef typename string::type string_type; + + // This is the factory method that actually returns the delegate + // instance. + // TODO Support passing in proxy settings when crafting connections. + static connection_delegate_ptr new_connection_delegate( + asio::io_service& service, bool https, bool always_verify_peer, + optional certificate_filename, + optional verify_path, optional certificate_file, + optional private_key_file, optional ciphers, + long ssl_options) { + connection_delegate_ptr delegate; + if (https) { +#ifdef BOOST_NETWORK_ENABLE_HTTPS + delegate.reset(new ssl_delegate( + service, always_verify_peer, certificate_filename, verify_path, + certificate_file, private_key_file, ciphers, ssl_options)); +#else + BOOST_THROW_EXCEPTION(std::runtime_error("HTTPS not supported.")); +#endif /* BOOST_NETWORK_ENABLE_HTTPS */ + } else { + delegate.reset(new normal_delegate(service)); + } + return delegate; + } +}; + +} /* impl */ +} /* http */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_DELEGATE_FACTORY_HPP_20110819 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/normal_delegate.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/normal_delegate.hpp new file mode 100644 index 00000000..ae6ace33 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/normal_delegate.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_NORMAL_DELEGATE_20110819 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_NORMAL_DELEGATE_20110819 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { +namespace impl { + +struct normal_delegate : connection_delegate { + normal_delegate(asio::io_service &service); + + virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, + function handler); + virtual void write( + asio::streambuf &command_streambuf, + function handler); + virtual void read_some( + asio::mutable_buffers_1 const &read_buffer, + function handler); + virtual void disconnect(); + ~normal_delegate(); + + private: + asio::io_service &service_; + scoped_ptr socket_; + + normal_delegate(normal_delegate const &); // = delete + normal_delegate &operator=(normal_delegate); // = delete +}; + +} /* impl */ + +} /* http */ + +} /* network */ + +} /* boost */ + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif /* BOOST_NETWORK_NO_LIB */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_NORMAL_DELEGATE_20110819 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/normal_delegate.ipp b/cpp-netlib/boost/network/protocol/http/client/connection/normal_delegate.ipp new file mode 100644 index 00000000..bc41d9c6 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/normal_delegate.ipp @@ -0,0 +1,57 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_NORMAL_DELEGATE_IPP_20110819 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_NORMAL_DELEGATE_IPP_20110819 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include +#include +#include +#include +#include + +boost::network::http::impl::normal_delegate::normal_delegate( + asio::io_service &service) + : service_(service) {} + +void boost::network::http::impl::normal_delegate::connect( + asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, + function handler) { + + // TODO(dberris): review parameter necessity. + (void)host; + + socket_.reset(new asio::ip::tcp::socket(service_)); + socket_->async_connect(endpoint, handler); +} + +void boost::network::http::impl::normal_delegate::write( + asio::streambuf &command_streambuf, + function handler) { + asio::async_write(*socket_, command_streambuf, handler); +} + +void boost::network::http::impl::normal_delegate::read_some( + asio::mutable_buffers_1 const &read_buffer, + function handler) { + socket_->async_read_some(read_buffer, handler); +} + +void boost::network::http::impl::normal_delegate::disconnect() { + if (socket_.get() && socket_->is_open()) { + boost::system::error_code ignored; + socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored); + if (!ignored) { + socket_->close(ignored); + } + } +} + +boost::network::http::impl::normal_delegate::~normal_delegate() {} + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_NORMAL_DELEGATE_IPP_20110819 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/ssl_delegate.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/ssl_delegate.hpp new file mode 100644 index 00000000..712fc517 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/ssl_delegate.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SSL_DELEGATE_20110819 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SSL_DELEGATE_20110819 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { +namespace impl { + +struct ssl_delegate : connection_delegate, + enable_shared_from_this { + ssl_delegate(asio::io_service &service, bool always_verify_peer, + optional certificate_filename, + optional verify_path, + optional certificate_file, + optional private_key_file, + optional ciphers, long ssl_options); + + virtual void connect(asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, + function handler); + virtual void write( + asio::streambuf &command_streambuf, + function handler); + virtual void read_some( + asio::mutable_buffers_1 const &read_buffer, + function handler); + virtual void disconnect(); + ~ssl_delegate(); + + private: + asio::io_service &service_; + optional certificate_filename_; + optional verify_path_; + optional certificate_file_; + optional private_key_file_; + optional ciphers_; + long ssl_options_; + scoped_ptr context_; + scoped_ptr tcp_socket_; + scoped_ptr > socket_; + bool always_verify_peer_; + + ssl_delegate(ssl_delegate const &); // = delete + ssl_delegate &operator=(ssl_delegate); // = delete + + void handle_connected(system::error_code const &ec, + function handler); +}; + +} /* impl */ + +} /* http */ + +} /* network */ + +} /* boost */ + +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif /* BOOST_NETWORK_NO_LIB */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SSL_DELEGATE_20110819 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/ssl_delegate.ipp b/cpp-netlib/boost/network/protocol/http/client/connection/ssl_delegate.ipp new file mode 100644 index 00000000..71161ba4 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/ssl_delegate.ipp @@ -0,0 +1,113 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SSL_DELEGATE_IPP_20110819 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SSL_DELEGATE_IPP_20110819 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include +#include + +boost::network::http::impl::ssl_delegate::ssl_delegate( + asio::io_service &service, bool always_verify_peer, + optional certificate_filename, + optional verify_path, + optional certificate_file, + optional private_key_file, + optional ciphers, + long ssl_options) + : service_(service), + certificate_filename_(certificate_filename), + verify_path_(verify_path), + certificate_file_(certificate_file), + private_key_file_(private_key_file), + ciphers_(ciphers), + ssl_options_(ssl_options), + always_verify_peer_(always_verify_peer) {} + +void boost::network::http::impl::ssl_delegate::connect( + asio::ip::tcp::endpoint &endpoint, std::string host, boost::uint16_t source_port, + function handler) { + context_.reset( + new asio::ssl::context(service_, asio::ssl::context::sslv23_client)); + if (ciphers_) { + ::SSL_CTX_set_cipher_list(context_->native_handle(), ciphers_->c_str()); + } + if (ssl_options_ != 0) { + context_->set_options(ssl_options_); + } + if (certificate_filename_ || verify_path_) { + context_->set_verify_mode(asio::ssl::context::verify_peer); + if (certificate_filename_) + context_->load_verify_file(*certificate_filename_); + if (verify_path_) context_->add_verify_path(*verify_path_); + } else { + if (always_verify_peer_) { + context_->set_verify_mode(asio::ssl::context::verify_peer); + // use openssl default verify paths. uses openssl environment variables + // SSL_CERT_DIR, SSL_CERT_FILE + context_->set_default_verify_paths(); + } else + context_->set_verify_mode(asio::ssl::context::verify_none); + } + if (certificate_file_) + context_->use_certificate_file(*certificate_file_, + boost::asio::ssl::context::pem); + if (private_key_file_) + context_->use_private_key_file(*private_key_file_, + boost::asio::ssl::context::pem); + + tcp_socket_.reset(new asio::ip::tcp::socket(service_, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), source_port))); + socket_.reset( + new asio::ssl::stream(*(tcp_socket_.get()), *context_)); + + if (always_verify_peer_) + socket_->set_verify_callback(boost::asio::ssl::rfc2818_verification(host)); + socket_->lowest_layer().async_connect( + endpoint, + ::boost::bind( + &boost::network::http::impl::ssl_delegate::handle_connected, + boost::network::http::impl::ssl_delegate::shared_from_this(), + asio::placeholders::error, handler)); +} + +void boost::network::http::impl::ssl_delegate::handle_connected( + system::error_code const &ec, + function handler) { + if (!ec) { + socket_->async_handshake(asio::ssl::stream_base::client, handler); + } else { + handler(ec); + } +} + +void boost::network::http::impl::ssl_delegate::write( + asio::streambuf &command_streambuf, + function handler) { + asio::async_write(*socket_, command_streambuf, handler); +} + +void boost::network::http::impl::ssl_delegate::read_some( + asio::mutable_buffers_1 const &read_buffer, + function handler) { + socket_->async_read_some(read_buffer, handler); +} + +void boost::network::http::impl::ssl_delegate::disconnect() { + if (socket_.get() && socket_->lowest_layer().is_open()) { + boost::system::error_code ignored; + socket_->lowest_layer().shutdown( + boost::asio::ip::tcp::socket::shutdown_both, ignored); + if (!ignored) { + socket_->lowest_layer().close(ignored); + } + } +} + +boost::network::http::impl::ssl_delegate::~ssl_delegate() {} + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SSL_DELEGATE_IPP_20110819 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/sync_base.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/sync_base.hpp new file mode 100644 index 00000000..4b81220f --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/sync_base.hpp @@ -0,0 +1,302 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_SYNC_CONNECTION_BASE_20091217 +#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_SYNC_CONNECTION_BASE_20091217 + +// Copyright 2013 Google, Inc. +// Copyright 2009 Dean Michael Berris +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef BOOST_NETWORK_ENABLE_HTTPS +#include +#endif + +namespace boost { +namespace network { +namespace http { +namespace impl { + +template +struct sync_connection_base_impl { + protected: + typedef typename resolver_policy::type resolver_base; + typedef typename resolver_base::resolver_type resolver_type; + typedef typename string::type string_type; + typedef function + resolver_function_type; + + template + void init_socket(Socket& socket_, resolver_type& resolver_, + string_type const& hostname, string_type const& port, + resolver_function_type resolve_) { + using boost::asio::ip::tcp; + boost::system::error_code error = boost::asio::error::host_not_found; + typename resolver_type::iterator endpoint_iterator, end; + boost::tie(endpoint_iterator, end) = resolve_(resolver_, hostname, port); + while (error && endpoint_iterator != end) { + socket_.close(); + socket_.connect(tcp::endpoint(endpoint_iterator->endpoint().address(), + endpoint_iterator->endpoint().port()), + error); + ++endpoint_iterator; + } + + if (error) throw boost::system::system_error(error); + } + + template + void read_status(Socket& socket_, basic_response& response_, + boost::asio::streambuf& response_buffer) { + boost::asio::read_until(socket_, response_buffer, "\r\n"); + std::istream response_stream(&response_buffer); + string_type http_version; + unsigned int status_code; + string_type status_message; + response_stream >> http_version >> status_code; + std::getline(response_stream, status_message); + trim_left(status_message); + trim_right_if(status_message, boost::is_space() || boost::is_any_of("\r")); + + if (!response_stream || http_version.substr(0, 5) != "HTTP/") + throw std::runtime_error("Invalid response"); + + response_ << http::version(http_version) << http::status(status_code) + << http::status_message(status_message); + } + + template + void read_headers(Socket& socket_, basic_response& response_, + boost::asio::streambuf& response_buffer) { + boost::asio::read_until(socket_, response_buffer, "\r\n\r\n"); + std::istream response_stream(&response_buffer); + string_type header_line, name; + while (std::getline(response_stream, header_line) && header_line != "\r") { + trim_right_if(header_line, boost::is_space() || boost::is_any_of("\r")); + typename string_type::size_type colon_offset; + if (header_line.size() && header_line[0] == ' ') { + assert(!name.empty()); + if (name.empty()) + throw std::runtime_error(std::string("Malformed header: ") + + header_line); + response_ << header(name, trim_left_copy(header_line)); + } else if ((colon_offset = header_line.find_first_of(':')) != + string_type::npos) { + name = header_line.substr(0, colon_offset); + response_ << header(name, header_line.substr(colon_offset + 2)); + } + } + } + + template + void send_request_impl(Socket& socket_, string_type const& method, + boost::asio::streambuf& request_buffer) { + // TODO(dberris): review parameter necessity. + (void)method; + + write(socket_, request_buffer); + } + + template + void read_body_normal(Socket& socket_, basic_response& response_, + boost::asio::streambuf& response_buffer, + typename ostringstream::type& body_stream) { + // TODO(dberris): review parameter necessity. + (void)response_; + + boost::system::error_code error; + if (response_buffer.size() > 0) body_stream << &response_buffer; + + while (boost::asio::read(socket_, response_buffer, + boost::asio::transfer_at_least(1), error)) { + body_stream << &response_buffer; + } + } + + template + void read_body_transfer_chunk_encoding( + Socket& socket_, basic_response& response_, + boost::asio::streambuf& response_buffer, + typename ostringstream::type& body_stream) { + boost::system::error_code error; + // look for the content-length header + typename headers_range >::type content_length_range = + headers(response_)["Content-Length"]; + if (boost::empty(content_length_range)) { + typename headers_range >::type + transfer_encoding_range = headers(response_)["Transfer-Encoding"]; + if (boost::empty(transfer_encoding_range)) { + read_body_normal(socket_, response_, response_buffer, body_stream); + return; + } + if (boost::iequals(boost::begin(transfer_encoding_range)->second, + "chunked")) { + bool stopping = false; + do { + std::size_t chunk_size_line = + read_until(socket_, response_buffer, "\r\n", error); + if ((chunk_size_line == 0) && (error != boost::asio::error::eof)) + throw boost::system::system_error(error); + std::size_t chunk_size = 0; + string_type data; + { + std::istream chunk_stream(&response_buffer); + std::getline(chunk_stream, data); + typename istringstream::type chunk_size_stream(data); + chunk_size_stream >> std::hex >> chunk_size; + } + if (chunk_size == 0) { + stopping = true; + if (!read_until(socket_, response_buffer, "\r\n", error) && + (error != boost::asio::error::eof)) + throw boost::system::system_error(error); + } else { + bool stopping_inner = false; + do { + if (response_buffer.size() < (chunk_size + 2)) { + std::size_t bytes_to_read = + (chunk_size + 2) - response_buffer.size(); + std::size_t chunk_bytes_read = + read(socket_, response_buffer, + boost::asio::transfer_at_least(bytes_to_read), error); + if (chunk_bytes_read == 0) { + if (error != boost::asio::error::eof) + throw boost::system::system_error(error); + stopping_inner = true; + } + } + + std::istreambuf_iterator eos; + std::istreambuf_iterator stream_iterator(&response_buffer); + for (; chunk_size > 0 && stream_iterator != eos; --chunk_size) + body_stream << *stream_iterator++; + response_buffer.consume(2); + } while (!stopping_inner && chunk_size != 0); + + if (chunk_size != 0) + throw std::runtime_error( + "Size mismatch between tranfer encoding chunk data " + "size and declared chunk size."); + } + } while (!stopping); + } else + throw std::runtime_error("Unsupported Transfer-Encoding."); + } else { + size_t already_read = response_buffer.size(); + if (already_read) body_stream << &response_buffer; + size_t length = + lexical_cast(boost::begin(content_length_range)->second) - + already_read; + if (length == 0) return; + size_t bytes_read = 0; + while ((bytes_read = boost::asio::read(socket_, response_buffer, + boost::asio::transfer_at_least(1), + error))) { + body_stream << &response_buffer; + length -= bytes_read; + if ((length <= 0) || error) break; + } + } + } + + template + void read_body(Socket& socket_, basic_response& response_, + boost::asio::streambuf& response_buffer) { + typename ostringstream::type body_stream; + // TODO tag dispatch based on whether it's HTTP 1.0 or HTTP 1.1 + if (version_major == 1 && version_minor == 0) { + read_body_normal(socket_, response_, response_buffer, body_stream); + } else if (version_major == 1 && version_minor == 1) { + if (response_.version() == "HTTP/1.0") + read_body_normal(socket_, response_, response_buffer, body_stream); + else + read_body_transfer_chunk_encoding(socket_, response_, response_buffer, + body_stream); + } else { + throw std::runtime_error("Unsupported HTTP version number."); + } + + response_ << network::body(body_stream.str()); + } +}; + +template +struct sync_connection_base { + typedef typename resolver_policy::type resolver_base; + typedef typename resolver_base::resolver_type resolver_type; + typedef typename string::type string_type; + typedef function + resolver_function_type; + typedef function body_generator_function_type; + + // FIXME make the certificate filename and verify path parameters be + // optional + // ranges + static sync_connection_base* + new_connection( + resolver_type& resolver, resolver_function_type resolve, bool https, + bool always_verify_peer, int timeout, + optional const& certificate_filename = + optional(), + optional const& verify_path = optional(), + optional const& certificate_file = + optional(), + optional const& private_key_file = + optional(), + optional const& ciphers = optional(), + long ssl_options = 0) { + if (https) { +#ifdef BOOST_NETWORK_ENABLE_HTTPS + return dynamic_cast< + sync_connection_base*>( + new https_sync_connection( + resolver, resolve, always_verify_peer, timeout, + certificate_filename, verify_path, certificate_file, + private_key_file, ciphers, ssl_options)); +#else + throw std::runtime_error("HTTPS not supported."); +#endif + } + return dynamic_cast< + sync_connection_base*>( + new http_sync_connection( + resolver, resolve, timeout)); + } + + virtual void init_socket(string_type const& hostname, + string_type const& port) = 0; + virtual void send_request_impl(string_type const& method, + basic_request const& request_, + body_generator_function_type generator) = 0; + virtual void read_status(basic_response& response_, + boost::asio::streambuf& response_buffer) = 0; + virtual void read_headers(basic_response& response_, + boost::asio::streambuf& response_buffer) = 0; + virtual void read_body(basic_response& response_, + boost::asio::streambuf& response_buffer) = 0; + virtual bool is_open() = 0; + virtual void close_socket() = 0; + virtual ~sync_connection_base() {} + + protected: + sync_connection_base() {} +}; + +} // namespace impl +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_IMPL_SYNC_CONNECTION_BASE_20091217 diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/sync_normal.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/sync_normal.hpp new file mode 100644 index 00000000..e9d3f326 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/sync_normal.hpp @@ -0,0 +1,134 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_SYNC_CONNECTION_20100601 +#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_SYNC_CONNECTION_20100601 + +// Copyright 2013 Google, Inc. +// Copyright 2010 (C) Dean Michael Berris +// Copyright 2010 (C) Sinefunc, Inc. +// 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) + +#include +#include + +#include + +namespace boost { +namespace network { +namespace http { +namespace impl { + +template +struct sync_connection_base_impl; + +template +struct sync_connection_base; + +template +struct http_sync_connection + : public virtual sync_connection_base, + sync_connection_base_impl, + boost::enable_shared_from_this< + http_sync_connection > { + typedef typename resolver_policy::type resolver_base; + typedef typename resolver_base::resolver_type resolver_type; + typedef typename string::type string_type; + typedef function + resolver_function_type; + typedef http_sync_connection this_type; + typedef sync_connection_base_impl + connection_base; + typedef function body_generator_function_type; + + http_sync_connection(resolver_type& resolver, resolver_function_type resolve, + int timeout) + : connection_base(), + timeout_(timeout), + timer_(resolver.get_io_service()), + resolver_(resolver), + resolve_(resolve), + socket_(resolver.get_io_service()) {} + + void init_socket(string_type const& hostname, string_type const& port) { + connection_base::init_socket(socket_, resolver_, hostname, port, resolve_); + } + + void send_request_impl(string_type const& method, + basic_request const& request_, + body_generator_function_type generator) { + boost::asio::streambuf request_buffer; + linearize( + request_, method, version_major, version_minor, + std::ostreambuf_iterator::type>(&request_buffer)); + connection_base::send_request_impl(socket_, method, request_buffer); + if (generator) { + string_type chunk; + while (generator(chunk)) { + std::copy(chunk.begin(), chunk.end(), + std::ostreambuf_iterator::type>( + &request_buffer)); + chunk.clear(); + connection_base::send_request_impl(socket_, method, request_buffer); + } + } + if (timeout_ > 0) { + timer_.expires_from_now(boost::posix_time::seconds(timeout_)); + timer_.async_wait(boost::bind(&this_type::handle_timeout, + this_type::shared_from_this(), + boost::arg<1>())); + } + } + + void read_status(basic_response& response_, + boost::asio::streambuf& response_buffer) { + connection_base::read_status(socket_, response_, response_buffer); + } + + void read_headers(basic_response& response, + boost::asio::streambuf& response_buffer) { + connection_base::read_headers(socket_, response, response_buffer); + } + + void read_body(basic_response& response_, + boost::asio::streambuf& response_buffer) { + connection_base::read_body(socket_, response_, response_buffer); + typename headers_range >::type connection_range = + headers(response_)["Connection"]; + if (version_major == 1 && version_minor == 1 && !boost::empty(connection_range) && + boost::iequals(boost::begin(connection_range)->second, "close")) { + close_socket(); + } else if (version_major == 1 && version_minor == 0) { + close_socket(); + } + } + + bool is_open() { return socket_.is_open(); } + + void close_socket() { + timer_.cancel(); + if (!is_open()) return; + boost::system::error_code ignored; + socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored); + if (ignored) return; + socket_.close(ignored); + } + + private: + void handle_timeout(boost::system::error_code const& ec) { + if (!ec) close_socket(); + } + + int timeout_; + boost::asio::deadline_timer timer_; + resolver_type& resolver_; + resolver_function_type resolve_; + boost::asio::ip::tcp::socket socket_; +}; + +} // namespace impl +} // nmaespace http +} // namespace network +} // nmaespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_SYNC_CONNECTION_20100 diff --git a/cpp-netlib/boost/network/protocol/http/client/connection/sync_ssl.hpp b/cpp-netlib/boost/network/protocol/http/client/connection/sync_ssl.hpp new file mode 100644 index 00000000..7561289d --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/connection/sync_ssl.hpp @@ -0,0 +1,184 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTPS_SYNC_CONNECTION_HTTP_20100601 +#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTPS_SYNC_CONNECTION_HTTP_20100601 + +// Copyright 2013 Google, Inc. +// Copyright 2010 (C) Dean Michael Berris +// Copyright 2010 (C) Sinefunc, Inc. +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { +namespace impl { + +template +struct sync_connection_base_impl; + +template +struct sync_connection_base; + +template +struct https_sync_connection + : public virtual sync_connection_base, + sync_connection_base_impl, + boost::enable_shared_from_this< + https_sync_connection > { + typedef typename resolver_policy::type resolver_base; + typedef typename resolver_base::resolver_type resolver_type; + typedef typename string::type string_type; + typedef function + resolver_function_type; + typedef https_sync_connection this_type; + typedef sync_connection_base_impl + connection_base; + typedef function body_generator_function_type; + + // FIXME make the certificate filename and verify path parameters be + // optional ranges + https_sync_connection( + resolver_type& resolver, resolver_function_type resolve, + bool always_verify_peer, int timeout, + optional const& certificate_filename = + optional(), + optional const& verify_path = optional(), + optional const& certificate_file = optional(), + optional const& private_key_file = optional(), + optional const& ciphers = optional(), + long ssl_options = 0) + : connection_base(), + timeout_(timeout), + timer_(resolver.get_io_service()), + resolver_(resolver), + resolve_(resolve), + context_(resolver.get_io_service(), + boost::asio::ssl::context::sslv23_client), + socket_(resolver.get_io_service(), context_) { + if (ciphers) { + ::SSL_CTX_set_cipher_list(context_.native_handle(), ciphers->c_str()); + } + if (ssl_options != 0) { + context_.set_options(ssl_options); + } + if (certificate_filename || verify_path) { + context_.set_verify_mode(boost::asio::ssl::context::verify_peer); + // FIXME make the certificate filename and verify path parameters + // be + // optional ranges + if (certificate_filename) + context_.load_verify_file(*certificate_filename); + if (verify_path) context_.add_verify_path(*verify_path); + } else { + if (always_verify_peer) + context_.set_verify_mode(boost::asio::ssl::context_base::verify_peer); + else + context_.set_verify_mode(boost::asio::ssl::context_base::verify_none); + } + if (certificate_file) + context_.use_certificate_file(*certificate_file, + boost::asio::ssl::context::pem); + if (private_key_file) + context_.use_private_key_file(*private_key_file, + boost::asio::ssl::context::pem); + } + + void init_socket(string_type const& hostname, string_type const& port) { + connection_base::init_socket(socket_.lowest_layer(), resolver_, hostname, + port, resolve_); + socket_.handshake(boost::asio::ssl::stream_base::client); + } + + void send_request_impl(string_type const& method, + basic_request const& request_, + body_generator_function_type generator) { + boost::asio::streambuf request_buffer; + linearize( + request_, method, version_major, version_minor, + std::ostreambuf_iterator::type>(&request_buffer)); + connection_base::send_request_impl(socket_, method, request_buffer); + if (generator) { + string_type chunk; + while (generator(chunk)) { + std::copy(chunk.begin(), chunk.end(), + std::ostreambuf_iterator::type>( + &request_buffer)); + chunk.clear(); + connection_base::send_request_impl(socket_, method, request_buffer); + } + } + if (timeout_ > 0) { + timer_.expires_from_now(boost::posix_time::seconds(timeout_)); + timer_.async_wait(boost::bind(&this_type::handle_timeout, + this_type::shared_from_this(), + boost::arg<1>())); + } + } + + void read_status(basic_response& response_, + boost::asio::streambuf& response_buffer) { + connection_base::read_status(socket_, response_, response_buffer); + } + + void read_headers(basic_response& response_, + boost::asio::streambuf& response_buffer) { + connection_base::read_headers(socket_, response_, response_buffer); + } + + void read_body(basic_response& response_, + boost::asio::streambuf& response_buffer) { + connection_base::read_body(socket_, response_, response_buffer); + typename headers_range >::type connection_range = + headers(response_)["Connection"]; + if (version_major == 1 && version_minor == 1 && !boost::empty(connection_range) && + boost::iequals(boost::begin(connection_range)->second, "close")) { + close_socket(); + } else if (version_major == 1 && version_minor == 0) { + close_socket(); + } + } + + bool is_open() { return socket_.lowest_layer().is_open(); } + + void close_socket() { + timer_.cancel(); + boost::system::error_code ignored; + socket_.lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, + ignored); + if (ignored) return; + socket_.lowest_layer().close(ignored); + } + + ~https_sync_connection() { close_socket(); } + + private: + void handle_timeout(boost::system::error_code const& ec) { + if (!ec) close_socket(); + } + + int timeout_; + boost::asio::deadline_timer timer_; + resolver_type& resolver_; + resolver_function_type resolve_; + boost::asio::ssl::context context_; + boost::asio::ssl::stream socket_; +}; + +} // namespace impl +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTPS_SYNC_CONNECTION_HTTP_20100601 diff --git a/cpp-netlib/boost/network/protocol/http/client/facade.hpp b/cpp-netlib/boost/network/protocol/http/client/facade.hpp new file mode 100644 index 00000000..68c02ce1 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/facade.hpp @@ -0,0 +1,174 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_FACADE_HPP_20100623 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_FACADE_HPP_20100623 + +// Copyright 2013 Google, Inc. +// Copyright 2010 Dean Michael Berris +// 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) + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +template +struct basic_response; + +template +struct basic_client_facade { + + typedef typename string::type string_type; + typedef basic_request request; + typedef basic_response response; + typedef basic_client_impl pimpl_type; + typedef function const&, + system::error_code const&)> body_callback_function_type; + typedef function body_generator_function_type; + + explicit basic_client_facade(client_options const& options) { + init_pimpl(options); + } + + ~basic_client_facade() { pimpl->wait_complete(); } + + response head(request const& request) { + return pimpl->request_skeleton(request, "HEAD", false, + body_callback_function_type(), + body_generator_function_type()); + } + + response get(request const& request, + body_callback_function_type body_handler = + body_callback_function_type()) { + return pimpl->request_skeleton(request, "GET", true, body_handler, + body_generator_function_type()); + } + + response post(request request, string_type const& body = string_type(), + string_type const& content_type = string_type(), + body_callback_function_type body_handler = + body_callback_function_type(), + body_generator_function_type body_generator = + body_generator_function_type()) { + if (body != string_type()) { + request << remove_header("Content-Length") + << header("Content-Length", + boost::lexical_cast(body.size())) + << boost::network::body(body); + } + typename headers_range >::type content_type_headers = + headers(request)["Content-Type"]; + if (content_type != string_type()) { + if (!boost::empty(content_type_headers)) + request << remove_header("Content-Type"); + request << header("Content-Type", content_type); + } else { + if (boost::empty(content_type_headers)) { + typedef typename char_::type char_type; + static char_type content_type[] = "x-application/octet-stream"; + request << header("Content-Type", content_type); + } + } + return pimpl->request_skeleton(request, "POST", true, body_handler, + body_generator); + } + + response post(request const& request, + body_generator_function_type body_generator, + body_callback_function_type callback = + body_generator_function_type()) { + return pimpl->request_skeleton(request, "POST", true, callback, + body_generator); + } + + response post(request const& request, body_callback_function_type callback, + body_generator_function_type body_generator = + body_generator_function_type()) { + return post(request, string_type(), string_type(), callback, + body_generator); + } + + response post(request const& request, string_type const& body, + body_callback_function_type callback, + body_generator_function_type body_generator = + body_generator_function_type()) { + return post(request, body, string_type(), callback, body_generator); + } + + response put(request request, string_type const& body = string_type(), + string_type const& content_type = string_type(), + body_callback_function_type body_handler = + body_callback_function_type(), + body_generator_function_type body_generator = + body_generator_function_type()) { + if (body != string_type()) { + request << remove_header("Content-Length") + << header("Content-Length", + boost::lexical_cast(body.size())) + << boost::network::body(body); + } + typename headers_range >::type content_type_headers = + headers(request)["Content-Type"]; + if (content_type != string_type()) { + if (!boost::empty(content_type_headers)) + request << remove_header("Content-Type"); + request << header("Content-Type", content_type); + } else { + if (boost::empty(content_type_headers)) { + typedef typename char_::type char_type; + static char_type content_type[] = "x-application/octet-stream"; + request << header("Content-Type", content_type); + } + } + return pimpl->request_skeleton(request, "PUT", true, body_handler, + body_generator); + } + + response put(request const& request, body_callback_function_type callback, + body_generator_function_type body_generator = + body_generator_function_type()) { + return put(request, string_type(), string_type(), callback, body_generator); + } + + response put(request const& request, string_type body, + body_callback_function_type callback, + body_generator_function_type body_generator = + body_generator_function_type()) { + return put(request, body, string_type(), callback, body_generator); + } + + response delete_(request const& request, + body_callback_function_type body_handler = + body_callback_function_type()) { + return pimpl->request_skeleton(request, "DELETE", true, body_handler, + body_generator_function_type()); + } + + void clear_resolved_cache() { pimpl->clear_resolved_cache(); } + + protected: + boost::shared_ptr pimpl; + + void init_pimpl(client_options const& options) { + pimpl.reset(new pimpl_type( + options.cache_resolved(), options.follow_redirects(), + options.always_verify_peer(), options.openssl_certificate(), + options.openssl_verify_path(), options.openssl_certificate_file(), + options.openssl_private_key_file(), options.openssl_ciphers(), + options.openssl_options(), options.io_service(), options.timeout())); + } +}; + +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_FACADE_HPP_20100623 diff --git a/cpp-netlib/boost/network/protocol/http/client/macros.hpp b/cpp-netlib/boost/network/protocol/http/client/macros.hpp new file mode 100644 index 00000000..c64cc7a0 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/macros.hpp @@ -0,0 +1,19 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_MACROS_HPP_20110430 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_MACROS_HPP_20110430 + +// Copyright 2011 Dean Michael Berris . +// 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) + +#include +#include + +#ifndef BOOST_NETWORK_HTTP_BODY_CALLBACK +#define BOOST_NETWORK_HTTP_BODY_CALLBACK(function_name, range_name, \ + error_name) \ + void function_name(boost::iterator_range const& range_name, \ + boost::system::error_code const& error_name) +#endif + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_MACROS_HPP_20110430 */ diff --git a/cpp-netlib/boost/network/protocol/http/client/options.hpp b/cpp-netlib/boost/network/protocol/http/client/options.hpp new file mode 100644 index 00000000..8207dcaa --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/options.hpp @@ -0,0 +1,181 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_OPTIONS_HPP_20130128 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_OPTIONS_HPP_20130128 + +#include +#include +#include +#include + +// Copyright 2013 Google, Inc. +// Copyright 2013 Dean Michael Berris +// 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) + +namespace boost { +namespace network { +namespace http { + +template +struct client_options { + typedef typename string::type string_type; + + client_options() + : cache_resolved_(false), + follow_redirects_(false), + openssl_certificate_(), + openssl_verify_path_(), + openssl_certificate_file_(), + openssl_private_key_file_(), + openssl_ciphers_(), + openssl_options_(0), + io_service_(), + always_verify_peer_(false), + timeout_(0) {} + + client_options(client_options const& other) + : cache_resolved_(other.cache_resolved_), + follow_redirects_(other.follow_redirects_), + openssl_certificate_(other.openssl_certificate_), + openssl_verify_path_(other.openssl_verify_path_), + openssl_certificate_file_(other.openssl_certificate_file_), + openssl_private_key_file_(other.openssl_private_key_file_), + openssl_ciphers_(other.openssl_ciphers_), + openssl_options_(other.openssl_options_), + io_service_(other.io_service_), + always_verify_peer_(other.always_verify_peer_), + timeout_(other.timeout_) {} + + client_options& operator=(client_options other) { + other.swap(*this); + return *this; + } + + void swap(client_options& other) { + using std::swap; + swap(cache_resolved_, other.cache_resolved_); + swap(follow_redirects_, other.follow_redirects_); + swap(openssl_certificate_, other.openssl_certificate_); + swap(openssl_verify_path_, other.openssl_verify_path_); + swap(openssl_certificate_file_, other.openssl_certificate_file_); + swap(openssl_private_key_file_, other.openssl_private_key_file_); + swap(openssl_ciphers_, other.openssl_ciphers_); + swap(openssl_options_, other.openssl_options_); + swap(io_service_, other.io_service_); + swap(always_verify_peer_, other.always_verify_peer_); + swap(timeout_, other.timeout_); + } + + client_options& cache_resolved(bool v) { + cache_resolved_ = v; + return *this; + } + + client_options& follow_redirects(bool v) { + follow_redirects_ = v; + return *this; + } + + client_options& openssl_certificate(string_type const& v) { + openssl_certificate_ = v; + return *this; + } + + client_options& openssl_verify_path(string_type const& v) { + openssl_verify_path_ = v; + return *this; + } + + client_options& openssl_certificate_file(string_type const& v) { + openssl_certificate_file_ = v; + return *this; + } + + client_options& openssl_private_key_file(string_type const& v) { + openssl_private_key_file_ = v; + return *this; + } + + client_options& openssl_ciphers(string_type const& v) { + openssl_ciphers_ = v; + return *this; + } + + client_options& openssl_options(long o) { + openssl_options_ = o; + return *this; + } + + client_options& io_service(boost::shared_ptr v) { + io_service_ = v; + return *this; + } + + client_options& always_verify_peer(bool v) { + always_verify_peer_ = v; + return *this; + } + + client_options& timeout(int v) { + timeout_ = v; + return *this; + } + + bool cache_resolved() const { return cache_resolved_; } + + bool follow_redirects() const { return follow_redirects_; } + + boost::optional openssl_certificate() const { + return openssl_certificate_; + } + + boost::optional openssl_verify_path() const { + return openssl_verify_path_; + } + + boost::optional openssl_certificate_file() const { + return openssl_certificate_file_; + } + + boost::optional openssl_private_key_file() const { + return openssl_private_key_file_; + } + + boost::optional openssl_ciphers() const { + return openssl_ciphers_; + } + + long openssl_options() const { return openssl_options_; } + + boost::shared_ptr io_service() const { + return io_service_; + } + + bool always_verify_peer() const { return always_verify_peer_; } + + int timeout() const { return timeout_; } + + private: + bool cache_resolved_; + bool follow_redirects_; + boost::optional openssl_certificate_; + boost::optional openssl_verify_path_; + boost::optional openssl_certificate_file_; + boost::optional openssl_private_key_file_; + boost::optional openssl_ciphers_; + long openssl_options_; + boost::shared_ptr io_service_; + bool always_verify_peer_; + int timeout_; +}; + +template +inline void swap(client_options& a, client_options& b) { + a.swap(b); +} + +} /* http */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_OPTIONS_HPP_20130128 */ diff --git a/cpp-netlib/boost/network/protocol/http/client/pimpl.hpp b/cpp-netlib/boost/network/protocol/http/client/pimpl.hpp new file mode 100644 index 00000000..d66aa387 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/pimpl.hpp @@ -0,0 +1,90 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_PIMPL_HPP_20100623 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_PIMPL_HPP_20100623 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_client_impl; + +namespace impl { + +template +struct async_client; + +template +struct sync_client; + +template +struct client_base { + typedef unsupported_tag type; +}; + +template +struct client_base >::type> { + typedef async_client type; +}; + +template +struct client_base >::type> { + typedef sync_client type; +}; + +} // namespace impl + +template +struct basic_client; + +template +struct basic_client_impl + : impl::client_base::type { + BOOST_STATIC_ASSERT( + (mpl::not_, is_sync > >::value)); + + typedef typename impl::client_base::type + base_type; + typedef typename base_type::string_type string_type; + + basic_client_impl(bool cache_resolved, bool follow_redirect, + bool always_verify_peer, + optional const& certificate_filename, + optional const& verify_path, + optional const& certificate_file, + optional const& private_key_file, + optional const& ciphers, long ssl_options, + boost::shared_ptr service, + int timeout) + : base_type(cache_resolved, follow_redirect, always_verify_peer, timeout, + service, certificate_filename, verify_path, certificate_file, + private_key_file, ciphers, ssl_options) {} + + ~basic_client_impl() {} +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_PIMPL_HPP_20100623 diff --git a/cpp-netlib/boost/network/protocol/http/client/sync_impl.hpp b/cpp-netlib/boost/network/protocol/http/client/sync_impl.hpp new file mode 100644 index 00000000..5051fbd8 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/client/sync_impl.hpp @@ -0,0 +1,99 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_SYNC_IMPL_HPP_20100623 +#define BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_SYNC_IMPL_HPP_20100623 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Copyright 2013 Google, Inc. +// Copyright 2010 Dean Michael Berris +// 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) + +namespace boost { +namespace network { +namespace http { + +template +struct basic_client_impl; + +namespace impl { +template +struct sync_client + : connection_policy::type { + typedef typename string::type string_type; + typedef typename connection_policy::type + connection_base; + typedef typename resolver::type resolver_type; + typedef function const&, + system::error_code const&)> body_callback_function_type; + typedef function body_generator_function_type; + friend struct basic_client_impl; + + boost::shared_ptr service_ptr; + boost::asio::io_service& service_; + resolver_type resolver_; + optional certificate_filename_; + optional verify_path_; + optional certificate_file_; + optional private_key_file_; + optional ciphers_; + long ssl_options_; + bool always_verify_peer_; + + sync_client( + bool cache_resolved, bool follow_redirect, bool always_verify_peer, + int timeout, boost::shared_ptr service, + optional const& certificate_filename = + optional(), + optional const& verify_path = optional(), + optional const& certificate_file = optional(), + optional const& private_key_file = optional(), + optional const& ciphers = optional(), + long ssl_options = 0) + : connection_base(cache_resolved, follow_redirect, timeout), + service_ptr(service.get() ? service + : make_shared()), + service_(*service_ptr), + resolver_(service_), + certificate_filename_(certificate_filename), + verify_path_(verify_path), + certificate_file_(certificate_file), + private_key_file_(private_key_file), + ciphers_(ciphers), + ssl_options_(ssl_options), + always_verify_peer_(always_verify_peer) {} + + ~sync_client() { + connection_base::cleanup(); + service_ptr.reset(); + } + + void wait_complete() {} + + basic_response request_skeleton(basic_request const& request_, + string_type method, bool get_body, + body_callback_function_type callback, + body_generator_function_type generator) { + typename connection_base::connection_ptr connection_; + connection_ = connection_base::get_connection( + resolver_, request_, always_verify_peer_, certificate_filename_, + verify_path_, certificate_file_, private_key_file_, ciphers_); + return connection_->send_request(method, request_, get_body, callback, + generator); + } +}; + +} // namespace impl +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_SYNC_IMPL_HPP_20100623 diff --git a/cpp-netlib/boost/network/protocol/http/errors.hpp b/cpp-netlib/boost/network/protocol/http/errors.hpp new file mode 100644 index 00000000..e2348eb9 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/errors.hpp @@ -0,0 +1,31 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_PROTOCOL_HTTP_ERRORS_20080516_HPP__ +#define __NETWORK_PROTOCOL_HTTP_ERRORS_20080516_HPP__ + +#include +#include + +namespace boost { +namespace network { +namespace http { +namespace errors { + +template +struct connection_timeout_exception : std::runtime_error {}; + +typedef connection_timeout_exception<> connection_timeout; + +} // namespace errors + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_PROTOCOL_HTTP_20080516_HPP__ diff --git a/cpp-netlib/boost/network/protocol/http/impl/message.ipp b/cpp-netlib/boost/network/protocol/http/impl/message.ipp new file mode 100644 index 00000000..5171cdec --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/impl/message.ipp @@ -0,0 +1,299 @@ +// This file is part of the Boost Network library +// Based on the Pion Network Library (r421) +// Copyright Atomic Labs, Inc. 2007-2008 +// See http://cpp-netlib.sourceforge.net for library home page. +// +// 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_IPP + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +// static member functions of boost::network::http::message + +template +typename message_impl::string_type const message_impl::url_decode( + typename message_impl::string_type const &str) { + char decode_buf[3]; + typename message_impl::string_type result; + result.reserve(str.size()); + + for (typename message_impl::string_type::size_type pos = 0; + pos < str.size(); ++pos) { + switch (str[pos]) { + case '+': + // convert to space character + result += ' '; + break; + case '%': + // decode hexidecimal value + if (pos + 2 < str.size()) { + decode_buf[0] = str[++pos]; + decode_buf[1] = str[++pos]; + decode_buf[2] = '\0'; + result += static_cast(strtol(decode_buf, 0, 16)); + } else { + // recover from error by not decoding character + result += '%'; + } + break; + default: + // character does not need to be escaped + result += str[pos]; + } + }; + + return result; +} + +template +typename message_impl::string_type const message_impl::url_encode( + typename message_impl::string_type const &str) { + char encode_buf[4]; + typename message_impl::string_type result; + encode_buf[0] = '%'; + result.reserve(str.size()); + + // character selection for this algorithm is based on the following url: + // http://www.blooberry.com/indexdot/html/topics/urlencoding.htm + + for (typename message_impl::string_type::size_type pos = 0; + pos < str.size(); ++pos) { + switch (str[pos]) { + default: + if (str[pos] >= 32 && str[pos] < 127) { + // character does not need to be escaped + result += str[pos]; + break; + } + // else pass through to next case + + case '$': + case '&': + case '+': + case ',': + case '/': + case ':': + case ';': + case '=': + case '?': + case '@': + case '"': + case '<': + case '>': + case '#': + case '%': + case '{': + case '}': + case '|': + case '\\': + case '^': + case '~': + case '[': + case ']': + case '`': + // the character needs to be encoded + sprintf(encode_buf + 1, "%02X", str[pos]); + result += encode_buf; + break; + } + }; + + return result; +} + +template +typename message_impl::string_type const +message_impl::make_query_string( + typename query_container::type const &query_params) { + typename message_impl::string_type query_string; + for (typename query_container::type::const_iterator i = + query_params.begin(); + i != query_params.end(); ++i) { + if (i != query_params.begin()) query_string += '&'; + query_string += url_encode(i->first); + query_string += '='; + query_string += url_encode(i->second); + } + return query_string; +} + +template +typename message_impl::string_type const +message_impl::make_set_cookie_header( + typename message_impl::string_type const &name, + typename message_impl::string_type const &value, + typename message_impl::string_type const &path, bool const has_max_age, + unsigned long const max_age) { + typename message_impl::string_type set_cookie_header(name); + set_cookie_header += "=\""; + set_cookie_header += value; + set_cookie_header += "\"; Version=\"1\""; + if (!path.empty()) { + set_cookie_header += "; Path=\""; + set_cookie_header += path; + set_cookie_header += '\"'; + } + if (has_max_age) { + set_cookie_header += "; Max-Age=\""; + set_cookie_header += + boost::lexical_cast::string_type>(max_age); + set_cookie_header += '\"'; + } + return set_cookie_header; +} + +template +bool message_impl::base64_decode( + const typename message_impl::string_type &input, + typename message_impl::string_type &output) { + static const char nop = -1; + static const char decoding_data[] = { + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, 62, nop, + nop, nop, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, nop, nop, + nop, nop, nop, nop, nop, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, nop, nop, nop, nop, nop, nop, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, + nop}; + + unsigned int input_length = input.size(); + const char *input_ptr = input.data(); + + // allocate space for output string + output.clear(); + output.reserve(((input_length + 2) / 3) * 4); + + // for each 4-bytes sequence from the input, extract 4 6-bits sequences + // by droping first two bits + // and regenerate into 3 8-bits sequence + + for (unsigned int i = 0; i < input_length; i++) { + char base64code0; + char base64code1; + char base64code2 = 0; // initialized to 0 to suppress warnings + char base64code3; + + base64code0 = decoding_data[static_cast(input_ptr[i])]; + if (base64code0 == nop) // non base64 character + return false; + if (!(++i < input_length)) // we need at least two input bytes for + // first byte output + return false; + base64code1 = decoding_data[static_cast(input_ptr[i])]; + if (base64code1 == nop) // non base64 character + return false; + + output += ((base64code0 << 2) | ((base64code1 >> 4) & 0x3)); + + if (++i < input_length) { + char c = input_ptr[i]; + if (c == '=') { // padding , end of input + BOOST_ASSERT((base64code1 & 0x0f) == 0); + return true; + } + base64code2 = decoding_data[static_cast(input_ptr[i])]; + if (base64code2 == nop) // non base64 character + return false; + + output += ((base64code1 << 4) & 0xf0) | ((base64code2 >> 2) & 0x0f); + } + + if (++i < input_length) { + char c = input_ptr[i]; + if (c == '=') { // padding , end of input + BOOST_ASSERT((base64code2 & 0x03) == 0); + return true; + } + base64code3 = decoding_data[static_cast(input_ptr[i])]; + if (base64code3 == nop) // non base64 character + return false; + + output += (((base64code2 << 6) & 0xc0) | base64code3); + } + } + + return true; +} + +template +bool message_impl::base64_encode( + typename message_impl::string_type const &input, + typename message_impl::string_type &output) { + static const char encoding_data[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + unsigned int input_length = input.size(); + const char *input_ptr = input.data(); + + // allocate space for output string + output.clear(); + output.reserve(((input_length + 2) / 3) * 4); + + // for each 3-bytes sequence from the input, extract 4 6-bits sequences + // and encode using + // encoding_data lookup table. + // if input do not contains enough chars to complete 3-byte sequence,use + // pad char '=' + for (unsigned int i = 0; i < input_length; i++) { + int base64code0 = 0; + int base64code1 = 0; + int base64code2 = 0; + int base64code3 = 0; + + base64code0 = (input_ptr[i] >> 2) & 0x3f; // 1-byte 6 bits + output += encoding_data[base64code0]; + base64code1 = (input_ptr[i] << 4) & 0x3f; // 1-byte 2 bits + + + if (++i < input_length) { + base64code1 |= (input_ptr[i] >> 4) & 0x0f; // 2-byte 4 bits + output += encoding_data[base64code1]; + base64code2 = (input_ptr[i] << 2) & 0x3f; // 2-byte 4 bits + + + if (++i < input_length) { + base64code2 |= (input_ptr[i] >> 6) & 0x03; // 3-byte 2 bits + base64code3 = input_ptr[i] & 0x3f; // 3-byte 6 bits + output += encoding_data[base64code2]; + output += encoding_data[base64code3]; + } else { + output += encoding_data[base64code2]; + output += '='; + } + } else { + output += encoding_data[base64code1]; + output += '='; + output += '='; + } + } + + return true; +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HPP diff --git a/cpp-netlib/boost/network/protocol/http/impl/parser.ipp b/cpp-netlib/boost/network/protocol/http/impl/parser.ipp new file mode 100644 index 00000000..9212d0c6 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/impl/parser.ipp @@ -0,0 +1,807 @@ +// This file is part of the Boost Network library +// Based on the Pion Network Library (r421) +// Copyright Atomic Labs, Inc. 2007-2008 +// See http://cpp-netlib.sourceforge.net for library home page. +// +// 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +// member functions for class basic_parser + +template +boost::tribool basic_parser::parse_http_headers( + basic_message& http_msg) { + // + // note that boost::tribool may have one of THREE states: + // + // false: encountered an error while parsing HTTP headers + // true: finished successfully parsing the HTTP headers + // indeterminate: parsed bytes, but the HTTP headers are not yet + // finished + // + const char* read_start_ptr = m_read_ptr; + m_bytes_last_read = 0; + while (m_read_ptr < m_read_end_ptr) { + + switch (m_headers_parse_state) { + case PARSE_METHOD_START: + // we have not yet started parsing the HTTP method string + if (*m_read_ptr != ' ' && *m_read_ptr != '\r' && + *m_read_ptr != '\n') { // ignore leading whitespace + if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || + is_special(*m_read_ptr)) + return false; + m_headers_parse_state = PARSE_METHOD; + m_method.erase(); + m_method.push_back(*m_read_ptr); + } + break; + + case PARSE_METHOD: + // we have started parsing the HTTP method string + if (*m_read_ptr == ' ') { + m_resource.erase(); + m_headers_parse_state = PARSE_URI_STEM; + } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || + is_special(*m_read_ptr)) { + return false; + } else if (m_method.size() >= ParserTraits::METHOD_MAX) { + return false; + } else { + m_method.push_back(*m_read_ptr); + } + break; + + case PARSE_URI_STEM: + // we have started parsing the URI stem (or resource name) + if (*m_read_ptr == ' ') { + m_headers_parse_state = PARSE_HTTP_VERSION_H; + } else if (*m_read_ptr == '?') { + m_query_string.erase(); + m_headers_parse_state = PARSE_URI_QUERY; + } else if (is_control(*m_read_ptr)) { + return false; + } else if (m_resource.size() >= ParserTraits::RESOURCE_MAX) { + return false; + } else { + m_resource.push_back(*m_read_ptr); + } + break; + + case PARSE_URI_QUERY: + // we have started parsing the URI query string + if (*m_read_ptr == ' ') { + m_headers_parse_state = PARSE_HTTP_VERSION_H; + } else if (is_control(*m_read_ptr)) { + return false; + } else if (m_query_string.size() >= ParserTraits::QUERY_STRING_MAX) { + return false; + } else { + m_query_string.push_back(*m_read_ptr); + } + break; + + case PARSE_HTTP_VERSION_H: + // parsing "HTTP" + if (*m_read_ptr != 'H') return false; + m_headers_parse_state = PARSE_HTTP_VERSION_T_1; + break; + + case PARSE_HTTP_VERSION_T_1: + // parsing "HTTP" + if (*m_read_ptr != 'T') return false; + m_headers_parse_state = PARSE_HTTP_VERSION_T_2; + break; + + case PARSE_HTTP_VERSION_T_2: + // parsing "HTTP" + if (*m_read_ptr != 'T') return false; + m_headers_parse_state = PARSE_HTTP_VERSION_P; + break; + + case PARSE_HTTP_VERSION_P: + // parsing "HTTP" + if (*m_read_ptr != 'P') return false; + m_headers_parse_state = PARSE_HTTP_VERSION_SLASH; + break; + + case PARSE_HTTP_VERSION_SLASH: + // parsing slash after "HTTP" + if (*m_read_ptr != '/') return false; + m_headers_parse_state = PARSE_HTTP_VERSION_MAJOR_START; + break; + + case PARSE_HTTP_VERSION_MAJOR_START: + // parsing the first digit of the major version number + if (!is_digit(*m_read_ptr)) return false; + http_msg.setVersionMajor(*m_read_ptr - '0'); + m_headers_parse_state = PARSE_HTTP_VERSION_MAJOR; + break; + + case PARSE_HTTP_VERSION_MAJOR: + // parsing the major version number (not first digit) + if (*m_read_ptr == '.') { + m_headers_parse_state = PARSE_HTTP_VERSION_MINOR_START; + } else if (is_digit(*m_read_ptr)) { + http_msg.setVersionMajor((http_msg.getVersionMajor() * 10) + + (*m_read_ptr - '0')); + } else { + return false; + } + break; + + case PARSE_HTTP_VERSION_MINOR_START: + // parsing the first digit of the minor version number + if (!is_digit(*m_read_ptr)) return false; + http_msg.setVersionMinor(*m_read_ptr - '0'); + m_headers_parse_state = PARSE_HTTP_VERSION_MINOR; + break; + + case PARSE_HTTP_VERSION_MINOR: + // parsing the major version number (not first digit) + if (*m_read_ptr == ' ') { + // should only happen for responses + if (m_is_request) return false; + m_headers_parse_state = PARSE_STATUS_CODE_START; + } else if (*m_read_ptr == '\r') { + // should only happen for requests + if (!m_is_request) return false; + m_headers_parse_state = PARSE_EXPECTING_NEWLINE; + } else if (*m_read_ptr == '\n') { + // should only happen for requests + if (!m_is_request) return false; + m_headers_parse_state = PARSE_EXPECTING_CR; + } else if (is_digit(*m_read_ptr)) { + http_msg.setVersionMinor((http_msg.getVersionMinor() * 10) + + (*m_read_ptr - '0')); + } else { + return false; + } + break; + + case PARSE_STATUS_CODE_START: + // parsing the first digit of the response status code + if (!is_digit(*m_read_ptr)) return false; + m_status_code = (*m_read_ptr - '0'); + m_headers_parse_state = PARSE_STATUS_CODE; + break; + + case PARSE_STATUS_CODE: + // parsing the response status code (not first digit) + if (*m_read_ptr == ' ') { + m_status_message.erase(); + m_headers_parse_state = PARSE_STATUS_MESSAGE; + } else if (is_digit(*m_read_ptr)) { + m_status_code = ((m_status_code * 10) + (*m_read_ptr - '0')); + } else { + return false; + } + break; + + case PARSE_STATUS_MESSAGE: + // parsing the response status message + if (*m_read_ptr == '\r') { + m_headers_parse_state = PARSE_EXPECTING_NEWLINE; + } else if (*m_read_ptr == '\n') { + m_headers_parse_state = PARSE_EXPECTING_CR; + } else if (is_control(*m_read_ptr)) { + return false; + } else if (m_status_message.size() >= + ParserTraits::STATUS_MESSAGE_MAX) { + return false; + } else { + m_status_message.push_back(*m_read_ptr); + } + break; + + case PARSE_EXPECTING_NEWLINE: + // we received a CR; expecting a newline to follow + if (*m_read_ptr == '\n') { + m_headers_parse_state = PARSE_HEADER_START; + } else if (*m_read_ptr == '\r') { + // we received two CR's in a row + // assume CR only is (incorrectly) being used for line + // termination + // therefore, the message is finished + ++m_read_ptr; + m_bytes_last_read = (m_read_ptr - read_start_ptr); + m_bytes_total_read += m_bytes_last_read; + return true; + } else if (*m_read_ptr == '\t' || *m_read_ptr == ' ') { + m_headers_parse_state = PARSE_HEADER_WHITESPACE; + } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || + is_special(*m_read_ptr)) { + return false; + } else { + // assume it is the first character for the name of a header + m_header_name.erase(); + m_header_name.push_back(*m_read_ptr); + m_headers_parse_state = PARSE_HEADER_NAME; + } + break; + + case PARSE_EXPECTING_CR: + // we received a newline without a CR + if (*m_read_ptr == '\r') { + m_headers_parse_state = PARSE_HEADER_START; + } else if (*m_read_ptr == '\n') { + // we received two newlines in a row + // assume newline only is (incorrectly) being used for line + // termination + // therefore, the message is finished + ++m_read_ptr; + m_bytes_last_read = (m_read_ptr - read_start_ptr); + m_bytes_total_read += m_bytes_last_read; + return true; + } else if (*m_read_ptr == '\t' || *m_read_ptr == ' ') { + m_headers_parse_state = PARSE_HEADER_WHITESPACE; + } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || + is_special(*m_read_ptr)) { + return false; + } else { + // assume it is the first character for the name of a header + m_header_name.erase(); + m_header_name.push_back(*m_read_ptr); + m_headers_parse_state = PARSE_HEADER_NAME; + } + break; + + case PARSE_HEADER_WHITESPACE: + // parsing whitespace before a header name + if (*m_read_ptr == '\r') { + m_headers_parse_state = PARSE_EXPECTING_NEWLINE; + } else if (*m_read_ptr == '\n') { + m_headers_parse_state = PARSE_EXPECTING_CR; + } else if (*m_read_ptr != '\t' && *m_read_ptr != ' ') { + if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || + is_special(*m_read_ptr)) + return false; + // assume it is the first character for the name of a header + m_header_name.erase(); + m_header_name.push_back(*m_read_ptr); + m_headers_parse_state = PARSE_HEADER_NAME; + } + break; + + case PARSE_HEADER_START: + // parsing the start of a new header + if (*m_read_ptr == '\r') { + m_headers_parse_state = PARSE_EXPECTING_FINAL_NEWLINE; + } else if (*m_read_ptr == '\n') { + m_headers_parse_state = PARSE_EXPECTING_FINAL_CR; + } else if (*m_read_ptr == '\t' || *m_read_ptr == ' ') { + m_headers_parse_state = PARSE_HEADER_WHITESPACE; + } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || + is_special(*m_read_ptr)) { + return false; + } else { + // first character for the name of a header + m_header_name.erase(); + m_header_name.push_back(*m_read_ptr); + m_headers_parse_state = PARSE_HEADER_NAME; + } + break; + + case PARSE_HEADER_NAME: + // parsing the name of a header + if (*m_read_ptr == ':') { + m_header_value.erase(); + m_headers_parse_state = PARSE_SPACE_BEFORE_HEADER_VALUE; + } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || + is_special(*m_read_ptr)) { + return false; + } else if (m_header_name.size() >= ParserTraits::HEADER_NAME_MAX) { + return false; + } else { + // character (not first) for the name of a header + m_header_name.push_back(*m_read_ptr); + } + break; + + case PARSE_SPACE_BEFORE_HEADER_VALUE: + // parsing space character before a header's value + if (*m_read_ptr == ' ') { + m_headers_parse_state = PARSE_HEADER_VALUE; + } else if (*m_read_ptr == '\r') { + http_msg.addHeader(m_header_name, m_header_value); + m_headers_parse_state = PARSE_EXPECTING_NEWLINE; + } else if (*m_read_ptr == '\n') { + http_msg.addHeader(m_header_name, m_header_value); + m_headers_parse_state = PARSE_EXPECTING_CR; + } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || + is_special(*m_read_ptr)) { + return false; + } else { + // assume it is the first character for the value of a header + m_header_value.push_back(*m_read_ptr); + m_headers_parse_state = PARSE_HEADER_VALUE; + } + break; + + case PARSE_HEADER_VALUE: + // parsing the value of a header + if (*m_read_ptr == '\r') { + http_msg.addHeader(m_header_name, m_header_value); + m_headers_parse_state = PARSE_EXPECTING_NEWLINE; + } else if (*m_read_ptr == '\n') { + http_msg.addHeader(m_header_name, m_header_value); + m_headers_parse_state = PARSE_EXPECTING_CR; + } else if (is_control(*m_read_ptr)) { + return false; + } else if (m_header_value.size() >= ParserTraits::HEADER_VALUE_MAX) { + return false; + } else { + // character (not first) for the value of a header + m_header_value.push_back(*m_read_ptr); + } + break; + + case PARSE_EXPECTING_FINAL_NEWLINE: + if (*m_read_ptr == '\n') ++m_read_ptr; + m_bytes_last_read = (m_read_ptr - read_start_ptr); + m_bytes_total_read += m_bytes_last_read; + return true; + + case PARSE_EXPECTING_FINAL_CR: + if (*m_read_ptr == '\r') ++m_read_ptr; + m_bytes_last_read = (m_read_ptr - read_start_ptr); + m_bytes_total_read += m_bytes_last_read; + return true; + } + + ++m_read_ptr; + } + + m_bytes_last_read = (m_read_ptr - read_start_ptr); + m_bytes_total_read += m_bytes_last_read; + return boost::indeterminate; +} + +template +boost::tribool basic_parser::parse_chunks( + types::chunk_cache_t& chunk_buffers) { + // + // note that boost::tribool may have one of THREE states: + // + // false: encountered an error while parsing message + // true: finished successfully parsing the message + // indeterminate: parsed bytes, but the message is not yet finished + // + const char* read_start_ptr = m_read_ptr; + m_bytes_last_read = 0; + while (m_read_ptr < m_read_end_ptr) { + + switch (m_chunked_content_parse_state) { + case PARSE_CHUNK_SIZE_START: + // we have not yet started parsing the next chunk size + if (is_hex_digit(*m_read_ptr)) { + m_chunk_size_str.erase(); + m_chunk_size_str.push_back(*m_read_ptr); + m_chunked_content_parse_state = PARSE_CHUNK_SIZE; + } else if (*m_read_ptr == ' ' || *m_read_ptr == '\x09' || + *m_read_ptr == '\x0D' || *m_read_ptr == '\x0A') { + // Ignore leading whitespace. Technically, the standard + // probably doesn't allow white space here, + // but we'll be flexible, since there's no ambiguity. + break; + } else { + return false; + } + break; + + case PARSE_CHUNK_SIZE: + if (is_hex_digit(*m_read_ptr)) { + m_chunk_size_str.push_back(*m_read_ptr); + } else if (*m_read_ptr == '\x0D') { + m_chunked_content_parse_state = PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE; + } else if (*m_read_ptr == ' ' || *m_read_ptr == '\x09') { + // Ignore trailing tabs or spaces. Technically, the standard + // probably doesn't allow this, + // but we'll be flexible, since there's no ambiguity. + m_chunked_content_parse_state = PARSE_EXPECTING_CR_AFTER_CHUNK_SIZE; + } else { + return false; + } + break; + + case PARSE_EXPECTING_CR_AFTER_CHUNK_SIZE: + if (*m_read_ptr == '\x0D') { + m_chunked_content_parse_state = PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE; + } else if (*m_read_ptr == ' ' || *m_read_ptr == '\x09') { + // Ignore trailing tabs or spaces. Technically, the standard + // probably doesn't allow this, + // but we'll be flexible, since there's no ambiguity. + break; + } else { + return false; + } + break; + + case PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE: + // We received a CR; expecting LF to follow. We can't be flexible + // here because + // if we see anything other than LF, we can't be certain where the + // chunk starts. + if (*m_read_ptr == '\x0A') { + m_bytes_read_in_current_chunk = 0; + m_size_of_current_chunk = strtol(m_chunk_size_str.c_str(), 0, 16); + if (m_size_of_current_chunk == 0) { + m_chunked_content_parse_state = + PARSE_EXPECTING_FINAL_CR_AFTER_LAST_CHUNK; + } else { + m_current_chunk.clear(); + m_chunked_content_parse_state = PARSE_CHUNK; + } + } else { + return false; + } + break; + + case PARSE_CHUNK: + if (m_bytes_read_in_current_chunk < m_size_of_current_chunk) { + m_current_chunk.push_back(*m_read_ptr); + m_bytes_read_in_current_chunk++; + } + if (m_bytes_read_in_current_chunk == m_size_of_current_chunk) { + chunk_buffers.push_back(m_current_chunk); + m_current_chunk.clear(); + m_chunked_content_parse_state = PARSE_EXPECTING_CR_AFTER_CHUNK; + } + break; + + case PARSE_EXPECTING_CR_AFTER_CHUNK: + // we've read exactly m_size_of_current_chunk bytes since starting + // the current chunk + if (*m_read_ptr == '\x0D') { + m_chunked_content_parse_state = PARSE_EXPECTING_LF_AFTER_CHUNK; + } else { + return false; + } + break; + + case PARSE_EXPECTING_LF_AFTER_CHUNK: + // we received a CR; expecting LF to follow + if (*m_read_ptr == '\x0A') { + m_chunked_content_parse_state = PARSE_CHUNK_SIZE_START; + } else { + return false; + } + break; + + case PARSE_EXPECTING_FINAL_CR_AFTER_LAST_CHUNK: + // we've read the final chunk; expecting final CRLF + if (*m_read_ptr == '\x0D') { + m_chunked_content_parse_state = + PARSE_EXPECTING_FINAL_LF_AFTER_LAST_CHUNK; + } else { + return false; + } + break; + + case PARSE_EXPECTING_FINAL_LF_AFTER_LAST_CHUNK: + // we received the final CR; expecting LF to follow + if (*m_read_ptr == '\x0A') { + ++m_read_ptr; + m_bytes_last_read = (m_read_ptr - read_start_ptr); + m_bytes_total_read += m_bytes_last_read; + return true; + } else { + return false; + } + } + + ++m_read_ptr; + } + + m_bytes_last_read = (m_read_ptr - read_start_ptr); + m_bytes_total_read += m_bytes_last_read; + return boost::indeterminate; +} + +template +std::size_t basic_parser::consume_content( + basic_message& http_msg) { + // get the payload content length from the HTTP headers + http_msg.updateContentLengthUsingHeader(); + + // read the post content + std::size_t content_bytes_to_read = http_msg.getContentLength(); + char* post_buffer = http_msg.createContentBuffer(); + + if (m_read_ptr < m_read_end_ptr) { + // there are extra bytes left from the last read operation + // copy them into the beginning of the content buffer + const std::size_t bytes_left_in_read_buffer = bytes_available(); + + if (bytes_left_in_read_buffer >= http_msg.getContentLength()) { + // the last read operation included all of the payload content + memcpy(post_buffer, m_read_ptr, http_msg.getContentLength()); + content_bytes_to_read = 0; + m_read_ptr += http_msg.getContentLength(); + } else { + // only some of the post content has been read so far + memcpy(post_buffer, m_read_ptr, bytes_left_in_read_buffer); + content_bytes_to_read -= bytes_left_in_read_buffer; + m_read_ptr = m_read_end_ptr; + } + } + + m_bytes_last_read = (http_msg.getContentLength() - content_bytes_to_read); + m_bytes_total_read += m_bytes_last_read; + return m_bytes_last_read; +} + +template +std::size_t basic_parser::consume_content_as_next_chunk( + types::chunk_cache_t& chunk_buffers) { + if (bytes_available() == 0) { + m_bytes_last_read = 0; + } else { + std::vector next_chunk; + while (m_read_ptr < m_read_end_ptr) { + next_chunk.push_back(*m_read_ptr); + ++m_read_ptr; + } + chunk_buffers.push_back(next_chunk); + m_bytes_last_read = next_chunk.size(); + m_bytes_total_read += m_bytes_last_read; + } + return m_bytes_last_read; +} + +template +void basic_parser::finish(basic_request& http_request) { + http_request.setIsValid(true); + http_request.setMethod(m_method); + http_request.setResource(m_resource); + http_request.setQueryString(m_query_string); + + // parse query pairs from the URI query string + if (!m_query_string.empty()) { + if (!parseURLEncoded(http_request.getQueryParams(), m_query_string.c_str(), + m_query_string.size())) + } + + // parse query pairs from post content (x-www-form-urlencoded) + if (http_request.getHeader(types::HEADER_CONTENT_TYPE) == + types::CONTENT_TYPE_URLENCODED) { + if (!parseURLEncoded(http_request.getQueryParams(), + http_request.getContent(), + http_request.getContentLength())) + } + + // parse "Cookie" headers + std::pair + cookie_pair = http_request.getHeaders().equal_range(types::HEADER_COOKIE); + for (types::headers::const_iterator cookie_iterator = cookie_pair.first; + cookie_iterator != http_request.getHeaders().end() && + cookie_iterator != cookie_pair.second; + ++cookie_iterator) { + if (!parseCookieHeader(http_request.getCookieParams(), + cookie_iterator->second)) + } +} + +template +void basic_parser::finish(basic_response& http_response) { + http_response.setIsValid(true); + http_response.setStatusCode(m_status_code); + http_response.setStatusMessage(m_status_message); +} + +template +inline void basic_parser::reset(void) { + m_headers_parse_state = + (m_is_request ? PARSE_METHOD_START : PARSE_HTTP_VERSION_H); + m_chunked_content_parse_state = PARSE_CHUNK_SIZE_START; + m_status_code = 0; + m_status_message.erase(); + m_method.erase(); + m_resource.erase(); + m_query_string.erase(); + m_current_chunk.clear(); + m_bytes_last_read = m_bytes_total_read = 0; +} + +template +static bool basic_parser::parse_url_encoded( + types::query_params& params, const char* ptr, const std::size_t len) { + // used to track whether we are parsing the name or value + enum query_parse_state_t { + QUERY_PARSE_NAME, + QUERY_PARSE_VALUE + } parse_state = QUERY_PARSE_NAME; + + // misc other variables used for parsing + const char* const end = ptr + len; + string_type query_name; + string_type query_value; + + // iterate through each encoded character + while (ptr < end) { + switch (parse_state) { + + case QUERY_PARSE_NAME: + // parsing query name + if (*ptr == '=') { + // end of name found + if (query_name.empty()) return false; + parse_state = QUERY_PARSE_VALUE; + } else if (*ptr == '&') { + // value is empty (OK) + if (query_name.empty()) return false; + params.insert(std::make_pair(query_name, query_value)); + query_name.erase(); + } else if (is_control(*ptr) || + query_name.size() >= ParserTraits::QUERY_NAME_MAX) { + // control character detected, or max sized exceeded + return false; + } else { + // character is part of the name + query_name.push_back(*ptr); + } + break; + + case QUERY_PARSE_VALUE: + // parsing query value + if (*ptr == '&') { + // end of value found (OK if empty) + params.insert(std::make_pair(query_name, query_value)); + query_name.erase(); + query_value.erase(); + parse_state = QUERY_PARSE_NAME; + } else if (is_control(*ptr) || + query_value.size() >= ParserTraits::QUERY_VALUE_MAX) { + // control character detected, or max sized exceeded + return false; + } else { + // character is part of the value + query_value.push_back(*ptr); + } + break; + } + + ++ptr; + } + + // handle last pair in string + if (!query_name.empty()) + params.insert(std::make_pair(query_name, query_value)); + + return true; +} + +template +static bool basic_parser::parse_cookie_header( + types::cookie_params& params, const string_type& cookie_header) { + // BASED ON RFC 2109 + // + // The current implementation ignores cookie attributes which begin with + // '$' + // (i.e. $Path=/, $Domain=, etc.) + + // used to track what we are parsing + enum cookie_parse_state_t { + COOKIE_PARSE_NAME, + COOKIE_PARSE_VALUE, + COOKIE_PARSE_IGNORE + } parse_state = COOKIE_PARSE_NAME; + + // misc other variables used for parsing + string_type cookie_name; + string_type cookie_value; + char value_quote_character = '\0'; + + // iterate through each character + for (string_type::const_iterator string_iterator = cookie_header.begin(); + string_iterator != cookie_header.end(); ++string_iterator) { + switch (parse_state) { + + case COOKIE_PARSE_NAME: + // parsing cookie name + if (*string_iterator == '=') { + // end of name found + if (cookie_name.empty()) return false; + value_quote_character = '\0'; + parse_state = COOKIE_PARSE_VALUE; + } else if (*string_iterator == ';' || *string_iterator == ',') { + // ignore empty cookie names since this may occur naturally + // when quoted values are encountered + if (!cookie_name.empty()) { + // value is empty (OK) + if (cookie_name[0] != '$') + params.insert(std::make_pair(cookie_name, cookie_value)); + cookie_name.erase(); + } + } else if (*string_iterator != ' ') { // ignore whitespace + // check if control character detected, or max sized exceeded + if (is_control(*string_iterator) || + cookie_name.size() >= ParserTraits::COOKIE_NAME_MAX) + return false; + // character is part of the name + // cookie names are case insensitive -> convert to lowercase + cookie_name.push_back(tolower(*string_iterator)); + } + break; + + case COOKIE_PARSE_VALUE: + // parsing cookie value + if (value_quote_character == '\0') { + // value is not (yet) quoted + if (*string_iterator == ';' || *string_iterator == ',') { + // end of value found (OK if empty) + if (cookie_name[0] != '$') + params.insert(std::make_pair(cookie_name, cookie_value)); + cookie_name.erase(); + cookie_value.erase(); + parse_state = COOKIE_PARSE_NAME; + } else if (*string_iterator == '\'' || *string_iterator == '"') { + if (cookie_value.empty()) { + // begin quoted value + value_quote_character = *string_iterator; + } else if (cookie_value.size() >= ParserTraits::COOKIE_VALUE_MAX) { + // max size exceeded + return false; + } else { + // assume character is part of the (unquoted) value + cookie_value.push_back(*string_iterator); + } + } else if (*string_iterator != ' ') { // ignore unquoted whitespace + // check if control character detected, or max sized exceeded + if (is_control(*string_iterator) || + cookie_value.size() >= ParserTraits::COOKIE_VALUE_MAX) + return false; + // character is part of the (unquoted) value + cookie_value.push_back(*string_iterator); + } + } else { + // value is quoted + if (*string_iterator == value_quote_character) { + // end of value found (OK if empty) + if (cookie_name[0] != '$') + params.insert(std::make_pair(cookie_name, cookie_value)); + cookie_name.erase(); + cookie_value.erase(); + parse_state = COOKIE_PARSE_IGNORE; + } else if (cookie_value.size() >= ParserTraits::COOKIE_VALUE_MAX) { + // max size exceeded + return false; + } else { + // character is part of the (quoted) value + cookie_value.push_back(*string_iterator); + } + } + break; + + case COOKIE_PARSE_IGNORE: + // ignore everything until we reach a comma "," or semicolon ";" + if (*string_iterator == ';' || *string_iterator == ',') + parse_state = COOKIE_PARSE_NAME; + break; + } + } + + // handle last cookie in string + if (!cookie_name.empty() && cookie_name[0] != '$') + params.insert(std::make_pair(cookie_name, cookie_value)); + + return true; +} + +}; // namespace http + +}; // namespace network + +}; // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_IPP diff --git a/cpp-netlib/boost/network/protocol/http/impl/request.hpp b/cpp-netlib/boost/network/protocol/http/impl/request.hpp new file mode 100644 index 00000000..29608f8a --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/impl/request.hpp @@ -0,0 +1,231 @@ + +// Copyright Dean Michael Berris 2007,2009,2010. +// Copyright Michael Dickey 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 __NETWORK_PROTOCOL_HTTP_REQUEST_IMPL_20070908_1_HPP__ +#define __NETWORK_PROTOCOL_HTTP_REQUEST_IMPL_20070908_1_HPP__ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +namespace boost { +namespace network { + +/** Specialize the traits for the http_server tag. */ +template <> +struct headers_container< + http::tags::http_server> : vector:: + apply::type> {}; + +template <> +struct headers_container< + http::tags:: + http_async_server> : vector:: + apply::type> {}; + +namespace http { + +/** request.hpp + * + * This file implements the basic request object required + * by the HTTP client implementation. The basic_request + * object encapsulates a URI which is parsed at runtime. + */ + +template +struct basic_request : public basic_message { + + mutable boost::network::uri::uri uri_; + boost::uint16_t source_port_; + typedef basic_message base_type; + + public: + typedef typename sync_only::type tag; + typedef typename string::type string_type; + typedef boost::uint16_t port_type; + + explicit basic_request(string_type const& uri_) : uri_(uri_), source_port_(0) {} + + explicit basic_request(boost::network::uri::uri const& uri_) : uri_(uri_), source_port_(0) {} + + void uri(string_type const& new_uri) { uri_ = new_uri; } + + void uri(boost::network::uri::uri const& new_uri) { uri_ = new_uri; } + + basic_request() : base_type(), source_port_(0) {} + + basic_request(basic_request const& other) + : base_type(other), uri_(other.uri_), source_port_(other.source_port_) {} + + basic_request& operator=(basic_request rhs) { + rhs.swap(*this); + return *this; + } + + void swap(basic_request& other) { + base_type& base_ref(other); + basic_request& this_ref(*this); + base_ref.swap(this_ref); + boost::swap(other.uri_, this->uri_); + boost::swap(other.source_port_, this->source_port_); + } + + string_type const host() const { return uri_.host(); } + + port_type port() const { + boost::optional port = uri::port_us(uri_); + if (!port) { + typedef constants consts; + return boost::iequals(uri_.scheme(), string_type(consts::https())) ? 443 + : 80; + } + return *port; + } + + string_type const path() const { return uri_.path(); } + + string_type const query() const { return uri_.query(); } + + string_type const anchor() const { return uri_.fragment(); } + + string_type const protocol() const { return uri_.scheme(); } + + void uri(string_type const& new_uri) const { uri_ = new_uri; } + + boost::network::uri::uri const& uri() const { return uri_; } + + void source_port(const boost::uint16_t port) { source_port_ = port; } + + boost::uint16_t source_port() const { return source_port_; } +}; + +/** This is the implementation of a POD request type + * that is specificially used by the HTTP server + * implementation. This fully specializes the + * basic_request template above to be + * primarily and be solely a POD for performance + * reasons. + * + * Reality check: This is not a POD because it contains a non-POD + * member, the headers vector. :( + */ +template +struct not_quite_pod_request_base { + typedef Tag tag; + typedef typename string::type string_type; + typedef typename request_header::type header_type; + typedef typename vector::template apply::type vector_type; + typedef vector_type headers_container_type; + typedef boost::uint16_t port_type; + mutable string_type source; + mutable port_type source_port; + mutable string_type method; + mutable string_type destination; + mutable boost::uint8_t http_version_major; + mutable boost::uint8_t http_version_minor; + mutable vector_type headers; + mutable string_type body; + + void swap(not_quite_pod_request_base& r) const { + using std::swap; + swap(method, r.method); + swap(source, r.source); + swap(source_port, r.source_port); + swap(destination, r.destination); + swap(http_version_major, r.http_version_major); + swap(http_version_minor, r.http_version_minor); + swap(headers, r.headers); + swap(body, r.body); + } +}; + +template <> +struct basic_request : not_quite_pod_request_base< + tags::http_async_server> {}; + +template <> +struct basic_request : not_quite_pod_request_base< + tags::http_server> {}; + +template +struct ServerRequest; + +BOOST_CONCEPT_ASSERT((ServerRequest >)); +BOOST_CONCEPT_ASSERT((ServerRequest >)); + +template +inline void swap(basic_request& lhs, basic_request& rhs) { + lhs.swap(rhs); +} + +} // namespace http + +namespace http { +namespace impl { + +template <> +struct request_headers_wrapper { + basic_request const& request_; + request_headers_wrapper(basic_request const& request_) + : request_(request_) {} + typedef headers_container::type headers_container_type; + operator headers_container_type() { return request_.headers; } +}; + +template <> +struct body_wrapper > { + typedef string::type string_type; + basic_request const& request_; + body_wrapper(basic_request const& request_) + : request_(request_) {} + operator string_type() { return request_.body; } +}; + +template <> +struct request_headers_wrapper { + basic_request const& request_; + request_headers_wrapper( + basic_request const& request_) + : request_(request_) {} + typedef headers_container::type + headers_container_type; + operator headers_container_type() { return request_.headers; } +}; + +template <> +struct body_wrapper > { + typedef string::type string_type; + basic_request const& request_; + body_wrapper(basic_request const& request_) + : request_(request_) {} + operator string_type() { return request_.body; } +}; + +} // namespace impl + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // __NETWORK_PROTOCOL_HTTP_REQUEST_IMPL_20070908_1_HPP__ diff --git a/cpp-netlib/boost/network/protocol/http/impl/request_parser.ipp b/cpp-netlib/boost/network/protocol/http/impl/request_parser.ipp new file mode 100644 index 00000000..e9ac43d5 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/impl/request_parser.ipp @@ -0,0 +1,262 @@ +// +// request_parser.ipp +// ~~~~~~~~~~~~~~~~~~ +// +// Implementation file for the header-only version of the request_parser. +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2009 Dean Michael Berris (mikhailberis@gmail.com) +// Copyright (c) 2009 Tarroo, Inc. +// +// 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 BOOST_NETWORK_HTTP_REQUEST_PARSER_IPP +#define BOOST_NETWORK_HTTP_REQUEST_PARSER_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template +boost::tribool basic_request_parser::consume(basic_request& req, + char input) { + switch (state_) { + case method_start: + if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { + return false; + } else { + state_ = method; + req.method.push_back(input); + return boost::indeterminate; + } + case method: + if (input == ' ') { + state_ = uri; + return boost::indeterminate; + } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { + return false; + } else { + req.method.push_back(input); + return boost::indeterminate; + } + case uri_start: + if (is_ctl(input)) { + return false; + } else { + state_ = uri; + req.destination.push_back(input); + return boost::indeterminate; + } + case uri: + if (input == ' ') { + state_ = http_version_h; + return boost::indeterminate; + } else if (is_ctl(input)) { + return false; + } else { + req.destination.push_back(input); + return boost::indeterminate; + } + case http_version_h: + if (input == 'H') { + state_ = http_version_t_1; + return boost::indeterminate; + } else { + return false; + } + case http_version_t_1: + if (input == 'T') { + state_ = http_version_t_2; + return boost::indeterminate; + } else { + return false; + } + case http_version_t_2: + if (input == 'T') { + state_ = http_version_p; + return boost::indeterminate; + } else { + return false; + } + case http_version_p: + if (input == 'P') { + state_ = http_version_slash; + return boost::indeterminate; + } else { + return false; + } + case http_version_slash: + if (input == '/') { + req.http_version_major = 0; + req.http_version_minor = 0; + state_ = http_version_major_start; + return boost::indeterminate; + } else { + return false; + } + case http_version_major_start: + if (is_digit(input)) { + req.http_version_major = req.http_version_major * 10 + input - '0'; + state_ = http_version_major; + return boost::indeterminate; + } else { + return false; + } + case http_version_major: + if (input == '.') { + state_ = http_version_minor_start; + return boost::indeterminate; + } else if (is_digit(input)) { + req.http_version_major = req.http_version_major * 10 + input - '0'; + return boost::indeterminate; + } else { + return false; + } + case http_version_minor_start: + if (is_digit(input)) { + req.http_version_minor = req.http_version_minor * 10 + input - '0'; + state_ = http_version_minor; + return boost::indeterminate; + } else { + return false; + } + case http_version_minor: + if (input == '\r') { + state_ = expecting_newline_1; + return boost::indeterminate; + } else if (is_digit(input)) { + req.http_version_minor = req.http_version_minor * 10 + input - '0'; + return boost::indeterminate; + } else { + return false; + } + case expecting_newline_1: + if (input == '\n') { + state_ = header_line_start; + return boost::indeterminate; + } else { + return false; + } + case header_line_start: + if (input == '\r') { + state_ = expecting_newline_3; + return boost::indeterminate; + } else if (!req.headers.empty() && (input == ' ' || input == '\t')) { + state_ = header_lws; + return boost::indeterminate; + } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { + return false; + } else { + req.headers.push_back(typename request_header::type()); + req.headers.back().name.push_back(input); + state_ = header_name; + return boost::indeterminate; + } + case header_lws: + if (input == '\r') { + state_ = expecting_newline_2; + return boost::indeterminate; + } else if (input == ' ' || input == '\t') { + return boost::indeterminate; + } else if (is_ctl(input)) { + return false; + } else { + state_ = header_value; + req.headers.back().value.push_back(input); + return boost::indeterminate; + } + case header_name: + if (input == ':') { + state_ = space_before_header_value; + return boost::indeterminate; + } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { + return false; + } else { + req.headers.back().name.push_back(input); + return boost::indeterminate; + } + case space_before_header_value: + if (input == ' ') { + state_ = header_value; + return boost::indeterminate; + } else { + return false; + } + case header_value: + if (input == '\r') { + state_ = expecting_newline_2; + return boost::indeterminate; + } else if (is_ctl(input)) { + return false; + } else { + req.headers.back().value.push_back(input); + return boost::indeterminate; + } + case expecting_newline_2: + if (input == '\n') { + state_ = header_line_start; + return boost::indeterminate; + } else { + return false; + } + case expecting_newline_3: + return (input == '\n'); + default: + return false; + } +} + +template +bool basic_request_parser::is_char(int c) { + return c >= 0 && c <= 127; +} + +template +bool basic_request_parser::is_ctl(int c) { + return (c >= 0 && c <= 31) || (c == 127); +} + +template +bool basic_request_parser::is_tspecial(int c) { + switch (c) { + case '(': + case ')': + case '<': + case '>': + case '@': + case ',': + case ';': + case ':': + case '\\': + case '"': + case '/': + case '[': + case ']': + case '?': + case '=': + case '{': + case '}': + case ' ': + case '\t': + return true; + default: + return false; + } +} + +template +bool basic_request_parser::is_digit(int c) { + return c >= '0' && c <= '9'; +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_HTTP_REQUEST_PARSER_IPP diff --git a/cpp-netlib/boost/network/protocol/http/impl/response.ipp b/cpp-netlib/boost/network/protocol/http/impl/response.ipp new file mode 100644 index 00000000..f41be41d --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/impl/response.ipp @@ -0,0 +1,522 @@ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2009 Dean Michael Berris (mikhailberis@gmail.com) +// Copyright (c) 2009 Tarroo, Inc. +// Copyright (c) 2014 Jussi Lyytinen (jussi@lyytinen.org) +// +// 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) +// +// Note: This implementation has significantly changed from the original example +// from a plain header file into a header-only implementation using C++ +// templates +// to reduce the dependence on building an external library. +// + +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_RESPONSE_RESPONSE_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_RESPONSE_RESPONSE_IPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +/// A reply to be sent to a client. +template <> +struct basic_response { + typedef tags::http_server tag; + typedef response_header::type header_type; + + /*! The status of the reply. Represent all the status codes of HTTP v1.1 + * from http://tools.ietf.org/html/rfc2616#page-39 and + * http://tools.ietf.org/html/rfc6585 + */ + enum status_type { + continue_http = 100, + switching_protocols = 101, + ok = 200, + created = 201, + accepted = 202, + non_authoritative_information = 203, + no_content = 204, + reset_content = 205, + partial_content = 206, + multiple_choices = 300, + moved_permanently = 301, + moved_temporarily = 302, ///< \deprecated Not HTTP standard + found = 302, + see_other = 303, + not_modified = 304, + use_proxy = 305, + temporary_redirect = 307, + bad_request = 400, + unauthorized = 401, + payment_required = 402, + forbidden = 403, + not_found = 404, + not_supported = 405, ///< \deprecated Not HTTP standard + method_not_allowed = 405, + not_acceptable = 406, + proxy_authentication_required = 407, + request_timeout = 408, + conflict = 409, + gone = 410, + length_required = 411, + precondition_failed = 412, + request_entity_too_large = 413, + request_uri_too_large = 414, + unsupported_media_type = 415, + unsatisfiable_range = 416, ///< \deprecated Not HTTP standard + requested_range_not_satisfiable = 416, + expectation_failed = 417, + precondition_required = 428, + too_many_requests = 429, + request_header_fields_too_large = 431, + internal_server_error = 500, + not_implemented = 501, + bad_gateway = 502, + service_unavailable = 503, + gateway_timeout = 504, + http_version_not_supported = 505, + space_unavailable = 507, + network_authentication_required = 511 + } status; + + /// The headers to be included in the reply. + typedef vector::apply::type headers_vector; + headers_vector headers; + + /// The content to be sent in the reply. + typedef string::type string_type; + string_type content; + + /// Convert the reply into a vector of buffers. The buffers do not own + /// the + /// underlying memory blocks, therefore the reply object must remain + /// valid and + /// not be changed until the write operation has completed. + std::vector to_buffers() { + using boost::asio::const_buffer; + using boost::asio::buffer; + static const char name_value_separator[] = {':', ' '}; + static const char crlf[] = {'\r', '\n'}; + std::vector buffers; + buffers.push_back(to_buffer(status)); + for (std::size_t i = 0; i < headers.size(); ++i) { + header_type &h = headers[i]; + buffers.push_back(buffer(h.name)); + buffers.push_back(buffer(name_value_separator)); + buffers.push_back(buffer(h.value)); + buffers.push_back(buffer(crlf)); + } + buffers.push_back(buffer(crlf)); + buffers.push_back(buffer(content)); + return buffers; + } + + /// Get a stock reply. + static basic_response stock_reply(status_type status) { + return stock_reply(status, to_string(status)); + } + + /// Get a stock reply with custom plain text data. + static basic_response stock_reply(status_type status, + string_type content) { + using boost::lexical_cast; + basic_response rep; + rep.status = status; + rep.content = content; + rep.headers.resize(2); + rep.headers[0].name = "Content-Length"; + rep.headers[0].value = lexical_cast(rep.content.size()); + rep.headers[1].name = "Content-Type"; + rep.headers[1].value = "text/html"; + return rep; + } + + /// Swap response objects + void swap(basic_response &r) { + using std::swap; + swap(headers, r.headers); + swap(content, r.content); + } + + private: + static string_type to_string(status_type status) { + switch (status) { + // 2xx Success + case basic_response::ok: + return ""; + case basic_response::created: + return + "" + "Created" + "

201 Created

" + ""; + case basic_response::accepted: + return + "" + "Accepted" + "

202 Accepted

" + ""; + case basic_response::non_authoritative_information: + return + "" + "Non-Authoritative Information" + "

203 Non-Authoritative Information

" + ""; + case basic_response::no_content: + return + "" + "No Content" + "

204 Content

" + ""; + case basic_response::reset_content: + return + "" + "Reset Content" + "

205 Reset Content

" + ""; + case basic_response::partial_content: + return + "" + "Partial Content" + "

206 Partial Content

" + ""; + + // 3xx Redirection + case basic_response::multiple_choices: + return + "" + "Multiple Choices" + "

300 Multiple Choices

" + ""; + case basic_response::moved_permanently: + return + "" + "Moved Permanently" + "

301 Moved Permanently

" + ""; + case basic_response::moved_temporarily: + return + "" + "Moved Temporarily" + "

302 Moved Temporarily

" + ""; + case basic_response::see_other: + return + "" + "See Other" + "

303 See Other

" + ""; + case basic_response::not_modified: + return + "" + "Not Modified" + "

304 Not Modified

" + ""; + case basic_response::use_proxy: + return + "" + "Use Proxy" + "

305 Use Proxy

" + ""; + case basic_response::temporary_redirect: + return + "" + "Temporary Redirect" + "

307 Temporary Redirect

" + ""; + + // 4xx Client Error + case basic_response::bad_request: + return + "" + "Bad Request" + "

400 Bad Request

" + ""; + case basic_response::unauthorized: + return + "" + "Unauthorized" + "

401 Unauthorized

" + ""; + case basic_response::forbidden: + return + "" + "Forbidden" + "

403 Forbidden

" + ""; + case basic_response::not_found: + return + "" + "Not Found" + "

404 Not Found

" + ""; + case basic_response::not_supported: + return + "" + "Method Not Supported" + "

405 Method Not Supported

" + ""; + case basic_response::not_acceptable: + return + "" + "Not Acceptable\r\n" + "

406 Not Acceptable

" + ""; + case basic_response::proxy_authentication_required: + return + "" + "Proxy Authentication Required" + "

407 Proxy Authentication Required

" + ""; + case basic_response::request_timeout: + return + "" + "Request Timeout" + "

408 Request Timeout

" + ""; + case basic_response::conflict: + return + "" + "Conflict" + "

409 Conflict

" + ""; + case basic_response::gone: + return + "" + "Gone" + "

410 Gone

" + ""; + case basic_response::length_required: + return + "" + "Length Required" + "

411 Length Required

" + ""; + case basic_response::precondition_failed: + return + "" + "Precondition Failed" + "

412 Precondition Failed

" + ""; + case basic_response::request_entity_too_large: + return + "" + "Request Entity Too Large" + "

413 Request Entity Too Large

" + ""; + case basic_response::request_uri_too_large: + return + "" + "Request-URI Too Large" + "

414 Request-URI Too Large

" + ""; + case basic_response::unsupported_media_type: + return + "" + "Unsupported Media Type" + "

415 Unsupported Media Type

" + ""; + case basic_response::unsatisfiable_range: + return + "" + "Unsatisfiable Range" + "

416 Requested Range Not " + "Satisfiable

" + ""; + case basic_response::expectation_failed: + return + "" + "Expectation Failed" + "

417 Expectation Failed

" + ""; + case basic_response::precondition_required: + return + "" + "Precondition Required" + "

428 Precondition Required

" + ""; + case basic_response::too_many_requests: + return + "" + "Too Many Requests" + "

429 Too Many Requests

" + ""; + case basic_response::request_header_fields_too_large: + return + "" + "Request Header Fields Too Large" + "

431 Request Header Fields Too Large

" + ""; + + // 5xx Server Error + case basic_response::internal_server_error: + return + "" + "Internal Server Error" + "

500 Internal Server Error

" + ""; + case basic_response::not_implemented: + return + "" + "Not Implemented" + "

501 Not Implemented

" + ""; + case basic_response::bad_gateway: + return + "" + "Bad Gateway" + "

502 Bad Gateway

" + ""; + case basic_response::service_unavailable: + return + "" + "Service Unavailable" + "

503 Service Unavailable

" + ""; + case basic_response::gateway_timeout: + return + "" + "Gateway Timeout" + "

504 Gateway Timeout

" + ""; + case basic_response::http_version_not_supported: + return + "" + "HTTP Version Not Supported" + "

505 HTTP Version Not Supported

" + ""; + case basic_response::space_unavailable: + return + "" + "Space Unavailable" + "

507 Insufficient Space to Store " + "Resource

" + ""; + + default: + return + "" + "Internal Server Error" + "

500 Internal Server Error

" + ""; + } + } + + boost::asio::const_buffer trim_null(boost::asio::const_buffer buffer) { + std::size_t size = boost::asio::buffer_size(buffer); + return boost::asio::buffer(buffer, size - 1); + } + + boost::asio::const_buffer to_buffer(status_type status) { + using boost::asio::buffer; + switch (status) { + // 2xx Success + case basic_response::ok: + return trim_null(buffer("HTTP/1.1 200 OK\r\n")); + case basic_response::created: + return trim_null(buffer("HTTP/1.1 201 Created\r\n")); + case basic_response::accepted: + return trim_null(buffer("HTTP/1.1 202 Accepted\r\n")); + case basic_response::non_authoritative_information: + return trim_null(buffer("HTTP/1.1 203 Non-Authoritative Information\r\n")); + case basic_response::no_content: + return trim_null(buffer("HTTP/1.1 204 No Content\r\n")); + case basic_response::reset_content: + return trim_null(buffer("HTTP/1.1 205 Reset Content\r\n")); + case basic_response::partial_content: + return trim_null(buffer("HTTP/1.1 206 Partial Content\r\n")); + + // 3xx Redirection + case basic_response::multiple_choices: + return trim_null(buffer("HTTP/1.1 300 Multiple Choices\r\n")); + case basic_response::moved_permanently: + return trim_null(buffer("HTTP/1.1 301 Moved Permanently\r\n")); + case basic_response::moved_temporarily: + return trim_null(buffer("HTTP/1.1 302 Moved Temporarily\r\n")); + case basic_response::see_other: + return trim_null(buffer("HTTP/1.1 303 See Other\r\n")); + case basic_response::not_modified: + return trim_null(buffer("HTTP/1.1 304 Not Modified\r\n")); + case basic_response::use_proxy: + return trim_null(buffer("HTTP/1.1 305 Use Proxy\r\n")); + case basic_response::temporary_redirect: + return trim_null(buffer("HTTP/1.1 307 Temporary Redirect\r\n")); + + // 4xx Client Error + case basic_response::bad_request: + return trim_null(buffer("HTTP/1.1 400 Bad Request\r\n")); + case basic_response::unauthorized: + return trim_null(buffer("HTTP/1.1 401 Unauthorized\r\n")); + case basic_response::forbidden: + return trim_null(buffer("HTTP/1.1 403 Forbidden\r\n")); + case basic_response::not_found: + return trim_null(buffer("HTTP/1.1 404 Not Found\r\n")); + case basic_response::not_supported: + return trim_null(buffer("HTTP/1.1 405 Method Not Supported\r\n")); + case basic_response::not_acceptable: + return trim_null(buffer("HTTP/1.1 406 Method Not Acceptable\r\n")); + case basic_response::proxy_authentication_required: + return trim_null(buffer("HTTP/1.1 407 Proxy Authentication Required\r\n")); + case basic_response::request_timeout: + return trim_null(buffer("HTTP/1.1 408 Request Timeout\r\n")); + case basic_response::conflict: + return trim_null(buffer("HTTP/1.1 409 Conflict\r\n")); + case basic_response::gone: + return trim_null(buffer("HTTP/1.1 410 Gone\r\n")); + case basic_response::length_required: + return trim_null(buffer("HTTP/1.1 411 Length Required\r\n")); + case basic_response::precondition_failed: + return trim_null(buffer("HTTP/1.1 412 Precondition Failed\r\n")); + case basic_response::request_entity_too_large: + return trim_null(buffer("HTTP/1.1 413 Request Entity Too Large\r\n")); + case basic_response::request_uri_too_large: + return trim_null(buffer("HTTP/1.1 414 Request-URI Too Large\r\n")); + case basic_response::unsupported_media_type: + return trim_null(buffer("HTTP/1.1 415 Unsupported Media Type\r\n")); + case basic_response::unsatisfiable_range: + return trim_null(buffer("HTTP/1.1 416 Requested Range Not Satisfiable\r\n")); + case basic_response::precondition_required: + return trim_null(buffer("HTTP/1.1 428 Precondition Required\r\n")); + case basic_response::too_many_requests: + return trim_null(buffer("HTTP/1.1 429 Too Many Requests\r\n")); + case basic_response::request_header_fields_too_large: + return trim_null(buffer("HTTP/1.1 431 Request Header Fields Too Large\r\n")); + + // 5xx Server Error + case basic_response::internal_server_error: + return trim_null(buffer("HTTP/1.1 500 Internal Server Error\r\n")); + case basic_response::not_implemented: + return trim_null(buffer("HTTP/1.1 501 Not Implemented\r\n")); + case basic_response::bad_gateway: + return trim_null(buffer("HTTP/1.1 502 Bad Gateway\r\n")); + case basic_response::service_unavailable: + return trim_null(buffer("HTTP/1.1 503 Service Unavailable\r\n")); + case basic_response::gateway_timeout: + return trim_null(buffer("HTTP/1.1 504 Gateway Timeout\r\n")); + case basic_response::http_version_not_supported: + return trim_null(buffer("HTTP/1.1 505 HTTP Version Not Supported\r\n")); + case basic_response::space_unavailable: + return trim_null(buffer("HTTP/1.1 507 Insufficient Space to Store Resource\r\n")); + + default: + return trim_null(buffer("HTTP/1.1 500 Internal Server Error\r\n")); + } + } +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_IMPL_RESPONSE_RESPONSE_IPP diff --git a/cpp-netlib/boost/network/protocol/http/message.hpp b/cpp-netlib/boost/network/protocol/http/message.hpp new file mode 100644 index 00000000..fa2d44ce --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message.hpp @@ -0,0 +1,137 @@ +// This file is part of the Boost Network library +// Based on the Pion Network Library (r421) +// Copyright Atomic Labs, Inc. 2007-2008 +// See http://cpp-netlib.sourceforge.net for library home page. +// +// 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) +// +// Some changes Copyright (c) Dean Michael Berris 2008 + +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +/// base class for HTTP messages (requests and responses) +template +struct message_impl : public basic_message { + + typedef typename string::type string_type; + + /// escapes URL-encoded strings (a%20value+with%20spaces) + static string_type const url_decode(string_type const &str); + + /// encodes strings so that they are safe for URLs (with%20spaces) + static string_type const url_encode(string_type const &str); + + /// builds an HTTP query string from a collection of query parameters + static string_type const make_query_string( + typename query_container::type const &query_params); + + /** + * creates a "Set-Cookie" header + * + * @param name the name of the cookie + * @param value the value of the cookie + * @param path the path of the cookie + * @param has_max_age true if the max_age value should be set + * @param max_age the life of the cookie, in seconds (0 = discard) + * + * @return the new "Set-Cookie" header + */ + static string_type const make_set_cookie_header( + string_type const &name, string_type const &value, + string_type const &path, bool const has_max_age = false, + unsigned long const max_age = 0); + + /** decodes base64-encoded strings + * + * @param input base64 encoded string + * @param output decoded string ( may include non-text chars) + * @return true if successful, false if input string contains non-base64 + *symbols + */ + static bool base64_decode(string_type const &input, string_type &output); + + /** encodes strings using base64 + * + * @param input arbitrary string ( may include non-text chars) + * @param output base64 encoded string + * @return true if successful + */ + static bool base64_encode(string_type const &input, string_type &output); + + protected: + mutable string_type version_; + mutable boost::uint16_t status_; + mutable string_type status_message_; + + private: + typedef basic_message base_type; + + public: + message_impl() : base_type(), version_(), status_(0u), status_message_() {} + + message_impl(message_impl const &other) + : base_type(other), + version_(other.version_), + status_(other.status_), + status_message_(other.status_message_) {} + + void version(string_type const &version) const { version_ = version; } + + string_type const version() const { return version_; } + + void status(boost::uint16_t status) const { status_ = status; } + + boost::uint16_t status() const { return status_; } + + void status_message(string_type const &status_message) const { + status_message_ = status_message; + } + + string_type const status_message() const { return status_message_; } + + message_impl &operator=(message_impl rhs) { + rhs.swap(*this); + return *this; + } + + void swap(message_impl &other) { + base_type &base_ref(other), &this_ref(*this); + std::swap(this_ref, base_ref); + std::swap(status_, other.status_); + std::swap(status_message_, other.status_message_); + std::swap(version_, other.version_); + } +}; + +template +inline void swap(message_impl &lhs, message_impl &rhs) { + lhs.swap(rhs); +} + +typedef message_impl message; + +} // namespace http + +} // namespace network + +} // namespace boost + +// import implementation file +#include + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HPP diff --git a/cpp-netlib/boost/network/protocol/http/message/async_message.hpp b/cpp-netlib/boost/network/protocol/http/message/async_message.hpp new file mode 100644 index 00000000..854c7075 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/async_message.hpp @@ -0,0 +1,158 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_ASYNC_MESSAGE_HPP_20100622 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_ASYNC_MESSAGE_HPP_20100622 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include +#include + +// FIXME move this out to a trait +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +namespace impl { + +template +struct ready_wrapper; + +} /* impl */ + +template +struct async_message { + + typedef typename string::type string_type; + typedef typename headers_container::type headers_container_type; + typedef typename headers_container_type::value_type header_type; + + async_message() + : status_message_(), + version_(), + source_(), + destination_(), + status_(), + headers_(), + body_() {} + + async_message(async_message const& other) + : status_message_(other.status_message_), + version_(other.version_), + source_(other.source_), + destination_(other.destination_), + status_(other.status_), + headers_(other.headers_), + body_(other.body_) {} + + string_type const status_message() const { return status_message_.get(); } + + void status_message(boost::shared_future const& future) const { + status_message_ = future; + } + + string_type const version() const { return version_.get(); } + + void version(boost::shared_future const& future) const { + version_ = future; + } + + boost::uint16_t status() const { return status_.get(); } + + void status(boost::shared_future const& future) const { + status_ = future; + } + + string_type const source() const { return source_.get(); } + + void source(boost::shared_future const& future) const { + source_ = future; + } + + string_type const destination() const { return destination_.get(); } + + void destination(boost::shared_future const& future) const { + destination_ = future; + } + + headers_container_type const& headers() const { + if (retrieved_headers_) return *retrieved_headers_; + headers_container_type raw_headers = headers_.get(); + raw_headers.insert(added_headers.begin(), added_headers.end()); + BOOST_FOREACH(string_type const & key, removed_headers) { + raw_headers.erase(key); + } + retrieved_headers_ = raw_headers; + return *retrieved_headers_; + } + + void headers(boost::shared_future const& future) + const { + headers_ = future; + } + + void add_header(typename headers_container_type::value_type const& pair_) + const { + added_headers.insert(added_headers.end(), pair_); + } + + void remove_header(typename headers_container_type::key_type const& key_) + const { + removed_headers.insert(key_); + } + + string_type const body() const { return body_.get(); } + + void body(boost::shared_future const& future) const { + body_ = future; + } + + void swap(async_message& other) { + std::swap(status_message_, other.status_message_); + std::swap(status_, other.status_); + std::swap(version_, other.version_); + std::swap(source_, other.source_); + std::swap(destination_, other.destination_); + std::swap(headers_, other.headers_); + std::swap(body_, other.body_); + } + + async_message& operator=(async_message other) { + other.swap(*this); + return *this; + } + + private: + mutable boost::shared_future status_message_, version_, source_, + destination_; + mutable boost::shared_future status_; + mutable boost::shared_future headers_; + mutable headers_container_type added_headers; + mutable std::set removed_headers; + mutable boost::shared_future body_; + mutable boost::optional retrieved_headers_; + + friend struct boost::network::http::impl::ready_wrapper; +}; + +template +inline void swap(async_message& lhs, async_message& rhs) { + lhs.swap(rhs); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_ASYNC_MESSAGE_HPP_20100622 diff --git a/cpp-netlib/boost/network/protocol/http/message/directives/major_version.hpp b/cpp-netlib/boost/network/protocol/http/message/directives/major_version.hpp new file mode 100644 index 00000000..7828b04f --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/directives/major_version.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_MAJOR_VERSION_HPP_20101120 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_MAJOR_VERSION_HPP_20101120 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +struct major_version_directive { + boost::uint8_t major_version; + explicit major_version_directive(boost::uint8_t major_version) + : major_version(major_version) {} + template + void operator()(basic_request& request) const { + request.http_version_major = major_version; + } +}; + +inline major_version_directive major_version(boost::uint8_t major_version_) { + return major_version_directive(major_version_); +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_MAJOR_VERSION_HPP_20101120 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/message/directives/method.hpp b/cpp-netlib/boost/network/protocol/http/message/directives/method.hpp new file mode 100644 index 00000000..b9e2c1df --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/directives/method.hpp @@ -0,0 +1,23 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_METHOD_HPP_20101120 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_METHOD_HPP_20101120 + +// Copyright 2010 Dean Michael Berris. +// 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) + +namespace boost { +namespace network { +namespace http { + +BOOST_NETWORK_STRING_DIRECTIVE(method, method_, message.method(method_), + message.method = method_); + +} /* http */ + +} /* network */ + +} /* booet */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_METHOD_HPP_20101120 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/message/directives/minor_version.hpp b/cpp-netlib/boost/network/protocol/http/message/directives/minor_version.hpp new file mode 100644 index 00000000..4c44414c --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/directives/minor_version.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_MINOR_VERSION_HPP_20101120 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_MINOR_VERSION_HPP_20101120 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +struct minor_version_directive { + boost::uint8_t minor_version; + explicit minor_version_directive(boost::uint8_t minor_version) + : minor_version(minor_version) {} + template + void operator()(basic_request& request) const { + request.http_version_minor = minor_version; + } +}; + +inline minor_version_directive minor_version(boost::uint8_t minor_version_) { + return minor_version_directive(minor_version_); +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_MINOR_VERSION_HPP_20101120 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/message/directives/status.hpp b/cpp-netlib/boost/network/protocol/http/message/directives/status.hpp new file mode 100644 index 00000000..61a41e45 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/directives/status.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_STATUS_HPP_20100603 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_STATUS_HPP_20100603 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +struct status_directive { + + boost::variant > + status_; + + explicit status_directive(boost::uint16_t status) : status_(status) {} + + explicit status_directive(boost::shared_future const &status) + : status_(status) {} + + status_directive(status_directive const &other) : status_(other.status_) {} + + template + struct value : mpl::if_, boost::shared_future, + boost::uint16_t> {}; + + template + struct status_visitor : boost::static_visitor<> { + basic_response const &response; + status_visitor(basic_response const &response) : response(response) {} + + void operator()(typename value::type const &status_) const { + response.status(status_); + } + + template + void operator()(T const &) const { + // FIXME fail here! + } + }; + + template + basic_response const &operator()(basic_response const &response) + const { + apply_visitor(status_visitor(response), status_); + return response; + } +}; + +template +inline status_directive const status(T const &status_) { + return status_directive(status_); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_STATUS_HPP_20100603 diff --git a/cpp-netlib/boost/network/protocol/http/message/directives/status_message.hpp b/cpp-netlib/boost/network/protocol/http/message/directives/status_message.hpp new file mode 100644 index 00000000..2e437ec1 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/directives/status_message.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_STATUS_MESSAGE_HPP_20100603 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_STATUS_MESSAGE_HPP_20100603 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +BOOST_NETWORK_STRING_DIRECTIVE(status_message, status_message_, + message.status_message(status_message_), + message.status_message = status_message_); + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_STATUS_MESSAGE_HPP_20100603 diff --git a/cpp-netlib/boost/network/protocol/http/message/directives/uri.hpp b/cpp-netlib/boost/network/protocol/http/message/directives/uri.hpp new file mode 100644 index 00000000..1a411426 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/directives/uri.hpp @@ -0,0 +1,26 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_URI_HPP_20100620 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_URI_HPP_20100620 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +BOOST_NETWORK_STRING_DIRECTIVE(uri, uri_, message.uri(uri_), + message.uri = uri_); + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_URI_HPP_20100620 diff --git a/cpp-netlib/boost/network/protocol/http/message/directives/version.hpp b/cpp-netlib/boost/network/protocol/http/message/directives/version.hpp new file mode 100644 index 00000000..16c3115d --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/directives/version.hpp @@ -0,0 +1,26 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_VERSION_HPP_20100603 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_VERSION_HPP_20100603 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +BOOST_NETWORK_STRING_DIRECTIVE(version, version_, message.version(version_), + message.version = version_); + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DIRECTIVES_VERSION_HPP_20100603 diff --git a/cpp-netlib/boost/network/protocol/http/message/header.hpp b/cpp-netlib/boost/network/protocol/http/message/header.hpp new file mode 100644 index 00000000..5be2ad80 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/header.hpp @@ -0,0 +1,99 @@ +// +// header.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2009,2010 Dean Michael Berris (mikhailberis@gmail.com) +// Copyright (c) 2009 Tarroo, Inc. +// +// 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_HPP_20101122 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_HPP_20101122 + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct unsupported_tag; + +struct request_header_narrow { + typedef std::string string_type; + std::string name, value; +}; + +struct request_header_wide { + typedef std::wstring string_type; + std::wstring name, value; +}; + +template +struct request_header + : mpl::if_, request_header_narrow, + typename mpl::if_, request_header_wide, + unsupported_tag >::type> {}; + +inline void swap(request_header_narrow& l, request_header_narrow& r) { + swap(l.name, r.name); + swap(l.value, r.value); +} + +inline void swap(request_header_wide& l, request_header_wide& r) { + swap(l.name, r.name); + swap(l.value, r.value); +} + +struct response_header_narrow { + typedef std::string string_type; + std::string name, value; +}; + +struct response_header_wide { + typedef std::wstring string_type; + std::wstring name, value; +}; + +template +struct response_header + : mpl::if_, response_header_narrow, + typename mpl::if_, response_header_wide, + unsupported_tag >::type> {}; + +inline void swap(response_header_narrow& l, response_header_narrow& r) { + std::swap(l.name, r.name); + std::swap(l.value, r.value); +} + +inline void swap(response_header_wide& l, response_header_wide& r) { + std::swap(l.name, r.name); + std::swap(l.value, r.value); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +BOOST_FUSION_ADAPT_STRUCT(boost::network::http::request_header_narrow, + (std::string, name)(std::string, value)) + +BOOST_FUSION_ADAPT_STRUCT(boost::network::http::request_header_wide, + (std::wstring, name)(std::wstring, value)) + +BOOST_FUSION_ADAPT_STRUCT(boost::network::http::response_header_narrow, + (std::string, name)(std::string, value)) + +BOOST_FUSION_ADAPT_STRUCT(boost::network::http::response_header_wide, + (std::wstring, name)(std::wstring, value)) + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_HPP_20101122 diff --git a/cpp-netlib/boost/network/protocol/http/message/header/name.hpp b/cpp-netlib/boost/network/protocol/http/message/header/name.hpp new file mode 100644 index 00000000..a5f6dee2 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/header/name.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_NAME_HPP_20101028 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_NAME_HPP_20101028 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +T1 &name(std::pair const &p) { + return p.first; +} + +inline std::string const &name(request_header_narrow const &h) { + return h.name; +} + +inline std::wstring const &name(request_header_wide const &h) { return h.name; } + +inline std::string const &name(response_header_narrow const &h) { + return h.name; +} + +inline std::wstring const &name(response_header_wide const &h) { + return h.name; +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_NAME_HPP_20101028 */ diff --git a/cpp-netlib/boost/network/protocol/http/message/header/value.hpp b/cpp-netlib/boost/network/protocol/http/message/header/value.hpp new file mode 100644 index 00000000..dd581d00 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/header/value.hpp @@ -0,0 +1,51 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_VALUE_HPP_20101028 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_VALUE_HPP_20101028 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +struct request_header_narrow; +struct request_header_wide; +struct response_header_narrow; +struct response_header_wide; + +template +T1& value(std::pair const& p) { + return p.second; +} + +inline request_header_narrow::string_type const& value( + request_header_narrow const& h) { + return h.value; +} + +inline request_header_wide::string_type const& value( + request_header_wide const& h) { + return h.value; +} + +inline response_header_narrow::string_type const& value( + response_header_narrow const& h) { + return h.value; +} + +inline response_header_wide::string_type const& value( + response_header_wide const& h) { + return h.value; +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_VALUE_HPP_20101028 */ diff --git a/cpp-netlib/boost/network/protocol/http/message/header_concept.hpp b/cpp-netlib/boost/network/protocol/http/message/header_concept.hpp new file mode 100644 index 00000000..f3134e25 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/header_concept.hpp @@ -0,0 +1,38 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_CONCEPT_HPP_20101028 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_CONCEPT_HPP_20101028 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +template +struct Header : DefaultConstructible, Assignable, CopyConstructible { + + BOOST_CONCEPT_USAGE(Header) { + typedef typename H::string_type string_type; + string_type name_ = name(header); + string_type value_ = value(header); + H h1, h2; + swap(h1, h2); // ADL Swap! + (void)name_; + (void)value_; + } + + private: + H header; +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_CONCEPT_HPP_20101028 */ diff --git a/cpp-netlib/boost/network/protocol/http/message/message_base.hpp b/cpp-netlib/boost/network/protocol/http/message/message_base.hpp new file mode 100644 index 00000000..39376531 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/message_base.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_BASE_HPP_20100603 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_BASE_HPP_20100603 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct async_message; + +template +struct message_impl; + +template +struct message_base + : mpl::if_, async_message, message_impl > {}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_BASE_HPP_20100603 diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/body.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/body.hpp new file mode 100644 index 00000000..dd1c7430 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/body.hpp @@ -0,0 +1,77 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_BODY_HPP_20100624 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_BODY_HPP_20100624 + +// Copyright 2010 (C) Dean Michael Berris +// 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) + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +template +struct basic_request; + +namespace impl { + +template +void body(basic_response &response, T const &value, mpl::false_ const &) { + response << ::boost::network::body(value); +} + +template +void body(basic_response &response, T const &future, mpl::true_ const &) { + response.body(future); +} +} + +template +inline void body(basic_response &response, T const &value) { + impl::body(response, value, is_async()); +} + +template +inline void body_impl(basic_request &request, T const &value, + tags::server) { + request.body = value; +} + +template +inline void body_impl(basic_request &request, T const &value, + tags::client) { + request << ::boost::network::body(value); +} + +template +inline void body(basic_request &request, T const &value) { + body_impl(request, value, typename client_or_server::type()); +} + +} // namespace http + +namespace impl { + +template +inline void body(Message const &message, ValueType const &body_, + http::tags::http_server, Async) { + message.body = body_; +} + +} /* impl */ + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_BODY_HPP_20100624 diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/clear_headers.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/clear_headers.hpp new file mode 100644 index 00000000..b723bb04 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/clear_headers.hpp @@ -0,0 +1,52 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_CLEAR_HEADER_HPP_20101128 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_CLEAR_HEADER_HPP_20101128 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +inline void clear_headers_impl(basic_request& request, tags::pod) { + typedef typename basic_request::headers_container_type headers_container; + headers_container().swap(request.headers); +} + +template +inline void clear_headers_impl(basic_request& request, tags::normal) { + request.headers(typename basic_request::headers_container_type()); +} + +template +inline void clear_headers_impl(basic_request& request, tags::client) { + clear_headers_impl(request, typename pod_or_normal::type()); +} + +template +inline void clear_headers_impl(basic_request& request, tags::server) { + typedef typename basic_request::headers_container_type headers_container; + headers_container().swap(request.headers); +} + +template +inline void clear_headers(basic_request& request) { + clear_headers_impl(request, typename client_or_server::type()); +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_CLEAR_HEADER_HPP_20101128 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/destination.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/destination.hpp new file mode 100644 index 00000000..902d7bd1 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/destination.hpp @@ -0,0 +1,95 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_DESTINATION_HPP_20100624 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_DESTINATION_HPP_20100624 + +// Copyright 2010 (C) Dean Michael Berris +// 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) + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +template +struct basic_request; + +namespace impl { + +template +void destination(basic_response &response, T const &value, + mpl::false_ const &) { + response << ::boost::network::destination(value); +} + +template +void destination(basic_response &response, T const &future, + mpl::true_ const &) { + response.destination(future); +} +} + +template +inline void destination(basic_response &response, T const &value) { + impl::destination(response, value, is_async()); +} + +template +struct ServerRequest; + +template +inline void destination_impl(basic_request &request, T const &value, + tags::server) { + request.destination = value; +} + +template +inline void destination_impl(basic_request &request, T const &value, + tags::pod) { + request.destination = value; +} + +template +inline void destination_impl(basic_request &request, T const &value, + tags::normal) { + request.destination(value); +} + +template +inline void destination_impl(basic_request &request, T const &value, + tags::client) { + destination_impl(request, value, typename pod_or_normal::type()); +} + +template +inline void destination(basic_request &request, T const &value) { + destination_impl(request, value, typename client_or_server::type()); +} + +} // namespace http + +namespace impl { + +template +inline void destination(Message const &message, ValueType const &destination_, + http::tags::http_server, Async) { + message.destination = destination_; +} + +} /* impl */ + +} // namespace network + +} // namespace boost + +#include + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_DESTINATION_HPP_20100624 diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/headers.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/headers.hpp new file mode 100644 index 00000000..90354941 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/headers.hpp @@ -0,0 +1,60 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_HEADERS_HPP_20100624 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_HEADERS_HPP_20100624 + +// Copyright 2010 (C) Dean Michael Berris +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +template +struct basic_request; + +namespace impl { + +template +void headers(basic_response &response, T const &value, + mpl::false_ const &) { + response << headers(value); +} + +template +void headers(basic_response &response, T const &future, + mpl::true_ const &) { + response.headers(future); +} + +template +void headers(basic_request &request, T const &value, + tags::server const &) { + request.headers = value; +} +} + +template +inline void headers(basic_response &response, T const &value) { + impl::headers(response, value, is_async()); +} + +template +inline void headers(basic_request &request, T const &value) { + impl::headers(request, value, Tag()); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_HEADERS_HPP_20100624 diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/major_version.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/major_version.hpp new file mode 100644 index 00000000..fbe60eb6 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/major_version.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_MAJOR_VERSION_HPP_20101120 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_MAJOR_VERSION_HPP_20101120 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +template +inline typename enable_if, void>::type major_version( + basic_request& request, boost::uint8_t major_version_) { + request.http_version_major = major_version_; +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_MAJOR_VERSION_HPP_20101120 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/method.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/method.hpp new file mode 100644 index 00000000..8aeab4ce --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/method.hpp @@ -0,0 +1,31 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_METHOD_HPP_20101118 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_METHOD_HPP_20101118 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +template +inline typename enable_if, void>::type method( + basic_request& request, typename string::type const& method_) { + request.method = method_; +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_METHOD_HPP_20101118 */ diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/minor_version.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/minor_version.hpp new file mode 100644 index 00000000..0850ba92 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/minor_version.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_MINOR_VERSION_HPP_20101120 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_MINOR_VERSION_HPP_20101120 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +template +inline typename enable_if, void>::type minor_version( + basic_request& request, boost::uint8_t minor_version_) { + request.http_version_minor = minor_version_; +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_MINOR_VERSION_HPP_20101120 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/source.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/source.hpp new file mode 100644 index 00000000..396b69fa --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/source.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_SOURCE_HPP_20100624 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_SOURCE_HPP_20100624 + +// Copyright 2010 (C) Dean Michael Berris +// 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) + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +namespace impl { + +template +void source(basic_response &response, T const &value, + mpl::false_ const &) { + response << ::boost::network::source(value); +} + +template +void source(basic_response &response, T const &future, + mpl::true_ const &) { + response.source(future); +} + +template +void source(basic_request &request, T const &value, tags::server const &) { + request.source = value; +} + +template +void source(basic_request &request, T const &value, tags::client const &) { + request << ::boost::network::source(value); +} +} + +template +inline void source(basic_response &response, T const &value) { + impl::source(response, value, is_async()); +} + +template +inline void source_impl(basic_request &request, T const &value, + tags::server) { + impl::source(request, value, Tag()); +} + +template +inline void source_impl(basic_request &request, T const &value, + tags::client) { + impl::source(request, value, Tag()); +} + +template +inline void source(basic_request &request, T const &value) { + source_impl(request, value, typename client_or_server::type()); +} + +} // namespace http + +namespace impl { + +template +inline void source(Message const &message, ValueType const &source_, + http::tags::http_server const &, Async const &) { + message.source = source_; +} + +} /* impl */ + +} // namespace network + +} // namespace boost + +#include +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIER_SOURCE_HPP_20100624 diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/status.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/status.hpp new file mode 100644 index 00000000..27a774be --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/status.hpp @@ -0,0 +1,47 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_STATUS_HPP_20100608 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_STATUS_HPP_20100608 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +namespace impl { + +template +void status(basic_response &response, T const &value, + mpl::false_ const &) { + response << boost::network::http::status(value); +} + +template +void status(basic_response &response, T const &future, + mpl::true_ const &) { + response.status(future); +} + +} // namespace impl + +template +void status(basic_response &response, T const &value) { + impl::status(response, value, is_async()); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_STATUS_HPP_20100608 diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/status_message.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/status_message.hpp new file mode 100644 index 00000000..75016305 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/status_message.hpp @@ -0,0 +1,47 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_STATUS_MESSAGE_HPP_20100608 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_STATUS_MESSAGE_HPP_20100608 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +namespace impl { + +template +void status_message(basic_response &response, T const &value, + mpl::false_ const &) { + response << boost::network::http::status_message(value); +} + +template +void status_message(basic_response &response, T const &future, + mpl::true_ const &) { + response.status_message(future); +} + +} // namespace impl + +template +void status_message(basic_response &response, T const &value) { + impl::status_message(response, value, is_async()); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_STATUS_MESSAGE_HPP_20100608 diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/uri.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/uri.hpp new file mode 100644 index 00000000..d173a774 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/uri.hpp @@ -0,0 +1,31 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_URI_HPP_20100621 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_URI_HPP_20100621 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +template +void uri(basic_request& request, T const& value) { + request.uri(value); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_URI_HPP_20100621 diff --git a/cpp-netlib/boost/network/protocol/http/message/modifiers/version.hpp b/cpp-netlib/boost/network/protocol/http/message/modifiers/version.hpp new file mode 100644 index 00000000..f237870b --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/modifiers/version.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_VERSION_HPP_20100608 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_VERSION_HPP_20100608 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +namespace impl { + +template +void version(basic_response &response, T const &value, + mpl::false_ const &) { + response << boost::network::http::version(value); +} + +template +void version(basic_response &response, T const &future, + mpl::true_ const &) { + response.version(future); +} + +} // namespace impl + +template +void version(basic_response &response, T const &value) { + impl::version(response, value, is_async()); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_MODIFIERS_VERSION_HPP_20100608 diff --git a/cpp-netlib/boost/network/protocol/http/message/traits/status.hpp b/cpp-netlib/boost/network/protocol/http/message/traits/status.hpp new file mode 100644 index 00000000..93b66885 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/traits/status.hpp @@ -0,0 +1,36 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_STATUS_HPP_20100903 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_STATUS_HPP_20100903 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +namespace traits { + +template +struct unsupported_tag; + +template +struct status + : mpl::if_< + is_async, + boost::shared_future, + typename mpl::if_, boost::uint16_t, + unsupported_tag >::type> {}; + +} /* traits */ + +} /* http */ +} /* network */ +} /* boost */ + +#endif diff --git a/cpp-netlib/boost/network/protocol/http/message/traits/status_message.hpp b/cpp-netlib/boost/network/protocol/http/message/traits/status_message.hpp new file mode 100644 index 00000000..92487ae7 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/traits/status_message.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_STATUS_MESSAGE_HPP_20100903 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_STATUS_MESSAGE_HPP_20100903 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +namespace traits { + +template +struct unsupported_tag; + +template +struct status_message + : mpl::if_< + is_async, + boost::shared_future::type>, + typename mpl::if_< + mpl::or_, + is_same, + is_same >, + typename string::type, + unsupported_tag >::type> {}; + +} /* traits */ + +} /* http */ +} /* network */ +} /* boost */ + +#endif diff --git a/cpp-netlib/boost/network/protocol/http/message/traits/version.hpp b/cpp-netlib/boost/network/protocol/http/message/traits/version.hpp new file mode 100644 index 00000000..d4b99811 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/traits/version.hpp @@ -0,0 +1,52 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_VERSION_HPP_20100903 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_VERSION_HPP_20100903 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +namespace traits { + +template +struct unsupported_tag; + +template +struct version { + typedef unsupported_tag type; +}; + +template +struct version >::type> { + typedef boost::shared_future::type> + type; +}; + +template +struct version< + Message, typename enable_if< + mpl::or_, + is_default_string, + is_default_wstring > >::type> { + typedef typename string::type type; +}; + +} /* traits */ + +} /* http */ +} /* network */ +} /* boost */ + +#endif diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/anchor.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/anchor.hpp new file mode 100644 index 00000000..27c4dd51 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/anchor.hpp @@ -0,0 +1,38 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_ANCHOR_HPP_20100618 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_ANCHOR_HPP_20100618 + +// Copyright 2010 (c) Dean Michael Berris. +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +namespace impl { +template +struct anchor_wrapper { + basic_request const& message_; + anchor_wrapper(basic_request const& message) : message_(message) {} + typedef typename basic_request::string_type string_type; + operator string_type() { return message_.anchor(); } +}; +} + +template +inline impl::anchor_wrapper anchor(basic_request const& request) { + return impl::anchor_wrapper(request); +} + +} // namespace http + +} // namespace network + +} // nmaespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_ANCHOR_HPP_20100618 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/body.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/body.hpp new file mode 100644 index 00000000..d4d6e63c --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/body.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_BODY_HPP_20100622 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_BODY_HPP_20100622 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +template +struct basic_request; + +namespace impl { + +template +struct body_wrapper { + typedef typename string::type string_type; + Message const& message_; + explicit body_wrapper(Message const& message) : message_(message) {} + body_wrapper(body_wrapper const& other) : message_(other.message_) {} + + operator string_type() const { return message_.body(); } + + size_t size() const { return message_.body().size(); } + + boost::iterator_range range() const { + return boost::make_iterator_range(message_.body()); + } +}; + +template +inline std::ostream& operator<<(std::ostream& os, + body_wrapper const& body) { + os << static_cast::string_type>(body); + return os; +} + +} // namespace impl + +template +inline typename impl::body_wrapper > body( + basic_response const& message) { + return impl::body_wrapper >(message); +} + +template +inline typename impl::body_wrapper > body( + basic_request const& message) { + return impl::body_wrapper >(message); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_BODY_HPP_20100622 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/destination.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/destination.hpp new file mode 100644 index 00000000..8210ab39 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/destination.hpp @@ -0,0 +1,35 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DESTINATION_HPP_20100624 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DESTINATION_HPP_20100624 + +// Copyright 2010 (c) Dean Michael Berris. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +template +struct basic_request; + +template +struct Request; + +template +struct Response; + +BOOST_NETWORK_DEFINE_HTTP_WRAPPER(destination, destination, destination); + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_DESTINATION_HPP_20100624 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/headers.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/headers.hpp new file mode 100644 index 00000000..a1bcd710 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/headers.hpp @@ -0,0 +1,123 @@ + +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPER_HEADERS_HPP_20100811 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPER_HEADERS_HPP_20100811 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct headers_range { + typedef typename headers_container::type + headers_container_type; + typedef typename boost::iterator_range< + typename headers_container_type::const_iterator> type; +}; + +template +struct basic_request; + +template +struct basic_response; + +namespace impl { + +template +struct request_headers_wrapper { + typedef typename string::type string_type; + typedef typename headers_range >::type range_type; + typedef typename headers_container::type headers_container_type; + typedef typename headers_container_type::const_iterator const_iterator; + typedef typename headers_container_type::iterator iterator; + + explicit request_headers_wrapper(basic_request const& message) + : message_(message) {} + + range_type operator[](string_type const& key) const { + return message_.headers().equal_range(key); + } + + typename headers_container_type::size_type count(string_type const& key) + const { + return message_.headers().count(key); + } + + const_iterator begin() const { return message_.headers().begin(); } + + const_iterator end() const { return message_.headers().end(); } + + operator range_type() { + return make_iterator_range(message_.headers().begin(), + message_.headers().end()); + } + + operator headers_container_type() { return message_.headers(); } + + private: + basic_request const& message_; +}; + +template +struct response_headers_wrapper { + typedef typename string::type string_type; + typedef typename headers_range >::type range_type; + typedef typename headers_container::type headers_container_type; + typedef typename headers_container_type::const_iterator const_iterator; + typedef typename headers_container_type::iterator iterator; + + explicit response_headers_wrapper(basic_response const& message) + : message_(message) {} + + range_type operator[](string_type const& key) const { + return message_.headers().equal_range(key); + } + + typename headers_container_type::size_type count(string_type const& key) + const { + return message_.headers().count(key); + } + + const_iterator begin() const { return message_.headers().begin(); } + + const_iterator end() const { return message_.headers().end(); } + + operator range_type() { + return make_iterator_range(message_.headers().begin(), + message_.headers().end()); + } + + operator headers_container_type() { return message_.headers(); } + + private: + basic_response const& message_; +}; + +} // namespace impl + +template +inline impl::request_headers_wrapper headers( + basic_request const& request_) { + return impl::request_headers_wrapper(request_); +} + +template +inline impl::response_headers_wrapper headers( + basic_response const& response_) { + return impl::response_headers_wrapper(response_); +} + +} // namepace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPER_HEADERS_HPP_20100811 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/helper.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/helper.hpp new file mode 100644 index 00000000..2f463414 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/helper.hpp @@ -0,0 +1,58 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_HELPER_20101013 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_HELPER_20101013 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include + +#ifndef BOOST_NETWORK_DEFINE_HTTP_WRAPPER +#define BOOST_NETWORK_DEFINE_HTTP_WRAPPER(name, accessor, pod_field) \ + struct name##_pod_accessor { \ + protected: \ + template \ + typename Message::string_type const& get_value(Message const& message) \ + const { \ + return message.pod_field; \ + } \ + }; \ + \ + struct name##_member_accessor { \ + protected: \ + template \ + typename Message::string_type get_value(Message const& message) const { \ + return message.accessor(); \ + } \ + }; \ + \ + template \ + struct name##_wrapper_impl \ + : mpl::if_, name##_pod_accessor, \ + name##_member_accessor> {}; \ + \ + template \ + struct name##_wrapper : name##_wrapper_impl::type { \ + typedef typename string::type string_type; \ + Message const& message_; \ + name##_wrapper(Message const& message) : message_(message) {} \ + name##_wrapper(name##_wrapper const& other) : message_(other.message_) {} \ + operator string_type() const { return this->get_value(message_); } \ + }; \ + \ + template \ + inline name##_wrapper > const name( \ + basic_response const& message) { \ + return name##_wrapper >(message); \ + } \ + \ + template \ + inline name##_wrapper > const name( \ + basic_request const& message) { \ + return name##_wrapper >(message); \ + } + +#endif /* BOOST_NETWORK_DEFINE_HTTP_WRAPPER */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_HELPER_20101013 */ diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/host.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/host.hpp new file mode 100644 index 00000000..9841674d --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/host.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HOST_HPP_20100618 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HOST_HPP_20100618 + +// Copyright 2010 (c) Dean Michael Berris. +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +namespace impl { + +template +struct host_wrapper { + basic_request const& message_; + + host_wrapper(basic_request const& message) : message_(message) {} + + typedef typename basic_request::string_type string_type; + + operator string_type() { return message_.host(); } +}; +} + +template +inline impl::host_wrapper host(basic_request const& request) { + return impl::host_wrapper(request); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HOST_HPP_20100618 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/major_version.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/major_version.hpp new file mode 100644 index 00000000..40ad3d52 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/major_version.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_MAJOR_VERSION_HPP_20101120 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_MAJOR_VERSION_HPP_20101120 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +template +struct major_version_wrapper { + basic_request const& request; + explicit major_version_wrapper(basic_request const& request) + : request(request) {} + operator boost::uint8_t() { return request.http_version_major; } +}; + +template +inline typename enable_if, major_version_wrapper >::type +major_version(basic_request const& request) { + return major_version_wrapper(request); +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_MAJOR_VERSION_HPP_20101120 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/method.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/method.hpp new file mode 100644 index 00000000..6f194d3f --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/method.hpp @@ -0,0 +1,43 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_METHOD_HPP_20101118 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_METHOD_HPP_20101118 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +template +struct method_wrapper { + explicit method_wrapper(basic_request const& message) + : message_(message) {} + + basic_request const& message_; + + typedef typename basic_request::string_type string_type; + + operator string_type() { return message_.method; } +}; + +template +inline typename enable_if, typename string::type>::type +method(basic_request const& message) { + return method_wrapper(message); +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_METHOD_HPP_20101118 */ diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/minor_version.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/minor_version.hpp new file mode 100644 index 00000000..aad54e38 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/minor_version.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_MINOR_VERSION_HPP_20101120 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_MINOR_VERSION_HPP_20101120 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +template +struct minor_version_wrapper { + basic_request const& request; + explicit minor_version_wrapper(basic_request const& request) + : request(request) {} + operator boost::uint8_t() { return request.http_version_minor; } +}; + +template +inline typename enable_if, minor_version_wrapper >::type +minor_version(basic_request const& request) { + return minor_version_wrapper(request); +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_MINOR_VERSION_HPP_20101120 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/path.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/path.hpp new file mode 100644 index 00000000..56f67e5c --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/path.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_PATH_HPP_20100618 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_PATH_HPP_20100618 + +// Copyright 2010 (c) Dean Michael Berris. +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +namespace impl { + +template +struct path_wrapper { + basic_request const& message_; + + path_wrapper(basic_request const& message) : message_(message) {} + + typedef typename basic_request::string_type string_type; + + operator string_type() { return message_.path(); } +}; +} + +template +inline impl::path_wrapper path(basic_request const& request) { + return impl::path_wrapper(request); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_PATH_HPP_20100618 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/port.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/port.hpp new file mode 100644 index 00000000..f05d9dc8 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/port.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_PORT_HPP_20100618 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_PORT_HPP_20100618 + +// Copyright 2010, 2014 Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2014 Google, Inc. +// Copyright 2014 Jussi Lyytinen +// 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) + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +namespace impl { + +template +struct port_wrapper { + basic_request const& message_; + + port_wrapper(basic_request const& message) : message_(message) {} + + typedef typename basic_request::port_type port_type; + + operator port_type() const { return message_.port(); } + +#if (_MSC_VER >= 1600 && BOOST_VERSION > 105500) + // Because of a breaking change in Boost 1.56 to boost::optional, implicit + // conversions no longer work correctly with MSVC. The conversion therefore + // has to be done explicitly with as_optional(). + boost::optional as_optional() const { + return uri::port_us(message_.uri()); + } +#else + operator boost::optional() const { + return uri::port_us(message_.uri()); + } +#endif + +}; + +} // namespace impl + +template +inline impl::port_wrapper port(basic_request const& request) { + return impl::port_wrapper(request); +} + +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_PORT_HPP_20100618 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/protocol.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/protocol.hpp new file mode 100644 index 00000000..0b18fda8 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/protocol.hpp @@ -0,0 +1,38 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_PROTOCOL_HPP_20100619 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_PROTOCOL_HPP_20100619 + +// Copyright 2010 (c) Dean Michael Berris. +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +namespace impl { +template +struct protocol_wrapper { + basic_request const& message_; + protocol_wrapper(basic_request const& message) : message_(message) {} + typedef typename basic_request::string_type string_type; + operator string_type() { return message_.protocol(); } +}; +} + +template +inline impl::protocol_wrapper protocol(basic_request const& request) { + return impl::protocol_wrapper(request); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_PROTOCOL_HPP_20100619 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/query.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/query.hpp new file mode 100644 index 00000000..3d3353c6 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/query.hpp @@ -0,0 +1,43 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_QUERY_HPP_20100618 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_QUERY_HPP_20100618 + +// Copyright 2010 (c) Dean Michael Berris. +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +namespace impl { + +template +struct query_wrapper { + basic_request const& message_; + + query_wrapper(basic_request const& message) : message_(message) {} + + typedef typename basic_request::string_type string_type; + + operator string_type() { return message_.query(); } +}; + +} // namespace impl + +template +inline impl::query_wrapper query(basic_request const& request) { + return impl::query_wrapper(request); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_QUERY_HPP_20100618 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/ready.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/ready.hpp new file mode 100644 index 00000000..cb1ab354 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/ready.hpp @@ -0,0 +1,47 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_READY_HPP_20100618 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_READY_HPP_20100618 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +template +struct async_message; + +namespace impl { +template +struct ready_wrapper + : boost::network::detail::wrapper_base_const > { + typedef boost::network::detail::wrapper_base_const > + wrapper_base; + explicit ready_wrapper(async_message const& message) + : wrapper_base(message) {} + operator bool() { + return wrapper_base::_message.version_.is_ready() && + wrapper_base::_message.status_.is_ready() && + wrapper_base::_message.status_message_.is_ready() && + wrapper_base::_message.headers_.is_ready() && + wrapper_base::_message.body_.is_ready(); + } +}; +} // namespace impl + +template +inline bool ready(async_message const& message) { + return impl::ready_wrapper(message); +} + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_READY_HPP_20100618 */ diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/source.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/source.hpp new file mode 100644 index 00000000..e4dee116 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/source.hpp @@ -0,0 +1,29 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_SOURCE_HPP_20100622 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_SOURCE_HPP_20100622 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +template +struct basic_request; + +BOOST_NETWORK_DEFINE_HTTP_WRAPPER(source, source, source); + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_SOURCE_HPP_20100622 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/status.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/status.hpp new file mode 100644 index 00000000..06ecc6ec --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/status.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_STATUS_HPP_20100603 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_STATUS_HPP_20100603 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +namespace impl { + +template +struct status_wrapper { + + basic_response const& response_; + + explicit status_wrapper(basic_response const& response) + : response_(response) {} + + status_wrapper(status_wrapper const& other) : response_(other.response_) {} + + operator boost::uint16_t() { return response_.status(); } +}; + +} // namespace impl + +template +struct Response; + +template +inline impl::status_wrapper status(basic_response const& response) { + return impl::status_wrapper(response); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_STATUS_HPP_20100603 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/status_message.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/status_message.hpp new file mode 100644 index 00000000..ea4c8fc4 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/status_message.hpp @@ -0,0 +1,58 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_STATUS_MESSAGE_HPP_20100603 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_STATUS_MESSAGE_HPP_20100603 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// Copyright 2014 (c) Google, Inc. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +namespace impl { + +template +struct status_message_wrapper { + + typedef typename string::type string_type; + + basic_response const& response_; + + explicit status_message_wrapper(basic_response const& response) + : response_(response) {} + + status_message_wrapper(status_message_wrapper const& other) + : response_(other.response_) {} + + operator string_type() const { return response_.status_message(); } +}; + +template +inline std::ostream& operator<<(std::ostream& os, + const status_message_wrapper& wrapper) { + return os << static_cast::type>(wrapper); +} + +} // namespace impl + +template +inline impl::status_message_wrapper status_message( + basic_response const& response) { + return impl::status_message_wrapper(response); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPER_STATUS_MESSAGE_HPP_20100603 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/uri.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/uri.hpp new file mode 100644 index 00000000..2e80d1c6 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/uri.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_URI_HPP_20100620 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_URI_HPP_20100620 + +// Copyright 2010 (c) Dean Michael Berris. +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +namespace impl { +template +struct uri_wrapper { + basic_request const& message_; + uri_wrapper(basic_request const& message) : message_(message) {} + typedef typename basic_request::string_type string_type; + operator string_type() { return message_.uri().raw(); } + operator boost::network::uri::uri() { return message_.uri(); } +}; +} + +template +inline impl::uri_wrapper uri(basic_request const& request) { + return impl::uri_wrapper(request); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_URI_HPP_20100620 diff --git a/cpp-netlib/boost/network/protocol/http/message/wrappers/version.hpp b/cpp-netlib/boost/network/protocol/http/message/wrappers/version.hpp new file mode 100644 index 00000000..c0502284 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/message/wrappers/version.hpp @@ -0,0 +1,47 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_VERSION_HPP_20100603 +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_VERSION_HPP_20100603 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response; + +namespace impl { + +template +struct version_wrapper { + + typedef typename string::type string_type; + + basic_response const& response_; + + explicit version_wrapper(basic_response const& response) + : response_(response) {} + + version_wrapper(version_wrapper const& other) : response_(other.response_) {} + + operator string_type() { return response_.version(); } +}; + +} // namespace impl + +template +inline impl::version_wrapper version(basic_response const& response) { + return impl::version_wrapper(response); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_WRAPPERS_VERSION_HPP_20100603 diff --git a/cpp-netlib/boost/network/protocol/http/parser.hpp b/cpp-netlib/boost/network/protocol/http/parser.hpp new file mode 100644 index 00000000..d0e33e79 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/parser.hpp @@ -0,0 +1,352 @@ +// This file is part of the Boost Network library +// Based on the Pion Network Library (r421) +// Copyright Atomic Labs, Inc. 2007-2008 +// See http://cpp-netlib.sourceforge.net for library home page. +// +// 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_HPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +// forward declarations used to finish HTTP requests +template +class basic_request; + +// forward declarations used to finish HTTP requests +template +class basic_response; + +/// an incremental HTTP 1.0/1.1 protocol parser +template > +class basic_parser : private boost::noncopyable { + public: + // import types from ParserTraits template + typedef ParserTraits traits_type; + typedef typename string::type string_type; + + // default destructor + virtual ~basic_parser() {} + + /** + * creates a new HTTP protocol parser + * + * @param is_request if true, the message is parsed as an HTTP request; + * if false, the message is parsed as an HTTP response + */ + basic_parser(const bool is_request) + : m_is_request(is_request), + m_read_ptr(NULL), + m_read_end_ptr(NULL), + m_headers_parse_state(is_request ? PARSE_METHOD_START + : PARSE_HTTP_VERSION_H), + m_chunked_content_parse_state(PARSE_CHUNK_SIZE_START), + m_status_code(0), + m_bytes_last_read(0), + m_bytes_total_read(0) {} + + /** + * parses an HTTP message up to the end of the headers using bytes + * available in the read buffer + * + * @param http_msg the HTTP message object to populate from parsing + * + * @return boost::tribool result of parsing: + * false = message has an error, + * true = finished parsing HTTP headers, + * indeterminate = not yet finished parsing HTTP + *headers + */ + boost::tribool parse_http_headers(basic_message& http_msg); + + /** + * parses a chunked HTTP message-body using bytes available in the read + *buffer + * + * @param chunk_buffers buffers to be populated from parsing chunked + *content + * + * @return boost::tribool result of parsing: + * false = message has an error, + * true = finished parsing message, + * indeterminate = message is not yet finished + */ + boost::tribool parse_chunks(types::chunk_cache_t& chunk_buffers); + + /** + * prepares the payload content buffer and consumes any content + *remaining + * in the parser's read buffer + * + * @param http_msg the HTTP message object to consume content for + * @return unsigned long number of content bytes consumed, if any + */ + std::size_t consume_content(basic_message& http_msg); + + /** + * consume the bytes available in the read buffer, converting them into + * the next chunk for the HTTP message + * + * @param chunk_buffers buffers to be populated from parsing chunked + *content + * @return unsigned long number of content bytes consumed, if any + */ + std::size_t consume_content_as_next_chunk( + types::chunk_cache_t& chunk_buffers); + + /** + * finishes parsing an HTTP request message (copies over request-only + *data) + * + * @param http_request the HTTP request object to finish + */ + void finish(basic_request& http_request); + + /** + * finishes an HTTP response message (copies over response-only data) + * + * @param http_request the HTTP response object to finish + */ + void finish(basic_response& http_response); + + /** + * resets the location and size of the read buffer + * + * @param ptr pointer to the first bytes available to be read + * @param len number of bytes available to be read + */ + inline void set_read_buffer(const char* ptr, std::size_t len) { + m_read_ptr = ptr; + m_read_end_ptr = ptr + len; + } + + /** + * saves the current read position bookmark + * + * @param read_ptr points to the next character to be consumed in the + *read_buffer + * @param read_end_ptr points to the end of the read_buffer (last byte + + *1) + */ + inline void save_read_position(const char*& read_ptr, + const char*& read_end_ptr) const { + read_ptr = m_read_ptr; + read_end_ptr = m_read_end_ptr; + } + + /// resets the parser to its initial state + inline void reset(void); + + /// returns true if there are no more bytes available in the read buffer + inline bool eof(void) const { + return m_read_ptr == NULL || m_read_ptr >= m_read_end_ptr; + } + + /// returns the number of bytes read during the last parse operation + inline std::size_t gcount(void) const { return m_bytes_last_read; } + + /// returns the total number of bytes read while parsing the HTTP + /// message + inline std::size_t bytes_read(void) const { return m_bytes_total_read; } + + /// returns the number of bytes available in the read buffer + inline std::size_t bytes_available(void) const { + return (eof() ? 0 : (m_read_end_ptr - m_read_ptr)); + } + + protected: + /** + * parse key-value pairs out of a url-encoded string + * (i.e. this=that&a=value) + * + * @param params container for key-values string pairs + * @param ptr points to the start of the encoded string + * @param len length of the encoded string, in bytes + * + * @return bool true if successful + */ + static bool parse_url_encoded(types::query_params& params, const char* ptr, + const std::size_t len); + + /** + * parse key-value pairs out of a "Cookie" request header + * (i.e. this=that; a=value) + * + * @param params container for key-values string pairs + * @param cookie_header header string to be parsed + * + * @return bool true if successful + */ + static bool parse_cookie_header(types::cookie_params& params, + const string_type& cookie_header); + + /// true if the message is an HTTP request; false if it is an HTTP + /// response + const bool m_is_request; + + /// points to the next character to be consumed in the read_buffer + const char* m_read_ptr; + + /// points to the end of the read_buffer (last byte + 1) + const char* m_read_end_ptr; + + private: + // returns true if the argument is a special character + inline static bool is_special(int c) { + switch (c) { + case '(': + case ')': + case '<': + case '>': + case '@': + case ',': + case ';': + case ':': + case '\\': + case '"': + case '/': + case '[': + case ']': + case '?': + case '=': + case '{': + case '}': + case ' ': + case '\t': + return true; + default: + return false; + } + } + + // returns true if the argument is a character + inline static bool is_char(int c) { return (c >= 0 && c <= 127); } + + // returns true if the argument is a control character + inline static bool is_control(int c) { + return ((c >= 0 && c <= 31) || c == 127); + } + + // returns true if the argument is a digit + inline static bool is_digit(int c) { return (c >= '0' && c <= '9'); } + + // returns true if the argument is a hexadecimal digit + inline static bool is_hex_digit(int c) { + return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F')); + } + + /// state used to keep track of where we are in parsing the HTTP headers + enum headers_parse_state_t { + PARSE_METHOD_START, + PARSE_METHOD, + PARSE_URI_STEM, + PARSE_URI_QUERY, + PARSE_HTTP_VERSION_H, + PARSE_HTTP_VERSION_T_1, + PARSE_HTTP_VERSION_T_2, + PARSE_HTTP_VERSION_P, + PARSE_HTTP_VERSION_SLASH, + PARSE_HTTP_VERSION_MAJOR_START, + PARSE_HTTP_VERSION_MAJOR, + PARSE_HTTP_VERSION_MINOR_START, + PARSE_HTTP_VERSION_MINOR, + PARSE_STATUS_CODE_START, + PARSE_STATUS_CODE, + PARSE_STATUS_MESSAGE, + PARSE_EXPECTING_NEWLINE, + PARSE_EXPECTING_CR, + PARSE_HEADER_WHITESPACE, + PARSE_HEADER_START, + PARSE_HEADER_NAME, + PARSE_SPACE_BEFORE_HEADER_VALUE, + PARSE_HEADER_VALUE, + PARSE_EXPECTING_FINAL_NEWLINE, + PARSE_EXPECTING_FINAL_CR + }; + + /// state used to keep track of where we are in parsing chunked content + enum chunked_content_parse_state_t { + PARSE_CHUNK_SIZE_START, + PARSE_CHUNK_SIZE, + PARSE_EXPECTING_CR_AFTER_CHUNK_SIZE, + PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE, + PARSE_CHUNK, + PARSE_EXPECTING_CR_AFTER_CHUNK, + PARSE_EXPECTING_LF_AFTER_CHUNK, + PARSE_EXPECTING_FINAL_CR_AFTER_LAST_CHUNK, + PARSE_EXPECTING_FINAL_LF_AFTER_LAST_CHUNK + }; + + /// the current state of parsing HTTP headers + headers_parse_state_t m_headers_parse_state; + + /// the current state of parsing chunked content + chunked_content_parse_state_t m_chunked_content_parse_state; + + /// Used for parsing the HTTP response status code + boost::uint16_t m_status_code; + + /// Used for parsing the HTTP response status message + string_type m_status_message; + + /// Used for parsing the request method + string_type m_method; + + /// Used for parsing the name of resource requested + string_type m_resource; + + /// Used for parsing the query string portion of a URI + string_type m_query_string; + + /// Used for parsing the name of HTTP headers + string_type m_header_name; + + /// Used for parsing the value of HTTP headers + string_type m_header_value; + + /// Used for parsing the chunk size + string_type m_chunk_size_str; + + /// Used for parsing the current chunk + std::vector m_current_chunk; + + /// number of bytes in the chunk currently being parsed + std::size_t m_size_of_current_chunk; + + /// number of bytes read so far in the chunk currently being parsed + std::size_t m_bytes_read_in_current_chunk; + + /// number of bytes read during last parse operation + std::size_t m_bytes_last_read; + + /// total number of bytes read while parsing the HTTP message + std::size_t m_bytes_total_read; +}; + +/// typedef for the default HTTP protocol parser implementation +typedef basic_parser parser; + +}; // namespace http + +}; // namespace network + +}; // namespace boost + +// import implementation file +#include + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_HPP diff --git a/cpp-netlib/boost/network/protocol/http/parser/incremental.hpp b/cpp-netlib/boost/network/protocol/http/parser/incremental.hpp new file mode 100644 index 00000000..ba7222a3 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/parser/incremental.hpp @@ -0,0 +1,312 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_INCREMENTAL_HPP_20100909 +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_INCREMENTAL_HPP_20100909 + +// Copyright Dean Michael Berris 2010. +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct response_parser { + + enum state_t { + http_response_begin, + http_version_h, + http_version_t1, + http_version_t2, + http_version_p, + http_version_slash, + http_version_major, + http_version_dot, + http_version_minor, + http_version_done, + http_status_digit, + http_status_done, + http_status_message_char, + http_status_message_cr, + http_status_message_done, + http_header_name_char, + http_header_colon, + http_header_value_char, + http_header_line_cr, + http_header_line_done, + http_headers_end_cr, + http_headers_done + }; + + explicit response_parser(state_t state = http_response_begin) + : state_(state) {} + + response_parser(response_parser const& other) : state_(other.state_) {} + + ~response_parser() {} + + void swap(response_parser& other) { std::swap(other.state_, this->state_); } + + response_parser& operator=(response_parser rhs) { + rhs.swap(*this); + return *this; + } + + template + fusion::tuple > + parse_until(state_t stop_state, Range& range_) { + logic::tribool parsed_ok(logic::indeterminate); + typename Range::const_iterator start = boost::begin(range_), + current = start, end = boost::end(range_); + boost::iterator_range local_range = + boost::make_iterator_range(start, end); + while (!boost::empty(local_range) && indeterminate(parsed_ok)) { + current = boost::begin(local_range); + if (state_ == stop_state) { + parsed_ok = true; + } else { + switch (state_) { + case http_response_begin: + if (*current == ' ' || *current == '\r' || *current == '\n') { + // skip valid leading whitespace + ++start; + ++current; + } else if (*current == 'H') { + state_ = http_version_h; + start = current; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_h: + if (*current == 'T') { + state_ = http_version_t1; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_t1: + if (*current == 'T') { + state_ = http_version_t2; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_t2: + if (*current == 'P') { + state_ = http_version_p; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_p: + if (*current == '/') { + state_ = http_version_slash; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_slash: + if (algorithm::is_digit()(*current)) { + state_ = http_version_major; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_major: + if (*current == '.') { + state_ = http_version_dot; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_dot: + if (algorithm::is_digit()(*current)) { + state_ = http_version_minor; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_minor: + if (*current == ' ') { + state_ = http_version_done; + ++current; + } else { + parsed_ok = false; + } + break; + case http_version_done: + if (algorithm::is_digit()(*current)) { + state_ = http_status_digit; + ++current; + } else { + parsed_ok = false; + } + break; + case http_status_digit: + if (algorithm::is_digit()(*current)) { + ++current; + } else if (*current == ' ') { + state_ = http_status_done; + ++current; + } else if (*current == '\r' || *current == '\n') { + state_ = http_status_done; + } else { + parsed_ok = false; + } + break; + case http_status_done: + if (*current == ' ') { + ++current; + } else if (*current == '\r') { + state_ = http_status_message_cr; + ++current; + } else if (*current == '\n') { + state_ = http_status_message_done; + ++current; + } else { + state_ = http_status_message_char; + ++current; + } + break; + case http_status_message_char: + if (*current == '\r') { + state_ = http_status_message_cr; + ++current; + } else if (*current == '\n') { + state_ = http_status_message_done; + ++current; + } else { + ++current; + } + break; + case http_status_message_cr: + if (*current == '\n') { + state_ = http_status_message_done; + ++current; + } else { + parsed_ok = false; + } + break; + case http_status_message_done: + case http_header_line_done: + if (*current == ' ') { + ++current; + } else if (algorithm::is_alnum()(*current) || + algorithm::is_punct()(*current)) { + state_ = http_header_name_char; + ++current; + } else if (*current == '\r') { + state_ = http_headers_end_cr; + ++current; + } else if (*current == '\n') { + state_ = http_headers_done; + ++current; + } else { + parsed_ok = false; + } + break; + case http_header_name_char: + if (*current == ':') { + state_ = http_header_colon; + ++current; + } else if (*current == '\r') { + state_ = http_header_line_cr; + ++current; + } else if (*current == '\n') { + state_ = http_header_line_done; + ++current; + } else if (algorithm::is_alnum()(*current) || + algorithm::is_space()(*current) || + algorithm::is_punct()(*current)) { + ++current; + } else { + parsed_ok = false; + } + break; + case http_header_colon: + if (*current == '\r') { + state_ = http_header_line_cr; + ++current; + } else if (*current == '\n') { + state_ = http_header_line_done; + ++current; + } else if (algorithm::is_space()(*current)) { + ++current; + } else { + state_ = http_header_value_char; + ++current; + } + break; + case http_header_value_char: + if (*current == '\r') { + state_ = http_header_line_cr; + ++current; + } else if (*current == '\n') { + state_ = http_header_line_done; + ++current; + } else { + ++current; + } + break; + case http_header_line_cr: + if (*current == '\n') { + state_ = http_header_line_done; + ++current; + } else { + parsed_ok = false; + } + break; + case http_headers_end_cr: + if (*current == '\n') { + state_ = http_headers_done; + ++current; + } else { + parsed_ok = false; + } + break; + default: + parsed_ok = false; + } + } + + local_range = boost::make_iterator_range(current, end); + } + if (state_ == stop_state) parsed_ok = true; + return fusion::make_tuple(parsed_ok, + boost::make_iterator_range(start, current)); + } + + state_t state() { return state_; } + + void reset(state_t new_state = http_response_begin) { state_ = new_state; } + + private: + state_t state_; +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif diff --git a/cpp-netlib/boost/network/protocol/http/policies/async_connection.hpp b/cpp-netlib/boost/network/protocol/http/policies/async_connection.hpp new file mode 100644 index 00000000..667712b3 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/policies/async_connection.hpp @@ -0,0 +1,111 @@ +#ifndef BOOST_NETWORK_POLICY_ASYNC_CONNECTION_HPP_20100529 +#define BOOST_NETWORK_POLICY_ASYNC_CONNECTION_HPP_20100529 + +// Copyright 2010 (C) Dean Michael Berris +// Copyright 2010 (C) Sinefunc, Inc. +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct async_connection_policy : resolver_policy::type { + protected: + typedef typename string::type string_type; + typedef typename resolver_policy::type resolver_base; + typedef typename resolver_base::resolver_type resolver_type; + typedef typename resolver_base::resolve_function resolve_function; + typedef function const&, + system::error_code const&)> body_callback_function_type; + typedef function body_generator_function_type; + + struct connection_impl { + connection_impl(bool follow_redirect, bool always_verify_peer, + resolve_function resolve, resolver_type& resolver, + bool https, int timeout, + optional const& certificate_filename, + optional const& verify_path, + optional const& certificate_file, + optional const& private_key_file, + optional const& ciphers, long ssl_options) { + pimpl = impl::async_connection_base< + Tag, version_major, + version_minor>::new_connection(resolve, resolver, follow_redirect, + always_verify_peer, https, timeout, + certificate_filename, verify_path, + certificate_file, private_key_file, + ciphers, ssl_options); + } + + basic_response send_request(string_type const& method, + basic_request const& request_, + bool get_body, + body_callback_function_type callback, + body_generator_function_type generator) { + return pimpl->start(request_, method, get_body, callback, generator); + } + + private: + shared_ptr > pimpl; + }; + + typedef boost::shared_ptr connection_ptr; + connection_ptr get_connection( + resolver_type& resolver, basic_request const& request_, + bool always_verify_peer, + optional const& certificate_filename = + optional(), + optional const& verify_path = optional(), + optional const& certificate_file = optional(), + optional const& private_key_file = optional(), + optional const& ciphers = optional(), + long ssl_options = 0) { + string_type protocol_ = protocol(request_); + connection_ptr connection_(new connection_impl( + follow_redirect_, always_verify_peer, + boost::bind(&async_connection_policy::resolve, + this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>(), + boost::arg<4>()), + resolver, boost::iequals(protocol_, string_type("https")), timeout_, + certificate_filename, verify_path, certificate_file, private_key_file, + ciphers, ssl_options)); + return connection_; + } + + void cleanup() {} + + async_connection_policy(bool cache_resolved, bool follow_redirect, + int timeout) + : resolver_base(cache_resolved), + follow_redirect_(follow_redirect), + timeout_(timeout) {} + + bool follow_redirect_; + int timeout_; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_POLICY_ASYNC_CONNECTION_HPP_ diff --git a/cpp-netlib/boost/network/protocol/http/policies/async_resolver.hpp b/cpp-netlib/boost/network/protocol/http/policies/async_resolver.hpp new file mode 100644 index 00000000..61a71014 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/policies/async_resolver.hpp @@ -0,0 +1,91 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_20100622 +#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_20100622 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { +namespace policies { + +template +struct async_resolver : boost::enable_shared_from_this > { + typedef typename resolver::type resolver_type; + typedef typename resolver_type::iterator resolver_iterator; + typedef typename resolver_type::query resolver_query; + typedef std::pair + resolver_iterator_pair; + typedef typename string::type string_type; + typedef boost::unordered_map + endpoint_cache; + typedef boost::function< + void(boost::system::error_code const &, resolver_iterator_pair)> + resolve_completion_function; + typedef boost::function resolve_function; + + protected: + bool cache_resolved_; + endpoint_cache endpoint_cache_; + boost::shared_ptr service_; + boost::shared_ptr resolver_strand_; + + explicit async_resolver(bool cache_resolved) + : cache_resolved_(cache_resolved), endpoint_cache_() {} + + void resolve(resolver_type &resolver_, string_type const &host, + boost::uint16_t port, + resolve_completion_function once_resolved) { + if (cache_resolved_) { + typename endpoint_cache::iterator iter = + endpoint_cache_.find(boost::to_lower_copy(host)); + if (iter != endpoint_cache_.end()) { + boost::system::error_code ignored; + once_resolved(ignored, iter->second); + return; + } + } + + typename resolver_type::query q(host, + lexical_cast(port)); + resolver_.async_resolve(q, resolver_strand_->wrap(boost::bind( + &async_resolver::handle_resolve, + async_resolver::shared_from_this(), + boost::to_lower_copy(host), once_resolved, + boost::asio::placeholders::error, + boost::asio::placeholders::iterator))); + } + + void handle_resolve(string_type const &host, + resolve_completion_function once_resolved, + boost::system::error_code const &ec, + resolver_iterator endpoint_iterator) { + typename endpoint_cache::iterator iter; + bool inserted = false; + if (!ec && cache_resolved_) { + boost::fusion::tie(iter, inserted) = + endpoint_cache_.insert(std::make_pair( + host, std::make_pair(endpoint_iterator, resolver_iterator()))); + once_resolved(ec, iter->second); + } else { + once_resolved(ec, std::make_pair(endpoint_iterator, resolver_iterator())); + } + } +}; + +} // namespace policies + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_ASYNC_RESOLVER_20100622 diff --git a/cpp-netlib/boost/network/protocol/http/policies/pooled_connection.hpp b/cpp-netlib/boost/network/protocol/http/policies/pooled_connection.hpp new file mode 100644 index 00000000..2ac32845 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/policies/pooled_connection.hpp @@ -0,0 +1,236 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POOLED_CONNECTION_POLICY_20091214 +#define BOOST_NETWORK_PROTOCOL_HTTP_POOLED_CONNECTION_POLICY_20091214 + +// Copyright 2013 Google, Inc. +// Copyright 2009 Dean Michael Berris +// 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) + +#include + +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT +#define BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT 5 +#endif // BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT + +namespace boost { +namespace network { +namespace http { + +template +struct pooled_connection_policy : resolver_policy::type { + protected: + typedef typename string::type string_type; + typedef typename resolver_policy::type resolver_base; + typedef typename resolver_base::resolver_type resolver_type; + typedef function + resolver_function_type; + typedef function const&, + system::error_code const&)> body_callback_function_type; + typedef function body_generator_function_type; + + void cleanup() { host_connection_map().swap(host_connections); } + + struct connection_impl { + typedef function( + resolver_type&, basic_request const&, optional const&, + optional const&, optional const&, + optional const&, optional const&)> + get_connection_function; + + connection_impl( + resolver_type& resolver, bool follow_redirect, string_type const& host, + string_type const& port, resolver_function_type resolve, + get_connection_function get_connection, bool https, + bool always_verify_peer, int timeout, + optional const& certificate_filename = + optional(), + optional const& verify_path = optional(), + optional const& certificate_file = optional(), + optional const& private_key_file = optional(), + optional const& ciphers = optional(), + long ssl_options = 0) + : pimpl(impl::sync_connection_base:: + new_connection(resolver, resolve, https, always_verify_peer, + timeout, certificate_filename, verify_path, + certificate_file, private_key_file, ciphers, + ssl_options)), + resolver_(resolver), + connection_follow_redirect_(follow_redirect), + get_connection_(get_connection), + certificate_filename_(certificate_filename), + verify_path_(verify_path), + certificate_file_(certificate_file), + private_key_file_(private_key_file), + ciphers_(ciphers), + ssl_options_(ssl_options) { + // TODO(dberris): review parameter necessity. + (void)host; + (void)port; + } + + basic_response send_request(string_type const& method, + basic_request request_, bool get_body, + body_callback_function_type callback, + body_generator_function_type generator) { + return send_request_impl(method, request_, get_body, callback, generator); + } + + private: + basic_response send_request_impl( + string_type const& method, basic_request request_, bool get_body, + body_callback_function_type callback, + body_generator_function_type generator) { + // TODO(dberris): review parameter necessity. + (void)callback; + + boost::uint8_t count = 0; + bool retry = false; + do { + if (count >= BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT) + boost::throw_exception(std::runtime_error( + "Redirection exceeds maximum redirect count.")); + + basic_response response_; + // check if the socket is open first + if (!pimpl->is_open()) { + pimpl->init_socket(request_.host(), + lexical_cast(request_.port())); + } + response_ = basic_response(); + response_ << ::boost::network::source(request_.host()); + + pimpl->send_request_impl(method, request_, generator); + boost::asio::streambuf response_buffer; + + try { + pimpl->read_status(response_, response_buffer); + } + catch (boost::system::system_error& e) { + if (!retry && e.code() == boost::asio::error::eof) { + retry = true; + pimpl->init_socket(request_.host(), + lexical_cast(request_.port())); + continue; + } + throw; // it's a retry, and there's something wrong. + } + + pimpl->read_headers(response_, response_buffer); + + if (get_body && response_.status() != 304 && + (response_.status() != 204) && + !(response_.status() >= 100 && response_.status() <= 199)) { + pimpl->read_body(response_, response_buffer); + } + + typename headers_range >::type connection_range = + headers(response_)["Connection"]; + if (version_major == 1 && version_minor == 1 && + !boost::empty(connection_range) && + boost::begin(connection_range)->second == string_type("close")) { + pimpl->close_socket(); + } else if (version_major == 1 && version_minor == 0) { + pimpl->close_socket(); + } + + if (connection_follow_redirect_) { + boost::uint16_t status = response_.status(); + if (status >= 300 && status <= 307) { + typename headers_range >::type location_range = + headers(response_)["Location"]; + typename range_iterator< + typename headers_range >::type>::type + location_header = boost::begin(location_range); + if (location_header != boost::end(location_range)) { + request_.uri(location_header->second); + connection_ptr connection_; + connection_ = get_connection_( + resolver_, request_, certificate_filename_, verify_path_, + certificate_file_, private_key_file_, ciphers_); + ++count; + continue; + } else + boost::throw_exception(std::runtime_error( + "Location header not defined in redirect response.")); + } + } + return response_; + } while (true); + } + + shared_ptr > pimpl; + resolver_type& resolver_; + bool connection_follow_redirect_; + get_connection_function get_connection_; + optional certificate_filename_; + optional verify_path_; + optional certificate_file_; + optional private_key_file_; + optional ciphers_; + long ssl_options_; + }; + + typedef shared_ptr connection_ptr; + + typedef unordered_map host_connection_map; + host_connection_map host_connections; + bool follow_redirect_; + int timeout_; + + connection_ptr get_connection( + resolver_type& resolver, basic_request const& request_, + bool always_verify_peer, + optional const& certificate_filename = + optional(), + optional const& verify_path = optional(), + optional const& certificate_file = optional(), + optional const& private_key_file = optional(), + optional const& ciphers = optional()) { + string_type index = + (request_.host() + ':') + lexical_cast(request_.port()); + connection_ptr connection_; + typename host_connection_map::iterator it = host_connections.find(index); + if (it == host_connections.end()) { + connection_.reset(new connection_impl( + resolver, follow_redirect_, request_.host(), + lexical_cast(request_.port()), + boost::bind(&pooled_connection_policy::resolve, + this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>()), + boost::bind(&pooled_connection_policy::get_connection, + this, boost::arg<1>(), boost::arg<2>(), + always_verify_peer, boost::arg<3>(), boost::arg<4>(), + boost::arg<5>(), boost::arg<6>(), boost::arg<7>()), + boost::iequals(request_.protocol(), string_type("https")), + always_verify_peer, timeout_, certificate_filename, verify_path, + certificate_file, private_key_file, ciphers, 0)); + host_connections.insert(std::make_pair(index, connection_)); + return connection_; + } + return it->second; + } + + pooled_connection_policy(bool cache_resolved, bool follow_redirect, + int timeout) + : resolver_base(cache_resolved), + host_connections(), + follow_redirect_(follow_redirect), + timeout_(timeout) {} +}; + +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_POOLED_CONNECTION_POLICY_20091214 diff --git a/cpp-netlib/boost/network/protocol/http/policies/simple_connection.hpp b/cpp-netlib/boost/network/protocol/http/policies/simple_connection.hpp new file mode 100644 index 00000000..4e9677ab --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/policies/simple_connection.hpp @@ -0,0 +1,156 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SIMPLE_CONNECTION_20091214 +#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SIMPLE_CONNECTION_20091214 + +// Copyright 2013 Google, Inc. +// Copyright 2009 Dean Michael Berris +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct simple_connection_policy : resolver_policy::type { + protected: + typedef typename string::type string_type; + typedef typename resolver_policy::type resolver_base; + typedef typename resolver_base::resolver_type resolver_type; + typedef function + resolver_function_type; + typedef function const&, + system::error_code const&)> body_callback_function_type; + typedef function body_generator_function_type; + + struct connection_impl { + connection_impl( + resolver_type& resolver, bool follow_redirect, bool always_verify_peer, + string_type const& hostname, string_type const& port, + resolver_function_type resolve, bool https, int timeout, + optional const& certificate_filename = + optional(), + optional const& verify_path = optional(), + optional const& certificate_file = optional(), + optional const& private_key_file = optional(), + optional const& ciphers = optional(), + long ssl_options = 0) + : pimpl(), follow_redirect_(follow_redirect) { + // TODO(dberris): review parameter necessity. + (void)hostname; + (void)port; + + pimpl.reset(impl::sync_connection_base< + Tag, version_major, + version_minor>::new_connection(resolver, resolve, https, + always_verify_peer, timeout, + certificate_filename, verify_path, + certificate_file, private_key_file, + ciphers, ssl_options)); + } + + basic_response send_request(string_type const& method, + basic_request request_, bool get_body, + body_callback_function_type callback, + body_generator_function_type generator) { + // TODO(dberris): review parameter necessity. + (void)callback; + + basic_response response_; + do { + pimpl->init_socket(request_.host(), + lexical_cast(request_.port())); + pimpl->send_request_impl(method, request_, generator); + + response_ = basic_response(); + response_ << network::source(request_.host()); + + boost::asio::streambuf response_buffer; + pimpl->read_status(response_, response_buffer); + pimpl->read_headers(response_, response_buffer); + if (get_body) pimpl->read_body(response_, response_buffer); + + if (follow_redirect_) { + boost::uint16_t status = response_.status(); + if (status >= 300 && status <= 307) { + typename headers_range >::type + location_range = headers(response_)["Location"]; + typename range_iterator< + typename headers_range >::type>::type + location_header = boost::begin(location_range); + if (location_header != boost::end(location_range)) { + request_.uri(location_header->second); + } else + throw std::runtime_error( + "Location header not defined in redirect response."); + } else + break; + } else + break; + } while (true); + return response_; + } + + private: + shared_ptr > pimpl; + bool follow_redirect_; + }; + + typedef boost::shared_ptr connection_ptr; + connection_ptr get_connection( + resolver_type& resolver, basic_request const& request_, + bool always_verify_peer, + optional const& certificate_filename = + optional(), + optional const& verify_path = optional(), + optional const& certificate_file = optional(), + optional const& private_key_file = optional(), + optional const& ciphers = optional(), + long ssl_options = 0) { + connection_ptr connection_(new connection_impl( + resolver, follow_redirect_, always_verify_peer, request_.host(), + lexical_cast(request_.port()), + boost::bind(&simple_connection_policy::resolve, + this, boost::arg<1>(), boost::arg<2>(), boost::arg<3>()), + boost::iequals(request_.protocol(), string_type("https")), timeout_, + certificate_filename, verify_path, certificate_file, private_key_file, + ciphers, ssl_options)); + return connection_; + } + + void cleanup() {} + + simple_connection_policy(bool cache_resolved, bool follow_redirect, + int timeout) + : resolver_base(cache_resolved), + follow_redirect_(follow_redirect), + timeout_(timeout) {} + + // member variables + bool follow_redirect_; + int timeout_; +}; + +} // namespace http +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SIMPLE_CONNECTION_20091214 diff --git a/cpp-netlib/boost/network/protocol/http/policies/sync_resolver.hpp b/cpp-netlib/boost/network/protocol/http/policies/sync_resolver.hpp new file mode 100644 index 00000000..9f93b985 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/policies/sync_resolver.hpp @@ -0,0 +1,73 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SYNC_RESOLVER_20091214 +#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SYNC_RESOLVER_20091214 + +// Copyright Dean Michael Berris 2009. +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { +namespace policies { + +template +struct sync_resolver { + + typedef typename resolver::type resolver_type; + typedef typename resolver_type::iterator resolver_iterator; + typedef typename resolver_type::query resolver_query; + typedef std::pair + resolver_iterator_pair; + + protected: + typedef typename string::type string_type; + typedef boost::unordered_map + resolved_cache; + resolved_cache endpoint_cache_; + bool cache_resolved_; + + sync_resolver(bool cache_resolved) : cache_resolved_(cache_resolved) {} + + resolver_iterator_pair resolve(resolver_type& resolver_, + string_type const& hostname, + string_type const& port) { + if (cache_resolved_) { + typename resolved_cache::iterator cached_iterator = + endpoint_cache_.find(hostname); + if (cached_iterator == endpoint_cache_.end()) { + bool inserted = false; + boost::fusion::tie(cached_iterator, inserted) = + endpoint_cache_.insert(std::make_pair( + boost::to_lower_copy(hostname), + std::make_pair( + resolver_.resolve(resolver_query( + hostname, port, resolver_query::numeric_service)), + resolver_iterator()))); + }; + return cached_iterator->second; + }; + + return std::make_pair(resolver_.resolve(resolver_query( + hostname, port, resolver_query::numeric_service)), + resolver_iterator()); + }; +}; + +} // namespace policies + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SYNC_RESOLVER_20091214 diff --git a/cpp-netlib/boost/network/protocol/http/request.hpp b/cpp-netlib/boost/network/protocol/http/request.hpp new file mode 100644 index 00000000..8c688118 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/request.hpp @@ -0,0 +1,84 @@ + +// Copyright Dean Michael Berris 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 __NETWORK_PROTOCOL_HTTP_REQUEST_20070908_1_HPP__ +#define __NETWORK_PROTOCOL_HTTP_REQUEST_20070908_1_HPP__ + +// Implement the HTTP Request Object + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// forward declarations +namespace boost { +namespace network { +namespace http { + +template +struct basic_request; + +} // namespace http + +} // namespace network + +} // namespace boost + +#include + +namespace boost { +namespace network { +namespace http { + +template +basic_request& operator<<(basic_request& message, + Directive const& directive) { + directive(message); + return message; +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#include + +#endif // __NETWORK_PROTOCOL_HTTP_REQUEST_20070908-1_HPP__ diff --git a/cpp-netlib/boost/network/protocol/http/request_concept.hpp b/cpp-netlib/boost/network/protocol/http/request_concept.hpp new file mode 100644 index 00000000..4d843cbb --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/request_concept.hpp @@ -0,0 +1,115 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_CONCEPT_HPP_20100603 +#define BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_CONCEPT_HPP_20100603 + +// Copyright 2010 (c) Dean Michael Berris. +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct ServerRequest { + typedef typename R::string_type string_type; + typedef typename R::tag tag; + typedef typename R::headers_container_type headers_container_type; + + BOOST_CONCEPT_USAGE(ServerRequest) { + string_type source_, method_, destination_; + boost::uint8_t major_version_, minor_version_; + headers_container_type headers_; + string_type body_; + + source_ = source(request); + method_ = method(request); + destination_ = destination(request); + major_version_ = major_version(request); + minor_version_ = minor_version(request); + headers_ = headers(request); + body_ = body(request); + + source(request, source_); + method(request, method_); + destination(request, destination_); + major_version(request, major_version_); + minor_version(request, minor_version_); + headers(request, headers_); + add_header(request, string_type(), string_type()); + remove_header(request, string_type()); + clear_headers(request); + body(request, body_); + + string_type name, value; + + request << ::boost::network::source(source_) + << ::boost::network::destination(destination_) + << ::boost::network::http::method(method_) + << ::boost::network::http::major_version(major_version_) + << ::boost::network::http::minor_version(minor_version_) + << ::boost::network::header(name, value) + << ::boost::network::body(body_); + + (void)source_; + (void)method_; + (void)destination_; + (void)major_version_; + (void)minor_version_; + (void)headers_; + (void)body_; + (void)name; + (void)value; + } + + private: + R request; +}; + +template +struct ClientRequest : boost::network::Message { + typedef typename R::string_type string_type; + typedef typename R::port_type port_type; + + BOOST_CONCEPT_USAGE(ClientRequest) { + string_type tmp; + R request_(tmp); + swap(request, request_); // swappable via ADL + + string_type host_ = host(request); + port_type port_ = port(request); + string_type path_ = path(request); + string_type query_ = query(request); + string_type anchor_ = anchor(request); + string_type protocol_ = protocol(request); + + request << uri(string_type()); + + boost::network::http::uri(request, string_type()); + + (void)host_; + (void)port_; + (void)path_; + (void)query_; + (void)anchor_; + (void)protocol_; + } + + private: + R request; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_REQUEST_CONCEPT_HPP_20100603 diff --git a/cpp-netlib/boost/network/protocol/http/request_parser.hpp b/cpp-netlib/boost/network/protocol/http/request_parser.hpp new file mode 100644 index 00000000..d68f6fbf --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/request_parser.hpp @@ -0,0 +1,108 @@ +// +// request_parser.hpp +// ~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2009 Dean Michael Berris (mikhailberis at gmail dot com) +// Copyright (c) 2009 Tarro, Inc. +// +// 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) +// +// Modifications by Dean Michael Berris +// + +#ifndef HTTP_SERVER3_REQUEST_PARSER_HPP +#define HTTP_SERVER3_REQUEST_PARSER_HPP + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +namespace tag { +struct default_; +} + +/// Parser for incoming requests. +template +class basic_request_parser { + public: + /// Construct ready to parse the request method. + basic_request_parser() : state_(method_start) {} + + /// Reset to initial parser state. + void reset() { state_ = method_start; } + + /// Parse some data. The tribool return value is true when a complete + /// request + /// has been parsed, false if the data is invalid, indeterminate when + /// more + /// data is required. The InputIterator return value indicates how much + /// of the + /// input has been consumed. + template + boost::tuple parse_headers( + basic_request& req, InputIterator begin, InputIterator end) { + while (begin != end) { + boost::tribool result = consume(req, *begin++); + if (result || !result) return boost::make_tuple(result, begin); + } + boost::tribool result = boost::indeterminate; + return boost::make_tuple(result, begin); + } + + private: + /// Handle the next character of input. + boost::tribool consume(basic_request& req, char input); + + /// Check if a byte is an HTTP character. + static bool is_char(int c); + + /// Check if a byte is an HTTP control character. + static bool is_ctl(int c); + + /// Check if a byte is defined as an HTTP tspecial character. + static bool is_tspecial(int c); + + /// Check if a byte is a digit. + static bool is_digit(int c); + + /// The current state of the parser. + enum state { + method_start, + method, + uri_start, + uri, + http_version_h, + http_version_t_1, + http_version_t_2, + http_version_p, + http_version_slash, + http_version_major_start, + http_version_major, + http_version_minor_start, + http_version_minor, + expecting_newline_1, + header_line_start, + header_lws, + header_name, + space_before_header_value, + header_value, + expecting_newline_2, + expecting_newline_3 + } state_; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#include + +#endif // HTTP_SERVER3_REQUEST_PARSER_HPP diff --git a/cpp-netlib/boost/network/protocol/http/response.hpp b/cpp-netlib/boost/network/protocol/http/response.hpp new file mode 100644 index 00000000..dea1f46e --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/response.hpp @@ -0,0 +1,100 @@ +// Copyright Dean Michael Berris 2007. +// Copyright Michael Dickey 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 BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_HPP +#define BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_HPP + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct basic_response : public message_base::type { + + typedef typename string::type string_type; + + private: + typedef typename message_base::type base_type; + + public: + typedef Tag tag; + + basic_response() : base_type() {} + + basic_response(basic_response const& other) : base_type(other) {} + + basic_response& operator=(basic_response rhs) { + rhs.swap(*this); + return *this; + }; + + void swap(basic_response& other) { + base_type& base_ref(other), &this_ref(*this); + std::swap(this_ref, base_ref); + }; +}; + +template +inline void swap(basic_response& lhs, basic_response& rhs) { + lhs.swap(rhs); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#include + +namespace boost { +namespace network { +namespace http { + +template +basic_response& operator<<(basic_response& message, + Directive const& directive) { + directive(message); + return message; +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_HPP diff --git a/cpp-netlib/boost/network/protocol/http/response_concept.hpp b/cpp-netlib/boost/network/protocol/http/response_concept.hpp new file mode 100644 index 00000000..63128296 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/response_concept.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_CONCEPT_HPP_20100603 +#define BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_CONCEPT_HPP_20100603 + +// Copyright 2010 (c) Dean Michael Berris. +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct Response : boost::network::Message { + typedef typename R::string_type string_type; + + BOOST_CONCEPT_USAGE(Response) { + R response_; + swap(response, response_); // swappable via ADL + + typedef typename traits::version::type version_type; + typedef typename traits::status::type status_type; + typedef typename traits::status_message::type status_message_type; + + response << version(version_type()) // version directive + << status(status_type()) // status directive + << status_message( + status_message_type()) // status_message directive + ; + + version(response, version_type()); + status(response, status_type()); + status_message(response, status_message_type()); + + string_type version_ = version(response); + boost::uint16_t status_ = status(response); + string_type status_message_ = status_message(response); + + (void)version_; + (void)status_; + (void)status_message_; + } + + private: + R response; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_RESPONSE_CONCEPT_HPP_20100603 diff --git a/cpp-netlib/boost/network/protocol/http/server.hpp b/cpp-netlib/boost/network/protocol/http/server.hpp new file mode 100644 index 00000000..d7c127ee --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server.hpp @@ -0,0 +1,62 @@ +// Copyright 2009 (c) Tarro, Inc. +// Copyright 2009 (c) Dean Michael Berris +// Copyright 2010 (c) Glyn Matthews +// Copyright 2003-2008 (c) Chris Kholhoff +// 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 BOOST_NETWORK_HTTP_SERVER_HPP_ +#define BOOST_NETWORK_HTTP_SERVER_HPP_ + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct server_base { + typedef unsupported_tag type; +}; + +template +struct server_base >::type> { + typedef async_server_base type; +}; + +template +struct server_base >::type> { + typedef sync_server_base type; +}; + +template +struct basic_server : server_base::type {}; + +template +struct server : server_base::type { + typedef typename server_base::type server_base; + typedef server_options options; + + explicit server(options const &options) : server_base(options) {} +}; + +template +struct async_server : server_base::type { + typedef typename server_base::type + server_base; + typedef server_options options; + + explicit async_server(options const &options) : server_base(options) {} +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_HTTP_SERVER_HPP_ diff --git a/cpp-netlib/boost/network/protocol/http/server/async_connection.hpp b/cpp-netlib/boost/network/protocol/http/server/async_connection.hpp new file mode 100644 index 00000000..0f84eea9 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/async_connection.hpp @@ -0,0 +1,674 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SERVER_CONNECTION_HPP_20101027 +#define BOOST_NETWORK_PROTOCOL_HTTP_SERVER_CONNECTION_HPP_20101027 + +// Copyright 2010 Dean Michael Berris. +// Copyright 2014 Jelle Van den Driessche. +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef BOOST_NETWORK_NO_LIB +#include +#endif + +#ifndef BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE +/** Here we define a page's worth of header connection buffer data. + * This can be tuned to reduce the memory cost of connections, but this + * default size is set to be friendly to typical service applications. + * This is the maximum size though and Boost.Asio's internal representation + * of a streambuf would make appropriate decisions on how big a buffer + * is to begin with. + * + * This kinda assumes that a page is by default 4096. Since we're using + * the default allocator with the static buffers, it's not guaranteed that + * the static buffers will be page-aligned when they are allocated. + */ +#define BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE 4096 +#endif /* BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE */ + +namespace boost { +namespace network { +namespace http { + +#ifndef BOOST_NETWORK_NO_LIB +extern void parse_version(std::string const& partial_parsed, + fusion::tuple& version_pair); +extern void parse_headers(std::string const& input, + std::vector& container); +#endif + +template +struct async_connection + : boost::enable_shared_from_this > { + + enum status_t { + ok = 200, + created = 201, + accepted = 202, + no_content = 204, + partial_content = 206, + multiple_choices = 300, + moved_permanently = 301, + moved_temporarily = 302, + not_modified = 304, + bad_request = 400, + unauthorized = 401, + forbidden = 403, + not_found = 404, + not_supported = 405, + not_acceptable = 406, + request_timeout = 408, + precondition_failed = 412, + unsatisfiable_range = 416, + internal_server_error = 500, + not_implemented = 501, + bad_gateway = 502, + service_unavailable = 503, + space_unavailable = 507 + }; + + typedef typename string::type string_type; + typedef basic_request request; + typedef shared_ptr connection_ptr; + + private: + static char const* status_message(status_t status) { + static char const ok_[] = "OK", created_[] = "Created", + accepted_[] = "Accepted", no_content_[] = "No Content", + multiple_choices_[] = "Multiple Choices", + moved_permanently_[] = "Moved Permanently", + moved_temporarily_[] = "Moved Temporarily", + not_modified_[] = "Not Modified", + bad_request_[] = "Bad Request", + unauthorized_[] = "Unauthorized", + forbidden_[] = "Fobidden", not_found_[] = "Not Found", + not_supported_[] = "Not Supported", + not_acceptable_[] = "Not Acceptable", + internal_server_error_[] = "Internal Server Error", + not_implemented_[] = "Not Implemented", + bad_gateway_[] = "Bad Gateway", + service_unavailable_[] = "Service Unavailable", + unknown_[] = "Unknown", + partial_content_[] = "Partial Content", + request_timeout_[] = "Request Timeout", + precondition_failed_[] = "Precondition Failed", + unsatisfiable_range_[] = + "Requested Range Not Satisfiable", + space_unavailable_[] = + "Insufficient Space to Store Resource"; + switch (status) { + case ok: + return ok_; + case created: + return created_; + case accepted: + return accepted_; + case no_content: + return no_content_; + case multiple_choices: + return multiple_choices_; + case moved_permanently: + return moved_permanently_; + case moved_temporarily: + return moved_temporarily_; + case not_modified: + return not_modified_; + case bad_request: + return bad_request_; + case unauthorized: + return unauthorized_; + case forbidden: + return forbidden_; + case not_found: + return not_found_; + case not_supported: + return not_supported_; + case not_acceptable: + return not_acceptable_; + case internal_server_error: + return internal_server_error_; + case not_implemented: + return not_implemented_; + case bad_gateway: + return bad_gateway_; + case service_unavailable: + return service_unavailable_; + case partial_content: + return partial_content_; + case request_timeout: + return request_timeout_; + case precondition_failed: + return precondition_failed_; + case unsatisfiable_range: + return unsatisfiable_range_; + case space_unavailable: + return space_unavailable_; + default: + return unknown_; + } + } + + public: + async_connection(asio::io_service& io_service, Handler& handler, + utils::thread_pool& thread_pool, + boost::shared_ptr ctx = + boost::shared_ptr()) + : strand(io_service), + handler(handler), + thread_pool_(thread_pool), + headers_buffer( + BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE), +#ifdef BOOST_NETWORK_ENABLE_HTTPS + socket_(io_service, ctx), +#else + socket_(io_service), +#endif + handshake_done(false), + headers_already_sent(false), + headers_in_progress(false) { + new_start = read_buffer_.begin(); + } + + ~async_connection() throw() { + boost::system::error_code ignored; + socket_.shutdown(asio::ip::tcp::socket::shutdown_receive, ignored); + } + + /** Function: template set_headers(Range headers) + * Precondition: headers have not been sent yet + * Postcondition: headers have been linearized to a buffer, + * and assumed to have been sent already when the + *function exits + * Throws: std::logic_error in case the headers have already been sent. + * + * A call to set_headers takes a Range where each element models the + * Header concept. This Range will be linearized onto a buffer, which + *is + * then sent as soon as the first call to `write` or `flush` commences. + */ + template + void set_headers(Range headers) { + lock_guard lock(headers_mutex); + if (headers_in_progress || headers_already_sent) + boost::throw_exception( + std::logic_error("Headers have already been sent.")); + + if (error_encountered) + boost::throw_exception(boost::system::system_error(*error_encountered)); + + typedef constants consts; + { + std::ostream stream(&headers_buffer); + stream << consts::http_slash() << 1 << consts::dot() << 1 + << consts::space() << status << consts::space() + << status_message(status) << consts::crlf(); + if (!boost::empty(headers)) { + typedef typename string::type string_type; + boost::transform(headers, std::ostream_iterator(stream), + linearize_header()); + } else { + stream << consts::crlf(); + } + stream << consts::crlf(); + } + + write_headers_only( + boost::bind(&async_connection::do_nothing, + async_connection::shared_from_this())); + } + + void set_status(status_t new_status) { + lock_guard lock(headers_mutex); + if (headers_already_sent) + boost::throw_exception(std::logic_error( + "Headers have already been sent, cannot reset status.")); + if (error_encountered) + boost::throw_exception(boost::system::system_error(*error_encountered)); + + status = new_status; + } + + template + void write(Range const& range) { + lock_guard lock(headers_mutex); + if (error_encountered) + boost::throw_exception(boost::system::system_error(*error_encountered)); + + boost::function f = boost::bind( + &async_connection::default_error, + async_connection::shared_from_this(), boost::arg<1>()); + + write_impl(boost::make_iterator_range(range), f); + } + + template + typename disable_if< + is_base_of, void>::type + write(Range const& range, Callback const& callback) { + lock_guard lock(headers_mutex); + if (error_encountered) + boost::throw_exception(boost::system::system_error(*error_encountered)); + write_impl(boost::make_iterator_range(range), callback); + } + + template + typename enable_if< + is_base_of, + void>::type + write(ConstBufferSeq const& seq, Callback const& callback) { + write_vec_impl(seq, callback, shared_array_list(), shared_buffers()); + } + + private: + typedef boost::array + buffer_type; + + public: + typedef iterator_range input_range; + typedef boost::function< + void(input_range, boost::system::error_code, std::size_t, connection_ptr)> + read_callback_function; + + void read(read_callback_function callback) { + if (error_encountered) + boost::throw_exception(boost::system::system_error(*error_encountered)); + if (new_start != read_buffer_.begin()) { + input_range input = + boost::make_iterator_range(new_start, read_buffer_.end()); + buffer_type::iterator start_tmp = new_start; + new_start = read_buffer_.begin(); + thread_pool().post( + boost::bind(callback, input, boost::system::error_code(), + std::distance(start_tmp, data_end), + async_connection::shared_from_this())); + return; + } + + socket().async_read_some( + asio::buffer(read_buffer_), + strand.wrap(boost::bind( + &async_connection::wrap_read_handler, + async_connection::shared_from_this(), callback, + asio::placeholders::error, asio::placeholders::bytes_transferred))); + } + + boost::network::stream_handler& socket() { return socket_; } + utils::thread_pool& thread_pool() { return thread_pool_; } + bool has_error() { return (!!error_encountered); } + optional error() { return error_encountered; } + + private: + void wrap_read_handler(read_callback_function callback, + boost::system::error_code const& ec, + std::size_t bytes_transferred) { + if (ec) error_encountered = in_place(ec); + buffer_type::const_iterator data_start = read_buffer_.begin(), + data_end = read_buffer_.begin(); + std::advance(data_end, bytes_transferred); + thread_pool().post(boost::bind( + callback, boost::make_iterator_range(data_start, data_end), ec, + bytes_transferred, async_connection::shared_from_this())); + } + + void default_error(boost::system::error_code const& ec) { + error_encountered = in_place(ec); + } + + typedef boost::array + array; + typedef std::list > array_list; + typedef boost::shared_ptr shared_array_list; + typedef boost::shared_ptr > shared_buffers; + typedef request_parser request_parser_type; + typedef boost::lock_guard lock_guard; + typedef std::list > pending_actions_list; + + asio::io_service::strand strand; + Handler& handler; + utils::thread_pool& thread_pool_; + asio::streambuf headers_buffer; + boost::network::stream_handler socket_; + bool handshake_done; + volatile bool headers_already_sent, headers_in_progress; + + boost::recursive_mutex headers_mutex; + buffer_type read_buffer_; + status_t status; + request_parser_type parser; + request request_; + buffer_type::iterator new_start, data_end; + string_type partial_parsed; + optional error_encountered; + pending_actions_list pending_actions; + + template + friend struct async_server_base; + + enum state_t { + method, + uri, + version, + headers + }; + + void start() { + typename ostringstream::type ip_stream; + ip_stream << socket_.remote_endpoint().address().to_string() << ':' + << socket_.remote_endpoint().port(); + request_.source = ip_stream.str(); + read_more(method); + } + + void read_more(state_t state) { +#ifdef BOOST_NETWORK_ENABLE_HTTPS + if (socket_.is_ssl_enabled() && !handshake_done) { + socket_.async_handshake( + boost::asio::ssl::stream_base::server, + boost::bind(&async_connection::handle_handshake, + async_connection::shared_from_this(), + boost::asio::placeholders::error, state)); + } else { +#endif + socket_.async_read_some( + asio::buffer(read_buffer_), + strand.wrap( + boost::bind(&async_connection::handle_read_data, + async_connection::shared_from_this(), + state, boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); +#ifdef BOOST_NETWORK_ENABLE_HTTPS + } +#endif + } + + void handle_read_data(state_t state, boost::system::error_code const& ec, + std::size_t bytes_transferred) { + if (!ec) { + logic::tribool parsed_ok; + iterator_range result_range, input_range; + data_end = read_buffer_.begin(); + std::advance(data_end, bytes_transferred); + switch (state) { + case method: + input_range = boost::make_iterator_range(new_start, data_end); + fusion::tie(parsed_ok, result_range) = + parser.parse_until(request_parser_type::method_done, input_range); + if (!parsed_ok) { + client_error(); + break; + } else if (parsed_ok == true) { + swap(partial_parsed, request_.method); + request_.method.append(boost::begin(result_range), + boost::end(result_range)); + trim(request_.method); + new_start = boost::end(result_range); + } else { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + new_start = read_buffer_.begin(); + read_more(method); + break; + } + case uri: + input_range = boost::make_iterator_range(new_start, data_end); + fusion::tie(parsed_ok, result_range) = + parser.parse_until(request_parser_type::uri_done, input_range); + if (!parsed_ok) { + client_error(); + break; + } else if (parsed_ok == true) { + swap(partial_parsed, request_.destination); + request_.destination.append(boost::begin(result_range), + boost::end(result_range)); + trim(request_.destination); + new_start = boost::end(result_range); + } else { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + new_start = read_buffer_.begin(); + read_more(uri); + break; + } + case version: + input_range = boost::make_iterator_range(new_start, data_end); + fusion::tie(parsed_ok, result_range) = parser.parse_until( + request_parser_type::version_done, input_range); + if (!parsed_ok) { + client_error(); + break; + } else if (parsed_ok == true) { + fusion::tuple version_pair; + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + parse_version(partial_parsed, version_pair); + request_.http_version_major = fusion::get<0>(version_pair); + request_.http_version_minor = fusion::get<1>(version_pair); + new_start = boost::end(result_range); + partial_parsed.clear(); + } else { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + new_start = read_buffer_.begin(); + read_more(version); + break; + } + case headers: + input_range = boost::make_iterator_range(new_start, data_end); + fusion::tie(parsed_ok, result_range) = parser.parse_until( + request_parser_type::headers_done, input_range); + if (!parsed_ok) { + client_error(); + break; + } else if (parsed_ok == true) { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + try { + parse_headers(partial_parsed, request_.headers); + } catch (...) { + client_error(); + break; + } + new_start = boost::end(result_range); + thread_pool().post(boost::bind( + &Handler::operator(), &handler, cref(request_), + async_connection::shared_from_this())); + return; + } else { + partial_parsed.append(boost::begin(result_range), + boost::end(result_range)); + new_start = read_buffer_.begin(); + read_more(headers); + break; + } + default: + BOOST_ASSERT(false && + "This is a bug, report to the cpp-netlib devel " + "mailing list!"); + std::abort(); + } + } else { + error_encountered = in_place(ec); + } + } + + void client_error() { + static char const* bad_request = + "HTTP/1.0 400 Bad Request\r\nConnection: close\r\nContent-Type: " + "text/plain\r\nContent-Length: 12\r\n\r\nBad Request."; + + asio::async_write( + socket(), asio::buffer(bad_request, strlen(bad_request)), + strand.wrap(boost::bind( + &async_connection::client_error_sent, + async_connection::shared_from_this(), + asio::placeholders::error, asio::placeholders::bytes_transferred))); + } + + void client_error_sent(boost::system::error_code const& ec, + std::size_t bytes_transferred) { + if (!ec) { + boost::system::error_code ignored; + socket().shutdown(asio::ip::tcp::socket::shutdown_both, ignored); + socket().close(ignored); + } else { + error_encountered = in_place(ec); + } + } + + void do_nothing() {} + + void write_headers_only(boost::function callback) { + if (headers_in_progress) return; + headers_in_progress = true; + asio::async_write( + socket(), headers_buffer, + strand.wrap(boost::bind( + &async_connection::handle_write_headers, + async_connection::shared_from_this(), callback, + asio::placeholders::error, asio::placeholders::bytes_transferred))); + } + + void handle_write_headers(boost::function callback, + boost::system::error_code const& ec, + std::size_t bytes_transferred) { + lock_guard lock(headers_mutex); + if (!ec) { + headers_buffer.consume(headers_buffer.size()); + headers_already_sent = true; + thread_pool().post(callback); + pending_actions_list::iterator start = pending_actions.begin(), + end = pending_actions.end(); + while (start != end) { + thread_pool().post(*start++); + } + pending_actions_list().swap(pending_actions); + } else { + error_encountered = in_place(ec); + } + } + + void handle_write( + boost::function callback, + shared_array_list temporaries, shared_buffers buffers, + boost::system::error_code const& ec, std::size_t bytes_transferred) { + // we want to forget the temporaries and buffers + thread_pool().post(boost::bind(callback, ec)); + } + + template + void write_impl(Range range, + boost::function callback) { + // linearize the whole range into a vector + // of fixed-sized buffers, then schedule an asynchronous + // write of these buffers -- make sure they are live + // by making these linearized buffers shared and made + // part of the completion handler. + // + // once the range has been linearized and sent, schedule + // a wrapper to be called in the io_service's thread, that + // will re-schedule the given callback into the thread pool + // referred to here so that the io_service's thread can concentrate + // on doing I/O. + // + + static std::size_t const connection_buffer_size = + BOOST_NETWORK_HTTP_SERVER_CONNECTION_BUFFER_SIZE; + shared_array_list temporaries = boost::make_shared(); + shared_buffers buffers = + boost::make_shared >(0); + + std::size_t range_size = boost::distance(range); + buffers->reserve((range_size / connection_buffer_size) + + ((range_size % connection_buffer_size) ? 1 : 0)); + std::size_t slice_size = std::min(range_size, connection_buffer_size); + typename boost::range_iterator::type start = boost::begin(range), + end = boost::end(range); + while (slice_size != 0) { + using boost::adaptors::sliced; + shared_ptr new_array = make_shared(); + boost::copy(range | sliced(0, slice_size), new_array->begin()); + temporaries->push_back(new_array); + buffers->push_back(asio::buffer(new_array->data(), slice_size)); + std::advance(start, slice_size); + range = boost::make_iterator_range(start, end); + range_size = boost::distance(range); + slice_size = std::min(range_size, connection_buffer_size); + } + + if (!buffers->empty()) { + write_vec_impl(*buffers, callback, temporaries, buffers); + } + } + + template + void write_vec_impl(ConstBufferSeq const& seq, Callback const& callback, + shared_array_list temporaries, shared_buffers buffers) { + lock_guard lock(headers_mutex); + if (error_encountered) + boost::throw_exception(boost::system::system_error(*error_encountered)); + + boost::function callback_function = + callback; + + boost::function continuation = boost::bind( + &async_connection::template write_vec_impl< + ConstBufferSeq, boost::function >, + async_connection::shared_from_this(), seq, + callback_function, temporaries, buffers); + + if (!headers_already_sent && !headers_in_progress) { + write_headers_only(continuation); + return; + } else if (headers_in_progress && !headers_already_sent) { + pending_actions.push_back(continuation); + return; + } + + asio::async_write( + socket_, seq, + boost::bind(&async_connection::handle_write, + async_connection::shared_from_this(), + callback_function, temporaries, buffers, + asio::placeholders::error, + asio::placeholders::bytes_transferred)); + } + void handle_handshake(const boost::system::error_code& ec, state_t state) { + if (!ec) { + handshake_done = true; + read_more(state); + } else { + error_encountered = in_place(ec); + } + } +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SERVER_CONNECTION_HPP_20101027 */ diff --git a/cpp-netlib/boost/network/protocol/http/server/async_server.hpp b/cpp-netlib/boost/network/protocol/http/server/async_server.hpp new file mode 100644 index 00000000..b3cdde50 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/async_server.hpp @@ -0,0 +1,188 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SERVER_ASYNC_SERVER_HPP_20101025 +#define BOOST_NETWORK_PROTOCOL_HTTP_SERVER_ASYNC_SERVER_HPP_20101025 + +// Copyright 2010 Dean Michael Berris. +// Copyright 2014 Jelle Van den Driessche. +// 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) + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct async_server_base : server_storage_base, socket_options_base { + typedef basic_request request; + typedef basic_response response; + typedef typename string::type string_type; + typedef typename boost::network::http::response_header::type + response_header; + typedef async_connection connection; + typedef shared_ptr connection_ptr; + typedef boost::unique_lock scoped_mutex_lock; + + explicit async_server_base(server_options const &options) + : server_storage_base(options), + socket_options_base(options), + handler(options.handler()), + address_(options.address()), + port_(options.port()), + thread_pool(options.thread_pool() + ? options.thread_pool() + : boost::make_shared()), + acceptor(server_storage_base::service_), + stopping(false), + new_connection(), + listening_mutex_(), + stopping_mutex_(), + listening(false), + ctx_(options.context()) {} + + void run() { + listen(); + service_.run(); + }; + + void stop() { + // stop accepting new requests and let all the existing + // handlers finish. + scoped_mutex_lock listening_lock(listening_mutex_); + if (listening) { // we dont bother stopping if we arent currently + // listening + scoped_mutex_lock stopping_lock(stopping_mutex_); + stopping = true; + system::error_code ignored; + acceptor.close(ignored); + listening = false; + service_.post(boost::bind(&async_server_base::handle_stop, this)); + } + } + + void listen() { + scoped_mutex_lock listening_lock(listening_mutex_); + BOOST_NETWORK_MESSAGE("Listening on " << address_ << ':' << port_); + if (!listening) + start_listening(); // we only initialize our acceptor/sockets if we + // arent already listening + if (!listening) { + BOOST_NETWORK_MESSAGE("Error listening on " << address_ << ':' << port_); + boost::throw_exception( + std::runtime_error("Error listening on provided port.")); + } + } + + private: + Handler &handler; + string_type address_, port_; + boost::shared_ptr thread_pool; + asio::ip::tcp::acceptor acceptor; + bool stopping; + connection_ptr new_connection; + boost::mutex listening_mutex_; + boost::mutex stopping_mutex_; + bool listening; + boost::shared_ptr ctx_; + + void handle_stop() { + scoped_mutex_lock stopping_lock(stopping_mutex_); + if (stopping) + service_.stop(); // a user may have started listening again before + // the stop command is reached + } + + void handle_accept(boost::system::error_code const &ec) { + { + scoped_mutex_lock stopping_lock(stopping_mutex_); + if (stopping) + return; // we dont want to add another handler instance, and we + // dont want to know about errors for a socket we dont + // need anymore + } + + if (ec) { + BOOST_NETWORK_MESSAGE("Error accepting connection, reason: " << ec); + } + +#ifdef BOOST_NETWORK_ENABLE_HTTPS + socket_options_base::socket_options(new_connection->socket().next_layer()); +#else + socket_options_base::socket_options(new_connection->socket()); +#endif + + new_connection->start(); + new_connection.reset(new connection(service_, handler, *thread_pool, ctx_)); + acceptor.async_accept( +#ifdef BOOST_NETWORK_ENABLE_HTTPS + new_connection->socket().next_layer(), +#else + new_connection->socket(), +#endif + boost::bind(&async_server_base::handle_accept, this, + boost::asio::placeholders::error)); + } + + void start_listening() { + using boost::asio::ip::tcp; + system::error_code error; + service_.reset(); // this allows repeated cycles of run -> stop -> + // run + tcp::resolver resolver(service_); + tcp::resolver::query query(address_, port_); + tcp::resolver::iterator endpoint_iterator = resolver.resolve(query, error); + if (error) { + BOOST_NETWORK_MESSAGE("Error resolving '" << address_ << ':' << port_); + return; + } + tcp::endpoint endpoint = *endpoint_iterator; + acceptor.open(endpoint.protocol(), error); + if (error) { + BOOST_NETWORK_MESSAGE("Error opening socket: " << address_ << ":" + << port_); + return; + } + socket_options_base::acceptor_options(acceptor); + acceptor.bind(endpoint, error); + if (error) { + BOOST_NETWORK_MESSAGE("Error binding socket: " << address_ << ":" + << port_); + return; + } + acceptor.listen(asio::socket_base::max_connections, error); + if (error) { + BOOST_NETWORK_MESSAGE("Error listening on socket: '" + << error << "' on " << address_ << ":" << port_); + return; + } + new_connection.reset(new connection(service_, handler, *thread_pool, ctx_)); + acceptor.async_accept( +#ifdef BOOST_NETWORK_ENABLE_HTTPS + new_connection->socket().next_layer(), +#else + new_connection->socket(), +#endif + boost::bind(&async_server_base::handle_accept, this, + boost::asio::placeholders::error)); + listening = true; + scoped_mutex_lock stopping_lock(stopping_mutex_); + stopping = false; // if we were in the process of stopping, we revoke + // that command and continue listening + BOOST_NETWORK_MESSAGE("Now listening on socket: '" << address_ << ":" + << port_ << "'"); + } +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SERVER_ASYNC_SERVER_HPP_20101025 */ diff --git a/cpp-netlib/boost/network/protocol/http/server/impl/parsers.ipp b/cpp-netlib/boost/network/protocol/http/server/impl/parsers.ipp new file mode 100644 index 00000000..4d7fb1a9 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/impl/parsers.ipp @@ -0,0 +1,74 @@ +#ifndef SERVER_REQUEST_PARSERS_IMPL_UW3PM6V6 +#define SERVER_REQUEST_PARSERS_IMPL_UW3PM6V6 + +#define BOOST_SPIRIT_UNICODE +#include + +// Copyright 2013 Google, Inc. +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include + +#ifdef BOOST_NETWORK_NO_LIB +#ifndef BOOST_NETWORK_INLINE +#define BOOST_NETWORK_INLINE inline +#endif +#else +#define BOOST_NETWORK_INLINE +#endif +#include + +namespace boost { +namespace spirit { +namespace traits { + +typedef std::basic_string u32_string; + +template <> // +struct assign_to_container_from_value { + static void call(u32_string const& val, std::string& attr) { + u32_to_u8_iterator begin = val.begin(), + end = val.end(); + for (; begin != end; ++begin) attr += *begin; + } +}; + +} // namespace traits +} // namespace spirit +} // namespace boost + +namespace boost { +namespace network { +namespace http { + +BOOST_NETWORK_INLINE void parse_version( + std::string const& partial_parsed, + fusion::tuple& version_pair) { + using namespace boost::spirit::qi; + parse(partial_parsed.begin(), partial_parsed.end(), + (lit("HTTP/") >> ushort_ >> '.' >> ushort_), version_pair); +} + +BOOST_NETWORK_INLINE void parse_headers( + std::string const& input, std::vector& container) { + using namespace boost::spirit::qi; + u8_to_u32_iterator begin = input.begin(), + end = input.end(); + typedef as as_u32_string; + parse(begin, end, + *(+((alnum | punct) - ':') >> lit(": ") >> + as_u32_string()[+((alnum | space | punct) - '\r' - '\n')] >> + lit("\r\n")) >> + lit("\r\n"), + container); +} + +} // namespace http +} // namespace network +} // namespace boost + +#endif /* SERVER_REQUEST_PARSERS_IMPL_UW3PM6V6 */ diff --git a/cpp-netlib/boost/network/protocol/http/server/options.hpp b/cpp-netlib/boost/network/protocol/http/server/options.hpp new file mode 100644 index 00000000..c64532e4 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/options.hpp @@ -0,0 +1,210 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SERVER_OPTIONS_20130128 +#define BOOST_NETWORK_PROTOCOL_HTTP_SERVER_OPTIONS_20130128 + +// Copyright 2013 Google, Inc. +// Copyright 2013 Dean Michael Berris +// Copyright 2014 Jelle Van den Driessche +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct server_options { + typedef typename string::type string_type; + + explicit server_options(Handler &handler) + : io_service_(), + handler_(handler), + address_("localhost"), + port_("80"), + reuse_address_(false), + report_aborted_(false), + non_blocking_io_(true), + linger_(true), + linger_timeout_(0), + receive_buffer_size_(), + send_buffer_size_(), + receive_low_watermark_(), + send_low_watermark_(), + thread_pool_(), + context_() {} + + server_options(const server_options &other) + : io_service_(other.io_service()), + handler_(other.handler_), + address_(other.address_), + port_(other.port_), + reuse_address_(other.reuse_address_), + report_aborted_(other.report_aborted_), + non_blocking_io_(other.non_blocking_io_), + linger_(other.linger_), + linger_timeout_(0), + receive_buffer_size_(other.receive_buffer_size_), + send_buffer_size_(other.send_buffer_size_), + receive_low_watermark_(other.receive_low_watermark_), + send_low_watermark_(other.send_low_watermark_), + thread_pool_(other.thread_pool_), + context_(other.context_) {} + + server_options &operator=(server_options other) { + other.swap(*this); + return *this; + } + + void swap(server_options &other) { + using std::swap; + swap(io_service_, other.io_service_); + swap(address_, other.address_); + swap(port_, other.port_); + swap(reuse_address_, other.reuse_address_); + swap(report_aborted_, other.report_aborted_); + swap(non_blocking_io_, other.non_blocking_io_); + swap(linger_, other.linger_); + swap(linger_timeout_, other.linger_timeout_); + swap(receive_buffer_size_, other.receive_buffer_size_); + swap(send_buffer_size_, other.send_buffer_size_); + swap(receive_low_watermark_, other.receive_low_watermark_); + swap(send_low_watermark_, other.send_low_watermark_); + swap(thread_pool_, other.thread_pool_); + swap(context_, other.context_); + } + + server_options &context(boost::shared_ptr v) { + context_ = v; + return *this; + } + server_options &io_service(boost::shared_ptr v) { + io_service_ = v; + return *this; + } + server_options &address(string_type const &v) { + address_ = v; + return *this; + } + server_options &port(string_type const &v) { + port_ = v; + return *this; + } + server_options &reuse_address(bool v) { + reuse_address_ = v; + return *this; + } + server_options &report_aborted(bool v) { + report_aborted_ = v; + return *this; + } + server_options &non_blocking_io(bool v) { + non_blocking_io_ = v; + return *this; + } + server_options &linger(bool v) { + linger_ = v; + return *this; + } + server_options &linger_timeout(size_t v) { + linger_timeout_ = v; + return *this; + } + server_options &receive_buffer_size( + boost::asio::socket_base::receive_buffer_size v) { + receive_buffer_size_ = v; + return *this; + } + server_options &send_buffer_size( + boost::asio::socket_base::send_buffer_size v) { + send_buffer_size_ = v; + return *this; + } + server_options &receive_low_watermark( + boost::asio::socket_base::receive_low_watermark v) { + receive_low_watermark_ = v; + return *this; + } + server_options &send_low_watermark( + boost::asio::socket_base::send_low_watermark v) { + send_low_watermark_ = v; + return *this; + } + server_options &thread_pool(boost::shared_ptr v) { + thread_pool_ = v; + return *this; + } + + boost::shared_ptr io_service() const { + return io_service_; + } + string_type address() const { return address_; } + string_type port() const { return port_; } + Handler &handler() const { return handler_; } + bool reuse_address() const { return reuse_address_; } + bool report_aborted() const { return report_aborted_; } + bool non_blocking_io() const { return non_blocking_io_; } + bool linger() const { return linger_; } + size_t linger_timeout() const { return linger_timeout_; } + boost::optional + receive_buffer_size() const { + return receive_buffer_size_; + } + boost::optional send_buffer_size() + const { + return send_buffer_size_; + } + boost::optional + receive_low_watermark() const { + return receive_low_watermark_; + } + boost::optional + send_low_watermark() const { + return send_low_watermark_; + } + boost::shared_ptr thread_pool() const { + return thread_pool_; + } + boost::shared_ptr context() const { + return context_; + } + + private: + boost::shared_ptr io_service_; + Handler &handler_; + string_type address_; + string_type port_; + bool reuse_address_; + bool report_aborted_; + bool non_blocking_io_; + bool linger_; + size_t linger_timeout_; + boost::optional + receive_buffer_size_; + boost::optional send_buffer_size_; + boost::optional + receive_low_watermark_; + boost::optional + send_low_watermark_; + boost::shared_ptr thread_pool_; + boost::shared_ptr context_; +}; + +template +inline void swap(server_options &a, + server_options &b) { + a.swap(b); +} + +} /* http */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SERVER_OPTIONS_20130128 */ diff --git a/cpp-netlib/boost/network/protocol/http/server/request.hpp b/cpp-netlib/boost/network/protocol/http/server/request.hpp new file mode 100644 index 00000000..f559ebf2 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/request.hpp @@ -0,0 +1,51 @@ +// +// request.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2009 Dean Michael Berris (mikhailberis@gmail.com) +// Copyright (c) 2009 Tarro, Inc. +// +// 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 BOOST_NETWORK_HTTP_REQUEST_HPP +#define BOOST_NETWORK_HTTP_REQUEST_HPP + +#include +#include +#include +#include "header.hpp" + +namespace boost { +namespace network { +namespace http { + +/// A request received from a client. +struct request { + std::string method; + std::string uri; + int http_version_major; + int http_version_minor; + std::vector
headers; + std::string body; +}; + +inline void swap(request& l, request& r) { + using std::swap; + swap(l.method, r.method); + swap(l.uri, r.uri); + swap(l.http_version_major, r.http_version_major); + swap(l.http_version_minor, r.http_version_minor); + swap(l.headers, r.headers); + swap(l.body, r.body); +} + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_HTTP_REQUEST_HPP diff --git a/cpp-netlib/boost/network/protocol/http/server/request_parser.hpp b/cpp-netlib/boost/network/protocol/http/server/request_parser.hpp new file mode 100644 index 00000000..86587d95 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/request_parser.hpp @@ -0,0 +1,229 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SERVER_REQUEST_PARSER_HPP_20101005 +#define BOOST_NETWORK_PROTOCOL_HTTP_SERVER_REQUEST_PARSER_HPP_20101005 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct request_parser { + + enum state_t { + method_start, + method_char, + method_done, + uri_char, + uri_done, + version_h, + version_t1, + version_t2, + version_p, + version_slash, + version_d1, + version_dot, + version_d2, + version_cr, + version_done, + header_name, + header_colon, + header_value, + header_cr, + header_line_done, + headers_cr, + headers_done + }; + + explicit request_parser(state_t start_state = method_start) + : internal_state(start_state) {} + + void reset(state_t start_state = method_start) { + internal_state = method_start; + } + + state_t state() const { return internal_state; } + + template + fusion::tuple > + parse_until(state_t stop_state, Range& range) { + logic::tribool parsed_ok = logic::indeterminate; + typedef typename range_iterator::type iterator; + iterator start = boost::begin(range), end = boost::end(range), + current_iterator = start; + iterator_range local_range = + boost::make_iterator_range(start, end); + while (!boost::empty(local_range) && stop_state != internal_state && + indeterminate(parsed_ok)) { + current_iterator = boost::begin(local_range); + switch (internal_state) { + case method_start: + if (algorithm::is_upper()(*current_iterator)) + internal_state = method_char; + else + parsed_ok = false; + break; + case method_char: + if (algorithm::is_upper()(*current_iterator)) + break; + else if (algorithm::is_space()(*current_iterator)) + internal_state = method_done; + else + parsed_ok = false; + break; + case method_done: + if (algorithm::is_cntrl()(*current_iterator)) + parsed_ok = false; + else if (algorithm::is_space()(*current_iterator)) + parsed_ok = false; + else + internal_state = uri_char; + break; + case uri_char: + if (algorithm::is_cntrl()(*current_iterator)) + parsed_ok = false; + else if (algorithm::is_space()(*current_iterator)) + internal_state = uri_done; + break; + case uri_done: + if (*current_iterator == 'H') + internal_state = version_h; + else + parsed_ok = false; + break; + case version_h: + if (*current_iterator == 'T') + internal_state = version_t1; + else + parsed_ok = false; + break; + case version_t1: + if (*current_iterator == 'T') + internal_state = version_t2; + else + parsed_ok = false; + break; + case version_t2: + if (*current_iterator == 'P') + internal_state = version_p; + else + parsed_ok = false; + break; + case version_p: + if (*current_iterator == '/') + internal_state = version_slash; + else + parsed_ok = false; + break; + case version_slash: + if (algorithm::is_digit()(*current_iterator)) + internal_state = version_d1; + else + parsed_ok = false; + break; + case version_d1: + if (*current_iterator == '.') + internal_state = version_dot; + else + parsed_ok = false; + break; + case version_dot: + if (algorithm::is_digit()(*current_iterator)) + internal_state = version_d2; + else + parsed_ok = false; + break; + case version_d2: + if (*current_iterator == '\r') + internal_state = version_cr; + else + parsed_ok = false; + break; + case version_cr: + if (*current_iterator == '\n') + internal_state = version_done; + else + parsed_ok = false; + break; + case version_done: + if (algorithm::is_alnum()(*current_iterator)) + internal_state = header_name; + else if (*current_iterator == '\r') + internal_state = headers_cr; + else + parsed_ok = false; + break; + case header_name: + if (*current_iterator == ':') + internal_state = header_colon; + else if (algorithm::is_alnum()(*current_iterator) || + algorithm::is_punct()(*current_iterator)) + break; + else + parsed_ok = false; + break; + case header_colon: + if (*current_iterator == ' ') + internal_state = header_value; + else + parsed_ok = false; + break; + case header_value: + if (*current_iterator == '\r') + internal_state = header_cr; + else if (algorithm::is_cntrl()(*current_iterator)) + parsed_ok = false; + break; + case header_cr: + if (*current_iterator == '\n') + internal_state = header_line_done; + else + parsed_ok = false; + break; + case header_line_done: + if (*current_iterator == '\r') + internal_state = headers_cr; + else if (algorithm::is_alnum()(*current_iterator)) + internal_state = header_name; + else + parsed_ok = false; + break; + case headers_cr: + if (*current_iterator == '\n') + internal_state = headers_done; + else + parsed_ok = false; + break; + case headers_done: + // anything that follows after headers_done is allowed. + break; + default: + parsed_ok = false; + }; + if (internal_state == stop_state) parsed_ok = true; + local_range = boost::make_iterator_range(++current_iterator, end); + } + return fusion::make_tuple( + parsed_ok, boost::make_iterator_range(start, current_iterator)); + } + + private: + state_t internal_state; +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SERVER_REQUEST_PARSER_HPP_20101005 */ diff --git a/cpp-netlib/boost/network/protocol/http/server/socket_options_base.hpp b/cpp-netlib/boost/network/protocol/http/server/socket_options_base.hpp new file mode 100644 index 00000000..9cc2ee15 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/socket_options_base.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SERVER_SOCKET_OPTIONS_BASE_HPP_20101210 +#define BOOST_NETWORK_PROTOCOL_HTTP_SERVER_SOCKET_OPTIONS_BASE_HPP_20101210 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +struct socket_options_base { + protected: + asio::socket_base::reuse_address acceptor_reuse_address; + asio::socket_base::enable_connection_aborted acceptor_report_aborted; + boost::optional receive_buffer_size; + boost::optional send_buffer_size; + boost::optional + receive_low_watermark; + boost::optional send_low_watermark; + asio::socket_base::non_blocking_io non_blocking_io; + asio::socket_base::linger linger; + + template + explicit socket_options_base(server_options const &options) + : acceptor_reuse_address(options.reuse_address()), + acceptor_report_aborted(options.report_aborted()), + receive_buffer_size(options.receive_buffer_size()), + send_buffer_size(options.send_buffer_size()), + receive_low_watermark(options.receive_low_watermark()), + send_low_watermark(options.send_low_watermark()), + non_blocking_io(options.non_blocking_io()), + linger(options.linger(), options.linger_timeout()) {} + + void acceptor_options(boost::asio::ip::tcp::acceptor &acceptor) { + acceptor.set_option(acceptor_reuse_address); + acceptor.set_option(acceptor_report_aborted); + } + + void socket_options(boost::asio::ip::tcp::socket &socket) { + boost::system::error_code ignored; + socket.io_control(non_blocking_io, ignored); + socket.set_option(linger, ignored); + if (receive_buffer_size) socket.set_option(*receive_buffer_size, ignored); + if (receive_low_watermark) + socket.set_option(*receive_low_watermark, ignored); + if (send_buffer_size) socket.set_option(*send_buffer_size, ignored); + if (send_low_watermark) socket.set_option(*send_low_watermark, ignored); + } +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SERVER_SOCKET_OPTIONS_BASE_HPP_20101210 \ + */ diff --git a/cpp-netlib/boost/network/protocol/http/server/storage_base.hpp b/cpp-netlib/boost/network/protocol/http/server/storage_base.hpp new file mode 100644 index 00000000..ce0073c7 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/storage_base.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SERVER_STORAGE_BASE_HPP_20101210 +#define BOOST_NETWORK_PROTOCOL_HTTP_SERVER_STORAGE_BASE_HPP_20101210 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +struct server_storage_base { + struct no_io_service {}; + struct has_io_service {}; + + protected: + template + explicit server_storage_base(server_options const& options) + : self_service_(options.io_service() + ? options.io_service() + : boost::make_shared()), + service_(*self_service_) {} + + boost::shared_ptr self_service_; + asio::io_service& service_; +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SERVER_STORAGE_BASE_HPP_20101210 */ diff --git a/cpp-netlib/boost/network/protocol/http/server/sync_connection.hpp b/cpp-netlib/boost/network/protocol/http/server/sync_connection.hpp new file mode 100644 index 00000000..bfe74969 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/sync_connection.hpp @@ -0,0 +1,233 @@ +// Copyright 2009 (c) Dean Michael Berris +// Copyright 2009 (c) Tarroo, Inc. +// Adapted from Christopher Kholhoff's Boost.Asio Example, released under +// the Boost Software License, Version 1.0. (See acccompanying file +// LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_NETWORK_HTTP_SERVER_SYNC_CONNECTION_HPP_ +#define BOOST_NETWORK_HTTP_SERVER_SYNC_CONNECTION_HPP_ + +#ifndef BOOST_NETWORK_HTTP_SERVER_CONNECTION_BUFFER_SIZE +#define BOOST_NETWORK_HTTP_SERVER_CONNECTION_BUFFER_SIZE 1024uL +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct sync_connection + : boost::enable_shared_from_this > { + + sync_connection(boost::asio::io_service &service, Handler &handler) + : service_(service), + handler_(handler), + socket_(service_), + wrapper_(service_) {} + + boost::asio::ip::tcp::socket &socket() { return socket_; } + + void start() { + // This is HTTP so we really want to just + // read and parse a request that's incoming + // and then pass that request object to the + // handler_ instance. + // + using boost::asio::ip::tcp; + boost::system::error_code option_error; + socket_.set_option(tcp::no_delay(true), option_error); + if (option_error) + handler_.log(boost::system::system_error(option_error).what()); + socket_.async_read_some( + boost::asio::buffer(buffer_), + wrapper_.wrap( + boost::bind(&sync_connection::handle_read_headers, + sync_connection::shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); + } + + private: + struct is_content_length { + template + bool operator()(Header const &header) { + return boost::to_lower_copy(header.name) == "content-length"; + } + }; + + void handle_read_headers(boost::system::error_code const &ec, + size_t bytes_transferred) { + if (!ec) { + request_.source = socket_.remote_endpoint().address().to_string(); + request_.source_port = socket_.remote_endpoint().port(); + boost::tribool done; + buffer_type::iterator new_start; + tie(done, new_start) = parser_.parse_headers( + request_, buffer_.data(), buffer_.data() + bytes_transferred); + if (done) { + if (request_.method[0] == 'P') { + // look for the content-length header + typename std::vector::type>::iterator + it = std::find_if(request_.headers.begin(), + request_.headers.end(), is_content_length()); + if (it == request_.headers.end()) { + response_ = basic_response::stock_reply( + basic_response::bad_request); + boost::asio::async_write( + socket_, response_.to_buffers(), + wrapper_.wrap(boost::bind( + &sync_connection::handle_write, + sync_connection::shared_from_this(), + boost::asio::placeholders::error))); + return; + } + + size_t content_length = 0; + + try { + content_length = boost::lexical_cast(it->value); + } + catch (...) { + response_ = basic_response::stock_reply( + basic_response::bad_request); + boost::asio::async_write( + socket_, response_.to_buffers(), + wrapper_.wrap(boost::bind( + &sync_connection::handle_write, + sync_connection::shared_from_this(), + boost::asio::placeholders::error))); + return; + } + + if (content_length != 0) { + if (new_start != (buffer_.begin() + bytes_transferred)) { + request_.body.append(new_start, + buffer_.begin() + bytes_transferred); + content_length -= + std::distance(new_start, buffer_.begin() + bytes_transferred); + } + if (content_length > 0) { + socket_.async_read_some( + boost::asio::buffer(buffer_), + wrapper_.wrap(boost::bind( + &sync_connection::handle_read_body_contents, + sync_connection::shared_from_this(), + boost::asio::placeholders::error, content_length, + boost::asio::placeholders::bytes_transferred))); + return; + } + } + + handler_(request_, response_); + boost::asio::async_write( + socket_, response_.to_buffers(), + wrapper_.wrap( + boost::bind(&sync_connection::handle_write, + sync_connection::shared_from_this(), + boost::asio::placeholders::error))); + } else { + handler_(request_, response_); + boost::asio::async_write( + socket_, response_.to_buffers(), + wrapper_.wrap( + boost::bind(&sync_connection::handle_write, + sync_connection::shared_from_this(), + boost::asio::placeholders::error))); + } + } else if (!done) { + response_ = + basic_response::stock_reply(basic_response::bad_request); + boost::asio::async_write( + socket_, response_.to_buffers(), + wrapper_.wrap( + boost::bind(&sync_connection::handle_write, + sync_connection::shared_from_this(), + boost::asio::placeholders::error))); + } else { + socket_.async_read_some( + boost::asio::buffer(buffer_), + wrapper_.wrap( + boost::bind(&sync_connection::handle_read_headers, + sync_connection::shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred))); + } + } + // TODO Log the error? + } + + void handle_read_body_contents(boost::system::error_code const &ec, + size_t bytes_to_read, + size_t bytes_transferred) { + if (!ec) { + size_t difference = bytes_to_read - bytes_transferred; + buffer_type::iterator start = buffer_.begin(), past_end = start; + std::advance(past_end, (std::min)(bytes_to_read, bytes_transferred)); + request_.body.append(buffer_.begin(), past_end); + if (difference == 0) { + handler_(request_, response_); + boost::asio::async_write( + socket_, response_.to_buffers(), + wrapper_.wrap( + boost::bind(&sync_connection::handle_write, + sync_connection::shared_from_this(), + boost::asio::placeholders::error))); + } else { + socket_.async_read_some( + boost::asio::buffer(buffer_), + wrapper_.wrap(boost::bind( + &sync_connection::handle_read_body_contents, + sync_connection::shared_from_this(), + boost::asio::placeholders::error, difference, + boost::asio::placeholders::bytes_transferred))); + } + } + // TODO Log the error? + } + + void handle_write(boost::system::error_code const &ec) { + if (!ec) { + using boost::asio::ip::tcp; + boost::system::error_code ignored_ec; + socket_.shutdown(tcp::socket::shutdown_receive, ignored_ec); + } + } + + boost::asio::io_service &service_; + Handler &handler_; + boost::asio::ip::tcp::socket socket_; + boost::asio::io_service::strand wrapper_; + + typedef boost::array + buffer_type; + buffer_type buffer_; + typedef basic_request_parser request_parser; + request_parser parser_; + basic_request request_; + basic_response response_; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_HTTP_SERVER_SYNC_CONNECTION_HPP_ diff --git a/cpp-netlib/boost/network/protocol/http/server/sync_server.hpp b/cpp-netlib/boost/network/protocol/http/server/sync_server.hpp new file mode 100644 index 00000000..7c5c42fa --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/server/sync_server.hpp @@ -0,0 +1,134 @@ + +// Copyright 2010 Dean Michael Berris. +// Copyright 2010 Glyn Matthews. +// 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 BOOST_NETWORK_PROTOCOL_HTTP_SERVER_SYNC_SERVER_HPP_20101025 +#define BOOST_NETWORK_PROTOCOL_HTTP_SERVER_SYNC_SERVER_HPP_20101025 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct sync_server_base : server_storage_base, socket_options_base { + typedef typename string::type string_type; + typedef basic_request request; + typedef basic_response response; + typedef typename boost::network::http::response_header::type + response_header; + + sync_server_base(server_options const& options) + : server_storage_base(options), + socket_options_base(options), + handler_(options.handler()), + address_(options.address()), + port_(options.port()), + acceptor_(server_storage_base::service_), + new_connection(), + listening_mutex_(), + listening_(false) {} + + void run() { + listen(); + service_.run(); + } + + void stop() { + // stop accepting new connections and let all the existing handlers + // finish. + system::error_code ignored; + acceptor_.close(ignored); + service_.stop(); + } + + void listen() { + boost::unique_lock listening_lock(listening_mutex_); + if (!listening_) start_listening(); + } + + private: + Handler& handler_; + string_type address_, port_; + boost::asio::ip::tcp::acceptor acceptor_; + boost::shared_ptr > new_connection; + boost::mutex listening_mutex_; + bool listening_; + + void handle_accept(boost::system::error_code const& ec) { + if (ec) { + } + socket_options_base::socket_options(new_connection->socket()); + new_connection->start(); + new_connection.reset(new sync_connection(service_, handler_)); + acceptor_.async_accept( + new_connection->socket(), + boost::bind(&sync_server_base::handle_accept, this, + boost::asio::placeholders::error)); + } + + void start_listening() { + using boost::asio::ip::tcp; + system::error_code error; + tcp::resolver resolver(service_); + tcp::resolver::query query(address_, port_); + tcp::resolver::iterator endpoint_iterator = resolver.resolve(query, error); + if (error) { + BOOST_NETWORK_MESSAGE("Error resolving address: " << address_ << ':' + << port_); + boost::throw_exception(std::runtime_error("Error resolving address.")); + } + tcp::endpoint endpoint = *endpoint_iterator; + acceptor_.open(endpoint.protocol(), error); + if (error) { + BOOST_NETWORK_MESSAGE("Error opening socket: " << address_ << ':' << port_ + << " -- reason: '" << error + << '\''); + boost::throw_exception(std::runtime_error("Error opening socket.")); + } + socket_options_base::acceptor_options(acceptor_); + acceptor_.bind(endpoint, error); + if (error) { + BOOST_NETWORK_MESSAGE("Error binding to socket: " + << address_ << ':' << port_ << " -- reason: '" + << error << '\''); + boost::throw_exception(std::runtime_error("Error binding to socket.")); + } + acceptor_.listen(tcp::socket::max_connections, error); + if (error) { + BOOST_NETWORK_MESSAGE("Error listening on socket: " + << address_ << ':' << port_ << " -- reason: '" + << error << '\''); + boost::throw_exception(std::runtime_error("Error listening on socket.")); + } + new_connection.reset(new sync_connection(service_, handler_)); + acceptor_.async_accept( + new_connection->socket(), + boost::bind(&sync_server_base::handle_accept, this, + boost::asio::placeholders::error)); + listening_ = true; + } +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SERVER_SYNC_SERVER_HPP_20101025 */ diff --git a/cpp-netlib/boost/network/protocol/http/support/client_or_server.hpp b/cpp-netlib/boost/network/protocol/http/support/client_or_server.hpp new file mode 100644 index 00000000..434d6f35 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/support/client_or_server.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_CLIENT_OR_SERVER_HPP_20101127 +#define BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_CLIENT_OR_SERVER_HPP_20101127 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct unsupported_tag; + +template +struct client_or_server { + typedef unsupported_tag type; +}; + +template +struct client_or_server >::type> { + typedef tags::server type; +}; + +template +struct client_or_server >::type> { + typedef tags::client type; +}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_CLIENT_OR_SERVER_HPP_20101127 */ diff --git a/cpp-netlib/boost/network/protocol/http/support/is_client.hpp b/cpp-netlib/boost/network/protocol/http/support/is_client.hpp new file mode 100644 index 00000000..c4201c1c --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/support/is_client.hpp @@ -0,0 +1,29 @@ +#ifndef BOOST_NETWORK_PROTOCOL_SUPPORT_IS_CLIENT_HPP_20101118 +#define BOOST_NETWORK_PROTOCOL_SUPPORT_IS_CLIENT_HPP_20101118 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct is_client : mpl::false_ {}; + +template +struct is_client< + Tag, typename enable_if::type> : mpl::true_ {}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_SUPPORT_IS_CLIENT_HPP_20101118 */ diff --git a/cpp-netlib/boost/network/protocol/http/support/is_http.hpp b/cpp-netlib/boost/network/protocol/http/support/is_http.hpp new file mode 100644 index 00000000..d170819c --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/support/is_http.hpp @@ -0,0 +1,29 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_HTTP_HPP_20100622 +#define BOOST_NETWORK_SUPPORT_IS_HTTP_HPP_20100622 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct is_http : mpl::false_ {}; + +template +struct is_http::type> : mpl::true_ {}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_SUPPORT_IS_HTTP_HPP_20100622 diff --git a/cpp-netlib/boost/network/protocol/http/support/is_keepalive.hpp b/cpp-netlib/boost/network/protocol/http/support/is_keepalive.hpp new file mode 100644 index 00000000..a063167f --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/support/is_keepalive.hpp @@ -0,0 +1,32 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_KEEPALIVE_HPP_20100927 +#define BOOST_NETWORK_SUPPORT_IS_KEEPALIVE_HPP_20100927 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct unsupported_tag; + +template +struct is_keepalive : mpl::false_ {}; + +template +struct is_keepalive< + Tag, typename enable_if::type> : mpl::true_ {}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_SUPPORT_IS_KEEPALIVE_HPP_20100927 */ diff --git a/cpp-netlib/boost/network/protocol/http/support/is_server.hpp b/cpp-netlib/boost/network/protocol/http/support/is_server.hpp new file mode 100644 index 00000000..365ad6e3 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/support/is_server.hpp @@ -0,0 +1,29 @@ +#ifndef BOOST_NETWORK_PROTOCOL_SUPPORT_IS_SERVER_HPP_20101118 +#define BOOST_NETWORK_PROTOCOL_SUPPORT_IS_SERVER_HPP_20101118 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct is_server : mpl::false_ {}; + +template +struct is_server< + Tag, typename enable_if::type> : mpl::true_ {}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_SUPPORT_IS_SERVER_HPP_20101118 */ diff --git a/cpp-netlib/boost/network/protocol/http/support/is_simple.hpp b/cpp-netlib/boost/network/protocol/http/support/is_simple.hpp new file mode 100644 index 00000000..c329df8f --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/support/is_simple.hpp @@ -0,0 +1,29 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_SIMPLE_HPP_20100927 +#define BOOST_NETWORK_SUPPORT_IS_SIMPLE_HPP_20100927 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct is_simple : mpl::false_ {}; + +template +struct is_simple< + Tag, typename enable_if::type> : mpl::true_ {}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_SUPPORT_IS_SIMPLE_HPP_20100927 */ diff --git a/cpp-netlib/boost/network/protocol/http/support/sync_only.hpp b/cpp-netlib/boost/network/protocol/http/support/sync_only.hpp new file mode 100644 index 00000000..6a3eb3fe --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/support/sync_only.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_SYNC_ONLY_HPP_20100927 +#define BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_SYNC_ONLY_HPP_20100927 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct sync_only + : mpl::inherit_linearly< + typename mpl::replace_if::type, + is_same, + tags::sync>::type, + mpl::inherit > {}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_SYNC_ONLY_HPP_20100927 */ diff --git a/cpp-netlib/boost/network/protocol/http/tags.hpp b/cpp-netlib/boost/network/protocol/http/tags.hpp new file mode 100644 index 00000000..bdf8b443 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/tags.hpp @@ -0,0 +1,71 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TAGS_HPP_20101019 +#define BOOST_NETWORK_PROTOCOL_HTTP_TAGS_HPP_20101019 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { +namespace tags { + +struct http { + typedef mpl::true_::type is_http; +}; +struct keepalive { + typedef mpl::true_::type is_keepalive; +}; +struct simple { + typedef mpl::true_::type is_simple; +}; +struct server { + typedef mpl::true_::type is_server; +}; +struct client { + typedef mpl::true_::type is_client; +}; + +using namespace boost::network::tags; + +template +struct components; + +typedef mpl::vector + http_default_8bit_tcp_resolve_tags; +typedef mpl::vector + http_default_8bit_udp_resolve_tags; +typedef mpl::vector + http_keepalive_8bit_tcp_resolve_tags; +typedef mpl::vector + http_keepalive_8bit_udp_resolve_tags; +typedef mpl::vector + http_async_8bit_udp_resolve_tags; +typedef mpl::vector + http_async_8bit_tcp_resolve_tags; +typedef mpl::vector + http_server_tags; +typedef mpl::vector + http_async_server_tags; + +BOOST_NETWORK_DEFINE_TAG(http_default_8bit_tcp_resolve); +BOOST_NETWORK_DEFINE_TAG(http_default_8bit_udp_resolve); +BOOST_NETWORK_DEFINE_TAG(http_keepalive_8bit_tcp_resolve); +BOOST_NETWORK_DEFINE_TAG(http_keepalive_8bit_udp_resolve); +BOOST_NETWORK_DEFINE_TAG(http_async_8bit_udp_resolve); +BOOST_NETWORK_DEFINE_TAG(http_async_8bit_tcp_resolve); +BOOST_NETWORK_DEFINE_TAG(http_server); +BOOST_NETWORK_DEFINE_TAG(http_async_server); + +} /* tags */ + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_TAGS_HPP_20101019 */ diff --git a/cpp-netlib/boost/network/protocol/http/traits.hpp b/cpp-netlib/boost/network/protocol/http/traits.hpp new file mode 100644 index 00000000..afa4ea0c --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits.hpp @@ -0,0 +1,18 @@ +// This file is part of the Boost Network library +// Based on the Pion Network Library (r421) +// Copyright Atomic Labs, Inc. 2007-2008 +// See http://cpp-netlib.sourceforge.net for library home page. +// +// 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 BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_HPP +#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_HPP + +// Convenience header for including different traits implementations. +#include +//#include +#include + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_HPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/connection_keepalive.hpp b/cpp-netlib/boost/network/protocol/http/traits/connection_keepalive.hpp new file mode 100644 index 00000000..0069b3a3 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/connection_keepalive.hpp @@ -0,0 +1,25 @@ +// Copyright (c) Dean Michael Berris 2010. +// 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 BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_CONECTION_KEEPALIVE_20091218 +#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_CONECTION_KEEPALIVE_20091218 + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct connection_keepalive : is_keepalive {}; + +} /* http */ + +} /* network */ + +} /* boost */ + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_CONECTION_KEEPALIVE_20091218 diff --git a/cpp-netlib/boost/network/protocol/http/traits/connection_policy.hpp b/cpp-netlib/boost/network/protocol/http/traits/connection_policy.hpp new file mode 100644 index 00000000..4ee96eee --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/connection_policy.hpp @@ -0,0 +1,61 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_CONNECTION_POLICY_20091214 +#define BOOST_NETWORK_PROTOCOL_HTTP_CONNECTION_POLICY_20091214 + +// Copyright 2013 Google, Inc. +// Copyright Dean Michael Berris 2009. +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct unsupported_tag; + +template +struct connection_policy { + typedef unsupported_tag type; +}; + +template +struct connection_policy >::type> { + typedef async_connection_policy type; +}; + +template +struct connection_policy< + Tag, version_major, version_minor, + typename enable_if< + mpl::and_, mpl::not_ > > >::type> { + typedef simple_connection_policy type; +}; + +template +struct connection_policy< + Tag, version_major, version_minor, + typename enable_if< + mpl::and_, mpl::not_ > > >::type> { + typedef pooled_connection_policy type; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_CONNECTION_POLICY_20091214 diff --git a/cpp-netlib/boost/network/protocol/http/traits/delegate_factory.hpp b/cpp-netlib/boost/network/protocol/http/traits/delegate_factory.hpp new file mode 100644 index 00000000..cec92c26 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/delegate_factory.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_DELEGATE_FACTORY_HPP_20110819 +#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_DELEGATE_FACTORY_HPP_20110819 + +// Copyright 2011 Dean Michael Berris (dberris@google.com). +// Copyright 2011 Google, Inc. +// 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) + +#include + +namespace boost { +namespace network { +namespace http { + +namespace impl { + +template +struct connection_delegate_factory; + +} /* impl */ + +template +struct unsupported_tag; + +template +struct delegate_factory { + typedef unsupported_tag type; +}; + +template +struct delegate_factory >::type> { + typedef impl::connection_delegate_factory type; +}; + +} /* http */ +} /* network */ +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_DELEGATE_FACTORY_HPP_20110819 */ diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/chunk_cache.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/chunk_cache.ipp new file mode 100644 index 00000000..c7ac9c88 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/chunk_cache.ipp @@ -0,0 +1,32 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CHUNK_CACHE_CONTAINER_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CHUNK_CACHE_CONTAINER_IPP + +#include +#include + +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct chunk_cache { + // TODO define the allocator using an allocator_traits? + typedef std::list::type> > type; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CHUNK_CACHE_CONTAINER_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/content.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/content.ipp new file mode 100644 index 00000000..81e96d37 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/content.ipp @@ -0,0 +1,46 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CONTENT_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CONTENT_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct content { + static char const* type_html() { + static char const* const TYPE_HTML = "text/html"; + return TYPE_HTML; + }; + + static char const* type_text() { + static char const* const TYPE_TEXT = "text/plain"; + return TYPE_TEXT; + }; + + static char const* type_xml() { + static char const* const TYPE_XML = "text/xml"; + return TYPE_XML; + }; + + static char const* type_urlencoded() { + static char const* const TYPE_URLENCODED = + "application/x-www-form-urlencoded"; + return TYPE_URLENCODED; + }; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_CONTENT_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/cookie_name.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/cookie_name.ipp new file mode 100644 index 00000000..af8cf6c5 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/cookie_name.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_NAME_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_NAME_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct cookie_name { + static boost::uint32_t const MAX = 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_NAME_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/cookie_value.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/cookie_value.ipp new file mode 100644 index 00000000..32b7ef38 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/cookie_value.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_VALUE_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_VALUE_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct cookie_value { + static boost::uint32_t const MAX = 1024u * 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_COOKIE_VALUE_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/cookies_container.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/cookies_container.ipp new file mode 100644 index 00000000..ef4db91c --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/cookies_container.ipp @@ -0,0 +1,30 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_COOKIES_CONTAINER_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_COOKIES_CONTAINER_IPP + +#include + +#include + +namespace boost { +namespace network { +namespace http { + +template +struct cookies_container { + typedef std::multimap::type, typename string::type> + type; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_COOKIES_CONTAINER_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/delimiters.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/delimiters.ipp new file mode 100644 index 00000000..b916b670 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/delimiters.ipp @@ -0,0 +1,41 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_DELIMITERS_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_DELIMITERS_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +// specialize on the tags::http_default_8bit_tcp_resolve type +template <> +struct delimiters { + static char const* string_crlf() { + static char const* const CRLF = "\x0D\x0A"; + return CRLF; + }; + + static char const* string_http_version() { + static char const* const HTTP_VERSION = "HTTP/1.1"; + return HTTP_VERSION; + }; + + static char const* header_name_value_delimiter() { + static char const* const HEADER_NAME_VALUE_DELIMITER = ": "; + return HEADER_NAME_VALUE_DELIMITER; + }; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_DELIMITERS_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/header_name.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/header_name.ipp new file mode 100644 index 00000000..dcab0f3f --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/header_name.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_NAME_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_NAME_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct header_name { + static boost::uint32_t const MAX = 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_NAME_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/header_value.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/header_value.ipp new file mode 100644 index 00000000..8f09d718 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/header_value.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_VALUE_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_VALUE_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct header_value { + static boost::uint32_t const MAX = 1024u * 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HEADER_VALUE_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/headers.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/headers.ipp new file mode 100644 index 00000000..24fac86b --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/headers.ipp @@ -0,0 +1,85 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_HPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_HPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct headers_ { + static char const* host() { + static char const* const HOST = "Host"; + return HOST; + }; + + static char const* cookie() { + static char const* const COOKIE = "Cookie"; + return COOKIE; + }; + + static char const* set_cookie() { + static char const* const SET_COOKIE = "Set-Cookie"; + return SET_COOKIE; + }; + + static char const* connection() { + static char const* const CONNECTION = "Connection"; + return CONNECTION; + }; + + static char const* content_type() { + static char const* const CONTENT_TYPE = "Content-Type"; + return CONTENT_TYPE; + }; + + static char const* content_length() { + static char const* const CONTENT_LENGTH = "Content-Length"; + return CONTENT_LENGTH; + }; + + static char const* content_location() { + static char const* const CONTENT_LOCATION = "Content-Location"; + return CONTENT_LOCATION; + }; + + static char const* last_modified() { + static char const* const LAST_MODIFIED = "Last-Modified"; + return LAST_MODIFIED; + }; + + static char const* if_modified_since() { + static char const* const IF_MODIFIED_SINCE = "If-Modified-Since"; + return IF_MODIFIED_SINCE; + }; + + static char const* transfer_encoding() { + static char const* const TRANSFER_ENCODING = "Transfer-Encoding"; + return TRANSFER_ENCODING; + }; + + static char const* location() { + static char const* const LOCATION = "Location"; + return LOCATION; + }; + + static char const* authorization() { + static char const* const AUTHORIZATION = "Authorization"; + return AUTHORIZATION; + }; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_HPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/headers_container.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/headers_container.ipp new file mode 100644 index 00000000..d06585ef --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/headers_container.ipp @@ -0,0 +1,51 @@ + +// Copyright 2013 Google, Inc. +// Copyright 2008 Dean Michael Berris +// 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_CONTAINER_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_CONTAINER_IPP + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace impl { + +// Moving implementation from original +// message_traits implementation by +// Atomic Labs, Inc. +// -- +// returns true if str1 < str2 (ignoring case) +struct is_less_ignore_case_impl { + inline bool operator()( + string::type const& str1, + string::type const& str2) + const { + return to_lower_copy(str1) < to_lower_copy(str2); + }; +}; + +template +struct headers_container_impl< + Tag, typename enable_if::type> { + + typedef is_less_ignore_case_impl is_less_ignore_case; + + typedef std::multimap::type, + string::type, + is_less_ignore_case> type; +}; + +} // namespace impl +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HEADERS_CONTAINER_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/method.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/method.ipp new file mode 100644 index 00000000..17c26111 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/method.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_METHOD_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_METHOD_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct method { + static boost::uint32_t const MAX = 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_METHOD_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/post_content.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/post_content.ipp new file mode 100644 index 00000000..6db2b2db --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/post_content.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_POST_CONTENT_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_POST_CONTENT_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct post_content { + static boost::uint32_t const MAX = 1024u * 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_POST_CONTENT_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/query_container.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/query_container.ipp new file mode 100644 index 00000000..b672c3b0 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/query_container.ipp @@ -0,0 +1,30 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_QUERY_CONTAINER_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_QUERY_CONTAINER_IPP + +#include + +#include + +namespace boost { +namespace network { +namespace http { + +template +struct query_container { + typedef std::multimap::type, typename string::type> + type; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_QUERY_CONTAINER_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/query_name.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/query_name.ipp new file mode 100644 index 00000000..f748172b --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/query_name.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_NAME_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_NAME_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct query_name { + static boost::uint32_t const MAX = 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_NAME_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/query_string.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/query_string.ipp new file mode 100644 index 00000000..4876e2c9 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/query_string.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_STRING_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_STRING_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct query_string { + static boost::uint32_t const MAX = 1024u * 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_STRING_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/query_value.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/query_value.ipp new file mode 100644 index 00000000..7a692a06 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/query_value.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_VALUE_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_VALUE_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct query_value { + static boost::uint32_t const MAX = 1024u * 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_QUERY_VALUE_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/request_methods.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/request_methods.ipp new file mode 100644 index 00000000..140beeff --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/request_methods.ipp @@ -0,0 +1,50 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_REQUEST_METHODS_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_REQUEST_METHODS_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct request_methods { + static char const* head() { + static char const* const HEAD = "HEAD"; + return HEAD; + }; + + static char const* get() { + static char const* const GET = "GET"; + return GET; + }; + + static char const* put() { + static char const* const PUT = "PUT"; + return PUT; + }; + + static char const* post() { + static char const* const POST = "POST"; + return POST; + }; + + static char const* delete_() { + static char const* const DELETE_ = "DELETE"; + return DELETE_; + }; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_REQUEST_METHODS_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/resource.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/resource.ipp new file mode 100644 index 00000000..5551d16f --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/resource.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_RESOURCE_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_RESOURCE_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct resource { + static boost::uint32_t const MAX = 1024u * 256u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_RESOURCE_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/response_code.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/response_code.ipp new file mode 100644 index 00000000..db32bcf9 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/response_code.ipp @@ -0,0 +1,45 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_CODE_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_CODE_IPP + +#include +#include + +namespace boost { +namespace network { +namespace http { + +/* This glob doesn't have a specialization on the + * tags::http_default_8bit_tcp_resolve + * yet because it doesn't need to define different behaviour/types + * on different message tags -- for example, it doesn't need to + * determine the type or change the values of the data no matter + * what the tag type is provided. + */ +template +struct response_code { + static boost::uint16_t const RC_OK = 200u; + static boost::uint16_t const RC_CREATED = 201u; + static boost::uint16_t const RC_NO_CONTENT = 204u; + static boost::uint16_t const RC_UNAUTHORIZED = 401u; + static boost::uint16_t const RC_FORBIDDEN = 403u; + static boost::uint16_t const RC_NOT_FOUND = 404u; + static boost::uint16_t const RC_METHOD_NOT_ALLOWED = 405u; + static boost::uint16_t const RC_NOT_MODIFIED = 304u; + static boost::uint16_t const RC_BAD_REQUEST = 400u; + static boost::uint16_t const RC_SERVER_ERROR = 500u; + static boost::uint16_t const RC_NOT_IMPLEMENTED = 501u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_CODE_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/response_message.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/response_message.ipp new file mode 100644 index 00000000..2f81b2d8 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/response_message.ipp @@ -0,0 +1,80 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_MESSAGE_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_MESSAGE_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct response_message { + static char const* ok() { + static char const* const RC_OK = "OK"; + return RC_OK; + }; + + static char const* created() { + static char const* const RC_CREATED = "Created"; + return RC_CREATED; + }; + + static char const* no_content() { + static char const* const RC_NO_CONTENT = "NO Content"; + return RC_NO_CONTENT; + }; + + static char const* unauthorized() { + static char const* const RC_UNAUTHORIZED = "Unauthorized"; + return RC_UNAUTHORIZED; + }; + + static char const* forbidden() { + static char const* const RC_FORBIDDEN = "Fobidden"; + return RC_FORBIDDEN; + }; + + static char const* not_found() { + static char const* const RC_NOT_FOUND = "Not Found"; + return RC_NOT_FOUND; + }; + + static char const* method_not_allowed() { + static char const* const RC_METHOD_NOT_ALLOWED = "Method Not Allowed"; + return RC_METHOD_NOT_ALLOWED; + }; + + static char const* not_modified() { + static char const* const RC_NOT_MODIFIED = "Not Modified"; + return RC_NOT_MODIFIED; + }; + + static char const* bad_request() { + static char const* const RC_BAD_REQUEST = "Bad Request"; + return RC_BAD_REQUEST; + }; + + static char const* server_error() { + static char const* const RC_SERVER_ERROR = "Server Error"; + return RC_SERVER_ERROR; + }; + + static char const* not_implemented() { + static char const* const RC_NOT_IMPLEMENTED = "Not Implemented"; + return RC_NOT_IMPLEMENTED; + }; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_RESPONSE_MESSAGE_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/impl/status_message.ipp b/cpp-netlib/boost/network/protocol/http/traits/impl/status_message.ipp new file mode 100644 index 00000000..78d8a9a4 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/impl/status_message.ipp @@ -0,0 +1,27 @@ + +// Copyright Dean Michael Berris 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 BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_STATUS_MESSAGE_IPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_STATUS_MESSAGE_IPP + +#include + +namespace boost { +namespace network { +namespace http { + +template <> +struct status_message_text { + static boost::uint32_t const MAX = 1024u; +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_STATUS_MESSAGE_IPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/message_traits.hpp b/cpp-netlib/boost/network/protocol/http/traits/message_traits.hpp new file mode 100644 index 00000000..8c2f65a6 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/message_traits.hpp @@ -0,0 +1,65 @@ + +// This file is part of the Boost Network library +// Based on the Pion Network Library (r421) +// Copyright Atomic Labs, Inc. 2007-2008 +// See http://cpp-netlib.sourceforge.net for library home page. +// +// 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) +// +// Some changes Copyright (c) Dean Michael Berris 2008 + +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HPP +#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_TRAITS_HPP + +namespace boost { +namespace network { +namespace http { + +template +struct delimiters; + +template +struct headers_; + +template +struct content; + +template +struct request_methods; + +template +struct response_message; + +template +struct response_code; + +template +struct query_container; + +template +struct cookies_container; + +template +struct chunk_cache; + +} // namespace http + +} // namespace network + +} // namespace boost + +// Defer definition in implementation files +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_HPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/parser_traits.hpp b/cpp-netlib/boost/network/protocol/http/traits/parser_traits.hpp new file mode 100644 index 00000000..82c3bc38 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/parser_traits.hpp @@ -0,0 +1,71 @@ +// This file is part of the Boost Network library +// Based on the Pion Network Library (r421) +// Copyright Atomic Labs, Inc. 2007-2008 +// See http://cpp-netlib.sourceforge.net for library home page. +// +// 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) +// +// Some changes Copyright 2008 (c) Dean Michael Berris + +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HPP +#define BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HPP + +namespace boost { +namespace network { +namespace http { + +template +struct status_message_text; + +template +struct method; + +template +struct resource; + +template +struct query_string; + +template +struct header_name; + +template +struct header_value; + +template +struct query_name; + +template +struct query_value; + +template +struct cookie_name; + +template +struct cookie_value; + +template +struct post_content; + +} // namespace http + +} // namespace network + +} // namespace boost + +// Include implementation files +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_PARSER_TRAITS_HPP diff --git a/cpp-netlib/boost/network/protocol/http/traits/resolver.hpp b/cpp-netlib/boost/network/protocol/http/traits/resolver.hpp new file mode 100644 index 00000000..45048fd8 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/resolver.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_RESOLVER_20091214 +#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_RESOLVER_20091214 + +// Copyright Dean Michael Berris 2009. +// 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) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct unsupported_tag; + +template +struct resolver + : mpl::if_, is_http >, + boost::asio::ip::tcp::resolver, + typename mpl::if_, is_http >, + boost::asio::ip::udp::resolver, + unsupported_tag >::type> { + BOOST_STATIC_ASSERT( + (mpl::not_, is_tcp > >::value)); +}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_RESOLVER_20091214 diff --git a/cpp-netlib/boost/network/protocol/http/traits/resolver_policy.hpp b/cpp-netlib/boost/network/protocol/http/traits/resolver_policy.hpp new file mode 100644 index 00000000..5c279dd3 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/resolver_policy.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_RESOLVER_POLICY_20091214 +#define BOOST_NETWORK_PROTOCOL_HTTP_RESOLVER_POLICY_20091214 + +// Copyright Dean Michael Berris 2009. +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace http { + +template +struct unsupported_tag; + +template +struct resolver_policy + : mpl::if_, is_http >, + policies::async_resolver, + typename mpl::if_, policies::sync_resolver, + unsupported_tag >::type> {}; + +} // namespace http + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_PROTOCOL_HTTP_RESOLVER_POLICY_20091214 diff --git a/cpp-netlib/boost/network/protocol/http/traits/vector.hpp b/cpp-netlib/boost/network/protocol/http/traits/vector.hpp new file mode 100644 index 00000000..bc343de7 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/http/traits/vector.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_VECTOR_HPP_20101019 +#define BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_VECTOR_HPP_20101019 + +// Copyright (c) Dean Michael Berris 2010. +// 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) + +#include +#include + +namespace boost { +namespace network { + +template <> +struct vector { + + template + struct apply { + typedef std::vector type; + }; +}; + +template <> +struct vector { + + template + struct apply { + typedef std::vector type; + }; +}; + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_TRAITS_VECTOR_HPP_20101019 */ diff --git a/cpp-netlib/boost/network/protocol/stream_handler.hpp b/cpp-netlib/boost/network/protocol/stream_handler.hpp new file mode 100644 index 00000000..615d8548 --- /dev/null +++ b/cpp-netlib/boost/network/protocol/stream_handler.hpp @@ -0,0 +1,188 @@ +#ifndef NETLIB_IO_STREAM_HANDLER_HPP +#define NETLIB_IO_STREAM_HANDLER_HPP + +// Copyright 2014 Jelle Van den Driessche. +// 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) + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#ifdef BOOST_NETWORK_ENABLE_HTTPS +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +typedef boost::asio::ip::tcp::socket tcp_socket; + +#ifndef BOOST_NETWORK_ENABLE_HTTPS +typedef tcp_socket stream_handler; +typedef void ssl_context; +#else + +typedef boost::asio::ssl::stream ssl_socket; +typedef boost::asio::ssl::context ssl_context; + +struct stream_handler { + public: + stream_handler(boost::shared_ptr socket) + : tcp_sock_(socket), ssl_enabled(false) {} + + ~stream_handler() {} + + stream_handler(boost::shared_ptr socket) + : ssl_sock_(socket), ssl_enabled(true) {} + + stream_handler(boost::asio::io_service& io, + boost::shared_ptr ctx = + boost::shared_ptr()) { + tcp_sock_ = boost::make_shared(boost::ref(io)); + ssl_enabled = false; + if (ctx) { + /// SSL is enabled + ssl_sock_ = + boost::make_shared(boost::ref(io), boost::ref(*ctx)); + ssl_enabled = true; + } + } + + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void(boost::system::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) { + try { + if (ssl_enabled) { + ssl_sock_->async_write_some(buffers, handler); + } else { + tcp_sock_->async_write_some(buffers, handler); + } + } + catch (const boost::system::error_code& e) { + std::cerr << e.message() << std::endl; + } + catch (const boost::system::system_error& e) { + std::cerr << e.code() << ": " << e.what() << std::endl; + } + } + + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void(boost::system::error_code, std::size_t)) + async_read_some(const MutableBufferSequence& buffers, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) { + try { + if (ssl_enabled) { + ssl_sock_->async_read_some(buffers, handler); + } else { + tcp_sock_->async_read_some(buffers, handler); + } + } + catch (const boost::system::error_code& e) { + std::cerr << e.message() << std::endl; + } + catch (const boost::system::system_error& e) { + std::cerr << e.code() << ": " << e.what() << std::endl; + } + } + + void close(boost::system::error_code& e) { + if (ssl_enabled) { + ssl_sock_->next_layer().close(); + } else { + tcp_sock_->close(); + } + } + + tcp_socket::endpoint_type remote_endpoint() const { + if (ssl_enabled) { + return ssl_sock_->next_layer().remote_endpoint(); + } else { + return tcp_sock_->remote_endpoint(); + } + } + + void shutdown(boost::asio::socket_base::shutdown_type st, + boost::system::error_code& e) { + try { + if (ssl_enabled) { + ssl_sock_->shutdown(e); + } else { + tcp_sock_->shutdown(boost::asio::ip::tcp::socket::shutdown_send, e); + } + } + catch (const boost::system::error_code& e) { + std::cerr << e.message() << std::endl; + } + catch (const boost::system::system_error& e) { + std::cerr << e.code() << ": " << e.what() << std::endl; + } + } + + ssl_socket::next_layer_type& next_layer() const { + if (ssl_enabled) { + return ssl_sock_->next_layer(); + } else { + return *tcp_sock_; + } + } + + ssl_socket::lowest_layer_type& lowest_layer() const { + if (ssl_enabled) { + return ssl_sock_->lowest_layer(); + } else { + return tcp_sock_->lowest_layer(); + } + } + + template + BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, + void(boost::system::error_code)) + async_handshake(ssl_socket::handshake_type type, + BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler) { + try { + if (ssl_enabled) { + return ssl_sock_->async_handshake(type, handler); + } else { + // NOOP + } + } + catch (const boost::system::error_code& e) { + std::cerr << e.message() << std::endl; + } + catch (const boost::system::system_error& e) { + std::cerr << e.code() << ": " << e.what() << std::endl; + } + } + boost::shared_ptr get_tcp_socket() { return tcp_sock_; } + boost::shared_ptr get_ssl_socket() { return ssl_sock_; } + + bool is_ssl_enabled() { return ssl_enabled; } + + private: + boost::shared_ptr tcp_sock_; + boost::shared_ptr ssl_sock_; + bool ssl_enabled; +}; +#endif +} +} + +#endif diff --git a/cpp-netlib/boost/network/support/is_async.hpp b/cpp-netlib/boost/network/support/is_async.hpp new file mode 100644 index 00000000..74fbab3b --- /dev/null +++ b/cpp-netlib/boost/network/support/is_async.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_ASYNC_HPP_20100608 +#define BOOST_NETWORK_SUPPORT_IS_ASYNC_HPP_20100608 + +// Copyright 2010 (c) Dean Michael Berris +// Copyright 2010 (c) Sinefunc, Inc. +// 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) + +#include +#include + +namespace boost { +namespace network { + +template +struct is_async : mpl::false_ {}; + +template +struct is_async< + Tag, typename enable_if::type> : mpl::true_ {}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_SUPPORT_IS_ASYNC_HPP_2010608 diff --git a/cpp-netlib/boost/network/support/is_default_string.hpp b/cpp-netlib/boost/network/support/is_default_string.hpp new file mode 100644 index 00000000..78e2a16f --- /dev/null +++ b/cpp-netlib/boost/network/support/is_default_string.hpp @@ -0,0 +1,27 @@ +// Copyright Dean Michael Berris 2010 +// 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 BOOST_NETWORK_SUPPORT_STRING_CHECK_20100808 +#define BOOST_NETWORK_SUPPORT_STRING_CHECK_20100808 + +#include +#include + +namespace boost { +namespace network { + +template +struct is_default_string : mpl::false_ {}; + +template +struct is_default_string< + Tag, + typename enable_if::type> : mpl::true_ {}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_SUPPORT_STRING_CHECK_20100808 diff --git a/cpp-netlib/boost/network/support/is_default_wstring.hpp b/cpp-netlib/boost/network/support/is_default_wstring.hpp new file mode 100644 index 00000000..02f4db87 --- /dev/null +++ b/cpp-netlib/boost/network/support/is_default_wstring.hpp @@ -0,0 +1,27 @@ +// Copyright Dean Michael Berris 2010 +// 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 BOOST_NETWORK_SUPPORT_WSTRING_CHECK_20100808 +#define BOOST_NETWORK_SUPPORT_WSTRING_CHECK_20100808 + +#include +#include + +namespace boost { +namespace network { + +template +struct is_default_wstring : mpl::false_ {}; + +template +struct is_default_wstring< + Tag, + typename enable_if::type> : mpl::true_ {}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_SUPPORT_STRING_CHECK_20100808 diff --git a/cpp-netlib/boost/network/support/is_http.hpp b/cpp-netlib/boost/network/support/is_http.hpp new file mode 100644 index 00000000..37ab06a4 --- /dev/null +++ b/cpp-netlib/boost/network/support/is_http.hpp @@ -0,0 +1,26 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_HTTP_HPP_20100622 +#define BOOST_NETWORK_SUPPORT_IS_HTTP_HPP_20100622 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include + +namespace boost { +namespace network { + +template +struct is_http : mpl::false_ {}; + +template +struct is_http::type> : mpl::true_ {}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_SUPPORT_IS_HTTP_HPP_20100622 diff --git a/cpp-netlib/boost/network/support/is_keepalive.hpp b/cpp-netlib/boost/network/support/is_keepalive.hpp new file mode 100644 index 00000000..4e454da9 --- /dev/null +++ b/cpp-netlib/boost/network/support/is_keepalive.hpp @@ -0,0 +1,26 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_KEEPALIVE_HPP_20100927 +#define BOOST_NETWORK_SUPPORT_IS_KEEPALIVE_HPP_20100927 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include + +namespace boost { +namespace network { + +template +struct is_keepalive : mpl::false_ {}; + +template +struct is_keepalive< + Tag, typename enable_if::type> : mpl::true_ {}; + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_SUPPORT_IS_KEEPALIVE_HPP_20100927 */ diff --git a/cpp-netlib/boost/network/support/is_pod.hpp b/cpp-netlib/boost/network/support/is_pod.hpp new file mode 100644 index 00000000..1778f112 --- /dev/null +++ b/cpp-netlib/boost/network/support/is_pod.hpp @@ -0,0 +1,26 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_POD_HPP_20101120 +#define BOOST_NETWORK_SUPPORT_IS_POD_HPP_20101120 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include + +namespace boost { +namespace network { + +template +struct is_pod : mpl::false_ {}; + +template +struct is_pod::type> : mpl::true_ {}; + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_SUPPORT_IS_POD_HPP_20101120 */ diff --git a/cpp-netlib/boost/network/support/is_simple.hpp b/cpp-netlib/boost/network/support/is_simple.hpp new file mode 100644 index 00000000..64335317 --- /dev/null +++ b/cpp-netlib/boost/network/support/is_simple.hpp @@ -0,0 +1,26 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_SIMPLE_HPP_20100927 +#define BOOST_NETWORK_SUPPORT_IS_SIMPLE_HPP_20100927 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include + +namespace boost { +namespace network { + +template +struct is_simple : mpl::false_ {}; + +template +struct is_simple< + Tag, typename enable_if::type> : mpl::true_ {}; + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_SUPPORT_IS_SIMPLE_HPP_20100927 */ diff --git a/cpp-netlib/boost/network/support/is_sync.hpp b/cpp-netlib/boost/network/support/is_sync.hpp new file mode 100644 index 00000000..d68d0cc5 --- /dev/null +++ b/cpp-netlib/boost/network/support/is_sync.hpp @@ -0,0 +1,26 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_SYNC_HPP_20100623 +#define BOOST_NETWORK_SUPPORT_IS_SYNC_HPP_20100623 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include + +namespace boost { +namespace network { + +template +struct is_sync : mpl::false_ {}; + +template +struct is_sync::type> : mpl::true_ {}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_SUPPORT_IS_SYNC_HPP_20100623 diff --git a/cpp-netlib/boost/network/support/is_tcp.hpp b/cpp-netlib/boost/network/support/is_tcp.hpp new file mode 100644 index 00000000..3bbc672e --- /dev/null +++ b/cpp-netlib/boost/network/support/is_tcp.hpp @@ -0,0 +1,28 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_TCP_HPP_20100622 +#define BOOST_NETWORK_SUPPORT_IS_TCP_HPP_20100622 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include +#include +#include + +namespace boost { +namespace network { + +template +struct is_tcp : mpl::false_ {}; + +template +struct is_tcp::type> : mpl::true_ {}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_SUPPORT_IS_TCP_HPP_20100622 \ No newline at end of file diff --git a/cpp-netlib/boost/network/support/is_udp.hpp b/cpp-netlib/boost/network/support/is_udp.hpp new file mode 100644 index 00000000..555b9bf8 --- /dev/null +++ b/cpp-netlib/boost/network/support/is_udp.hpp @@ -0,0 +1,29 @@ +#ifndef BOOST_NETWORK_SUPPORT_IS_UDP_HPP_20100622 +#define BOOST_NETWORK_SUPPORT_IS_UDP_HPP_20100622 + +// Copyright 2010 (c) Dean Michael Berris +// 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) + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +template +struct is_udp : mpl::false_ {}; + +template +struct is_udp::type> : mpl::true_ {}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_SUPPORT_IS_UDP_HPP_20100622 diff --git a/cpp-netlib/boost/network/support/pod_or_normal.hpp b/cpp-netlib/boost/network/support/pod_or_normal.hpp new file mode 100644 index 00000000..2d54bbd0 --- /dev/null +++ b/cpp-netlib/boost/network/support/pod_or_normal.hpp @@ -0,0 +1,29 @@ +#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_POD_OR_NORMAL_HPP_20101128 +#define BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_POD_OR_NORMAL_HPP_20101128 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include + +namespace boost { +namespace network { + +template +struct pod_or_normal { + typedef tags::normal type; +}; + +template +struct pod_or_normal< + Tag, typename enable_if::type> : tags::pod {}; + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_PROTOCOL_HTTP_SUPPORT_POD_OR_NORMAL_HPP_20101128 */ diff --git a/cpp-netlib/boost/network/support/sync_only.hpp b/cpp-netlib/boost/network/support/sync_only.hpp new file mode 100644 index 00000000..719737e4 --- /dev/null +++ b/cpp-netlib/boost/network/support/sync_only.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_NETWORK_SUPPORT_SYNC_ONLY_HPP_20100927 +#define BOOST_NETWORK_SUPPORT_SYNC_ONLY_HPP_20100927 + +// Copyright Dean Michael Berris 2010. +// 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) + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +template +struct sync_only + : mpl::inherit_linearly< + typename mpl::replace_if::type, + is_same, + tags::sync>::type, + mpl::inherit > {}; + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_SUPPORT_SYNC_ONLY_HPP_20100927 */ diff --git a/cpp-netlib/boost/network/tags.hpp b/cpp-netlib/boost/network/tags.hpp new file mode 100644 index 00000000..a220fd43 --- /dev/null +++ b/cpp-netlib/boost/network/tags.hpp @@ -0,0 +1,68 @@ +// Copyright Dean Michael Berris 2008, 2009. +// Glyn Matthews 2009 +// 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 BOOST_NETWORK_TAG_INCLUDED_20100808 +#define BOOST_NETWORK_TAG_INCLUDED_20100808 + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace tags { + +struct pod { + typedef mpl::true_::type is_pod; +}; +struct normal { + typedef mpl::true_::type is_normal; +}; +struct async { + typedef mpl::true_::type is_async; +}; +struct tcp { + typedef mpl::true_::type is_tcp; +}; +struct udp { + typedef mpl::true_::type is_udp; +}; +struct sync { + typedef mpl::true_::type is_sync; +}; +struct default_string { + typedef mpl::true_::type is_default_string; +}; +struct default_wstring { + typedef mpl::true_::type is_default_wstring; +}; + +template +struct components; + +// Tag Definition Macro Helper +#ifndef BOOST_NETWORK_DEFINE_TAG +#define BOOST_NETWORK_DEFINE_TAG(name) \ + struct name \ + : mpl::inherit_linearly >::type {}; \ + template <> \ + struct components { \ + typedef name##_tags type; \ + }; +#endif // BOOST_NETWORK_DEFINE_TAG + +typedef default_string default_; + +} // namespace tags + +} // namespace network + +} // namespace boost + +#endif // __BOOST_NETWORK_TAGS_INC__ diff --git a/cpp-netlib/boost/network/traits/char.hpp b/cpp-netlib/boost/network/traits/char.hpp new file mode 100644 index 00000000..70341897 --- /dev/null +++ b/cpp-netlib/boost/network/traits/char.hpp @@ -0,0 +1,37 @@ +// Copyright (c) Dean Michael Berris 2008, 2009. +// 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 BOOST_NETWORK_TRAITS_CHAR_HPP +#define BOOST_NETWORK_TRAITS_CHAR_HPP + +#include +#include + +namespace boost { +namespace network { + +template +struct unsupported_tag; + +template +struct char_ { + typedef unsupported_tag type; +}; + +template +struct char_ >::type> { + typedef char type; +}; + +template +struct char_ >::type> { + typedef wchar_t type; +}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_TRAITS_CHAR_HPP diff --git a/cpp-netlib/boost/network/traits/headers_container.hpp b/cpp-netlib/boost/network/traits/headers_container.hpp new file mode 100644 index 00000000..46f63327 --- /dev/null +++ b/cpp-netlib/boost/network/traits/headers_container.hpp @@ -0,0 +1,33 @@ +// Copyright (c) Glyn Matthews 2009. +// Copyright 2013 Google, Inc. +// Copyright 2013 Dean Michael Berris +// 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 BOOST_NETWORK_TRAITS_HEADERS_CONTAINER_INC +#define BOOST_NETWORK_TRAITS_HEADERS_CONTAINER_INC + +#include +#include +#include + +namespace boost { +namespace network { +namespace impl { + +template +struct headers_container_impl { + typedef std::multimap::type, typename string::type> + type; +}; + +} // namespace impl + +template +struct headers_container : impl::headers_container_impl {}; + +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_TRAITS_HEADERS_CONTAINER_INC__ diff --git a/cpp-netlib/boost/network/traits/istream.hpp b/cpp-netlib/boost/network/traits/istream.hpp new file mode 100644 index 00000000..4a8a0a86 --- /dev/null +++ b/cpp-netlib/boost/network/traits/istream.hpp @@ -0,0 +1,40 @@ + +#ifndef BOOST_NETWORK_TRAITS_ISTREAM_HPP_20100924 +#define BOOST_NETWORK_TRAITS_ISTREAM_HPP_20100924 + +// Copyright 2010 (C) Dean Michael Berris +// 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) + +#include +#include +#include +#include + +namespace boost { +namespace network { + +template +struct unsupported_tag; + +template +struct istream { + typedef unsupported_tag type; +}; + +template +struct istream >::type> { + typedef std::istream type; +}; + +template +struct istream >::type> { + typedef std::wistream type; +}; + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_TRAITS_ISTREAM_HPP_20100924 */ diff --git a/cpp-netlib/boost/network/traits/istringstream.hpp b/cpp-netlib/boost/network/traits/istringstream.hpp new file mode 100644 index 00000000..0f5273a3 --- /dev/null +++ b/cpp-netlib/boost/network/traits/istringstream.hpp @@ -0,0 +1,40 @@ +// Copyright (c) Glyn Matthews 2009. +// Copyright (c) Dean Michael Berris 2009. +// 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 BOOST_NETWORK_TRAITS_ISTRINGSTREAM_INC +#define BOOST_NETWORK_TRAITS_ISTRINGSTREAM_INC + +#include +#include +#include +#include + +namespace boost { +namespace network { + +template +struct unsupported_tag; + +template +struct istringstream { + typedef unsupported_tag type; +}; + +template +struct istringstream >::type> { + typedef std::istringstream type; +}; + +template +struct istringstream >::type> { + typedef std::basic_istringstream type; +}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_TRAITS_ISTRINGSTREAM_INC diff --git a/cpp-netlib/boost/network/traits/ostream_iterator.hpp b/cpp-netlib/boost/network/traits/ostream_iterator.hpp new file mode 100644 index 00000000..9099247d --- /dev/null +++ b/cpp-netlib/boost/network/traits/ostream_iterator.hpp @@ -0,0 +1,34 @@ +#ifndef BOOST_NETWORK_TRAITS_OSTREAM_ITERATOR_HPP_20100815 +#define BOOST_NETWORK_TRAITS_OSTREAM_ITERATOR_HPP_20100815 + +// Copyright 2010 (C) Dean Michael Berris +// 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) + +#include +#include +#include +#include + +namespace boost { +namespace network { + +template +struct unsupported_tag; + +template +struct ostream_iterator; + +template +struct ostream_iterator + : mpl::if_, std::ostream_iterator, + typename mpl::if_, + std::ostream_iterator, + unsupported_tag >::type> {}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_TRAITS_OSTREAM_ITERATOR_HPP_20100815 diff --git a/cpp-netlib/boost/network/traits/ostringstream.hpp b/cpp-netlib/boost/network/traits/ostringstream.hpp new file mode 100644 index 00000000..f6925b2a --- /dev/null +++ b/cpp-netlib/boost/network/traits/ostringstream.hpp @@ -0,0 +1,41 @@ +// Copyright (c) Glyn Matthews 2009. +// Copyright (c) Dean Michael Berris 2009, 2010. +// 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 BOOST_NETWORK_TRAITS_OSTRINGSTREAM_INC +#define BOOST_NETWORK_TRAITS_OSTRINGSTREAM_INC + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { + +template +struct unsupported_tag; + +template +struct ostringstream { + typedef unsupported_tag type; +}; + +template +struct ostringstream >::type> { + typedef std::ostringstream type; +}; + +template +struct ostringstream >::type> { + typedef std::wostringstream type; +}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_TRAITS_OSTRINGSTREAM_INC diff --git a/cpp-netlib/boost/network/traits/string.hpp b/cpp-netlib/boost/network/traits/string.hpp new file mode 100644 index 00000000..6d9a1a03 --- /dev/null +++ b/cpp-netlib/boost/network/traits/string.hpp @@ -0,0 +1,48 @@ +// Copyright (c) Dean Michael Berris 2008, 2009. +// Glyn Matthews 2009. +// 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 BOOST_NETWORK_TRAITS_STRING_INC +#define BOOST_NETWORK_TRAITS_STRING_INC + +#include +#include +#include +#include + +#ifndef BOOST_NETWORK_DEFAULT_STRING +#define BOOST_NETWORK_DEFAULT_STRING std::string +#endif + +#ifndef BOOST_NETWORK_DEFAULT_WSTRING +#define BOOST_NETWORK_DEFAULT_WSTRING std::wstring +#endif + +namespace boost { +namespace network { + +template +struct unsupported_tag; + +template +struct string { + typedef unsupported_tag type; +}; + +template +struct string >::type> { + typedef BOOST_NETWORK_DEFAULT_STRING type; +}; + +template +struct string >::type> { + typedef BOOST_NETWORK_DEFAULT_WSTRING type; +}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_TRAITS_STRING_INC diff --git a/cpp-netlib/boost/network/traits/vector.hpp b/cpp-netlib/boost/network/traits/vector.hpp new file mode 100644 index 00000000..580a5e14 --- /dev/null +++ b/cpp-netlib/boost/network/traits/vector.hpp @@ -0,0 +1,30 @@ +// Copyright (c) Dean Michael Berris 2008, 2009. +// 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 BOOST_NETWORK_TRAITS_VECTOR_HPP +#define BOOST_NETWORK_TRAITS_VECTOR_HPP + +#include +#include + +namespace boost { +namespace network { + +template +struct unsupported_tag; + +template +struct vector { + + template + struct apply : mpl::if_, std::vector, + unsupported_tag > {}; +}; + +} // namespace network + +} // namespace boost + +#endif // BOOST_NETWORK_TRAITS_VECTOR_HPP diff --git a/cpp-netlib/boost/network/uri.hpp b/cpp-netlib/boost/network/uri.hpp new file mode 100644 index 00000000..7d36bec1 --- /dev/null +++ b/cpp-netlib/boost/network/uri.hpp @@ -0,0 +1,11 @@ +#ifndef BOOST_NETWORK_URL_HPP_ +#define BOOST_NETWORK_URL_HPP_ + +// Copyright 2009 Dean Michael Berris. +// 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) + +#include + +#endif diff --git a/cpp-netlib/boost/network/uri/accessors.hpp b/cpp-netlib/boost/network/uri/accessors.hpp new file mode 100644 index 00000000..5248b34d --- /dev/null +++ b/cpp-netlib/boost/network/uri/accessors.hpp @@ -0,0 +1,95 @@ +// Copyright (c) Glyn Matthews 2011. +// 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 __BOOST_NETWORK_URI_URI_ACCESSORS_INC__ +#define __BOOST_NETWORK_URI_URI_ACCESSORS_INC__ + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace uri { +namespace details { +template +struct key_value_sequence : spirit::qi::grammar { + typedef typename Map::key_type key_type; + typedef typename Map::mapped_type mapped_type; + typedef std::pair pair_type; + + key_value_sequence() : key_value_sequence::base_type(query) { + query = pair >> *((spirit::qi::lit(';') | '&') >> pair); + pair = key >> -('=' >> value); + key = + spirit::qi::char_("a-zA-Z_") >> *spirit::qi::char_("-+.~a-zA-Z_0-9/%"); + value = *spirit::qi::char_("-+.~a-zA-Z_0-9/%"); + } + + spirit::qi::rule query; + spirit::qi::rule pair; + spirit::qi::rule key; + spirit::qi::rule value; +}; +} // namespace details + +template +inline Map &query_map(const uri &uri_, Map &map) { + const uri::string_type range = uri_.query(); + details::key_value_sequence parser; + spirit::qi::parse(boost::begin(range), boost::end(range), parser, map); + return map; +} + +inline uri::string_type username(const uri &uri_) { + const uri::string_type user_info = uri_.user_info(); + uri::const_iterator it(boost::begin(user_info)), end(boost::end(user_info)); + for (; it != end; ++it) { + if (*it == ':') { + break; + } + } + return uri::string_type(boost::begin(user_info), it); +} + +inline uri::string_type password(const uri &uri_) { + const uri::string_type user_info = uri_.user_info(); + uri::const_iterator it(boost::begin(user_info)), end(boost::end(user_info)); + for (; it != end; ++it) { + if (*it == ':') { + ++it; + break; + } + } + return uri::string_type(it, boost::end(user_info)); +} + +inline uri::string_type decoded_path(const uri &uri_) { + const uri::string_type path = uri_.path(); + uri::string_type decoded_path; + decode(path, std::back_inserter(decoded_path)); + return decoded_path; +} + +inline uri::string_type decoded_query(const uri &uri_) { + const uri::string_type query = uri_.query(); + uri::string_type decoded_query; + decode(query, std::back_inserter(decoded_query)); + return decoded_query; +} + +inline uri::string_type decoded_fragment(const uri &uri_) { + const uri::string_type fragment = uri_.fragment(); + uri::string_type decoded_fragment; + decode(fragment, std::back_inserter(decoded_fragment)); + return decoded_fragment; +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_URI_ACCESSORS_INC__ diff --git a/cpp-netlib/boost/network/uri/builder.hpp b/cpp-netlib/boost/network/uri/builder.hpp new file mode 100644 index 00000000..878a3c56 --- /dev/null +++ b/cpp-netlib/boost/network/uri/builder.hpp @@ -0,0 +1,151 @@ +// Copyright (c) Glyn Matthews 2012. +// 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 __BOOST_NETWORK_URI_BUILDER_INC__ +#define __BOOST_NETWORK_URI_BUILDER_INC__ + +#include +#include + +namespace boost { +namespace network { +namespace uri { +class builder { + + typedef uri::string_type string_type; + + public: + builder(uri &uri_) : uri_(uri_) {} + + builder &set_scheme(const string_type &scheme) { + uri_.uri_.append(scheme); + if (opaque_schemes::exists(scheme)) { + uri_.uri_.append(":"); + } else { + uri_.uri_.append("://"); + } + uri_.parse(); + return *this; + } + + builder &scheme(const string_type &scheme) { return set_scheme(scheme); } + + builder &set_user_info(const string_type &user_info) { + uri_.uri_.append(user_info); + uri_.uri_.append("@"); + uri_.parse(); + return *this; + } + + builder &user_info(const string_type &user_info) { + return set_user_info(user_info); + } + + builder &set_host(const string_type &host) { + uri_.uri_.append(host); + uri_.parse(); + return *this; + } + + builder &host(const string_type &host) { return set_host(host); } + + builder &set_host(const asio::ip::address &address) { + uri_.uri_.append(address.to_string()); + uri_.parse(); + return *this; + } + + builder &host(const asio::ip::address &host) { return set_host(host); } + + builder &set_host(const asio::ip::address_v4 &address) { + uri_.uri_.append(address.to_string()); + uri_.parse(); + return *this; + } + + builder &host(const asio::ip::address_v4 &host) { return set_host(host); } + + builder &set_host(const asio::ip::address_v6 &address) { + uri_.uri_.append("["); + uri_.uri_.append(address.to_string()); + uri_.uri_.append("]"); + uri_.parse(); + return *this; + } + + builder &host(const asio::ip::address_v6 &host) { return set_host(host); } + + builder &set_port(const string_type &port) { + uri_.uri_.append(":"); + uri_.uri_.append(port); + uri_.parse(); + return *this; + } + + builder &port(const string_type &port) { return set_port(port); } + + builder &port(uint16_t port) { + return set_port(boost::lexical_cast(port)); + } + + builder &set_path(const string_type &path) { + uri_.uri_.append(path); + uri_.parse(); + return *this; + } + + builder &path(const string_type &path) { return set_path(path); } + + builder &encoded_path(const string_type &path) { + string_type encoded_path; + encode(path, std::back_inserter(encoded_path)); + return set_path(encoded_path); + } + + builder &set_query(const string_type &query) { + uri_.uri_.append("?"); + uri_.uri_.append(query); + uri_.parse(); + return *this; + } + + builder &set_query(const string_type &key, const string_type &value) { + if (!uri_.query_range()) { + uri_.uri_.append("?"); + } else { + uri_.uri_.append("&"); + } + uri_.uri_.append(key); + uri_.uri_.append("="); + uri_.uri_.append(value); + uri_.parse(); + return *this; + } + + builder &query(const string_type &query) { return set_query(query); } + + builder &query(const string_type &key, const string_type &value) { + return set_query(key, value); + } + + builder &set_fragment(const string_type &fragment) { + uri_.uri_.append("#"); + uri_.uri_.append(fragment); + uri_.parse(); + return *this; + } + + builder &fragment(const string_type &fragment) { + return set_fragment(fragment); + } + + private: + uri &uri_; +}; +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_BUILDER_INC__ diff --git a/cpp-netlib/boost/network/uri/config.hpp b/cpp-netlib/boost/network/uri/config.hpp new file mode 100644 index 00000000..de6ae447 --- /dev/null +++ b/cpp-netlib/boost/network/uri/config.hpp @@ -0,0 +1,18 @@ +// Copyright (c) Glyn Matthews 2012. +// 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 __BOOST_NETWORK_URI_CONFIG_INC__ +#define __BOOST_NETWORK_URI_CONFIG_INC__ + +#include +#include + +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_URI_DYN_LINK) +#define BOOST_URI_DECL +#else +#define BOOST_URI_DECL +#endif // defined(BOOST_ALL_DYN_LINK) || defined(BOOST_URI_DYN_LINK) + +#endif // __BOOST_NETWORK_URI_CONFIG_INC__ diff --git a/cpp-netlib/boost/network/uri/decode.hpp b/cpp-netlib/boost/network/uri/decode.hpp new file mode 100644 index 00000000..e9e80e98 --- /dev/null +++ b/cpp-netlib/boost/network/uri/decode.hpp @@ -0,0 +1,92 @@ +// Copyright (c) Glyn Matthews 2011. +// 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 __BOOST_NETWORK_URI_DECODE_INC__ +#define __BOOST_NETWORK_URI_DECODE_INC__ + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace uri { +namespace detail { +template +CharT letter_to_hex(CharT in) { + switch (in) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return in - '0'; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + return in + 10 - 'a'; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + return in + 10 - 'A'; + } + return CharT(); +} +} // namespace detail + +template +OutputIterator decode(const InputIterator &in_begin, + const InputIterator &in_end, + const OutputIterator &out_begin) { + typedef typename boost::iterator_value::type value_type; + + InputIterator it = in_begin; + OutputIterator out = out_begin; + while (it != in_end) { + if (*it == '%') { + ++it; + value_type v0 = detail::letter_to_hex(*it); + ++it; + value_type v1 = detail::letter_to_hex(*it); + ++it; + *out++ = 0x10 * v0 + v1; + } else if (*it == '+') { + *out++ = ' '; + ++it; + } else { + *out++ = *it++; + } + } + return out; +} + +template +inline OutputIterator decode(const SinglePassRange &range, + const OutputIterator &out) { + return decode(boost::begin(range), boost::end(range), out); +} + +inline std::string decoded(const std::string &input) { + std::string decoded; + decode(input, std::back_inserter(decoded)); + return decoded; +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_DECODE_INC__ diff --git a/cpp-netlib/boost/network/uri/detail/uri_parts.hpp b/cpp-netlib/boost/network/uri/detail/uri_parts.hpp new file mode 100644 index 00000000..2564f43a --- /dev/null +++ b/cpp-netlib/boost/network/uri/detail/uri_parts.hpp @@ -0,0 +1,87 @@ +// Copyright 2009, 2010, 2011, 2012 Dean Michael Berris, Jeroen Habraken, Glyn +// Matthews. +// 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 BOOST_NETWORK_URL_DETAIL_URL_PARTS_HPP_ +#define BOOST_NETWORK_URL_DETAIL_URL_PARTS_HPP_ + +#include +#include + +namespace boost { +namespace network { +namespace uri { +namespace detail { +template +struct hierarchical_part { + optional > user_info; + optional > host; + optional > port; + optional > path; + + FwdIter begin() const { return boost::begin(user_info); } + + FwdIter end() const { return boost::end(path); } + + void update() { + if (!user_info) { + if (host) { + user_info = iterator_range(boost::begin(host.get()), + boost::begin(host.get())); + } else if (path) { + user_info = iterator_range(boost::begin(path.get()), + boost::begin(path.get())); + } + } + + if (!host) { + host = iterator_range(boost::begin(path.get()), + boost::begin(path.get())); + } + + if (!port) { + port = iterator_range(boost::end(host.get()), + boost::end(host.get())); + } + + if (!path) { + path = iterator_range(boost::end(port.get()), + boost::end(port.get())); + } + } +}; + +template +struct uri_parts { + iterator_range scheme; + hierarchical_part hier_part; + optional > query; + optional > fragment; + + FwdIter begin() const { return boost::begin(scheme); } + + FwdIter end() const { return boost::end(fragment); } + + void update() { + + hier_part.update(); + + if (!query) { + query = iterator_range(boost::end(hier_part.path.get()), + boost::end(hier_part.path.get())); + } + + if (!fragment) { + fragment = iterator_range(boost::end(query.get()), + boost::end(query.get())); + } + } +}; +} // namespace detail +} // namespace uri +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_URL_DETAIL_URL_PARTS_HPP_ diff --git a/cpp-netlib/boost/network/uri/directives.hpp b/cpp-netlib/boost/network/uri/directives.hpp new file mode 100644 index 00000000..caf15de5 --- /dev/null +++ b/cpp-netlib/boost/network/uri/directives.hpp @@ -0,0 +1,39 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_DIRECTIVES_INC__ +#define __BOOST_NETWORK_URI_DIRECTIVES_INC__ + +#include + +namespace boost { +namespace network { +namespace uri { +inline uri &operator<<(uri &uri_, const uri &root_uri) { + if (empty(uri_) && valid(root_uri)) { + uri_.append(boost::begin(root_uri), boost::end(root_uri)); + } + return uri_; +} + +template +inline uri &operator<<(uri &uri_, const Directive &directive) { + directive(uri_); + return uri_; +} +} // namespace uri +} // namespace network +} // namespace boost + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // __BOOST_NETWORK_URI_DIRECTIVES_INC__ diff --git a/cpp-netlib/boost/network/uri/directives/authority.hpp b/cpp-netlib/boost/network/uri/directives/authority.hpp new file mode 100644 index 00000000..2f0bbaef --- /dev/null +++ b/cpp-netlib/boost/network/uri/directives/authority.hpp @@ -0,0 +1,32 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_DIRECTIVES_AUTHORITY_INC__ +#define __BOOST_NETWORK_URI_DIRECTIVES_AUTHORITY_INC__ + +namespace boost { +namespace network { +namespace uri { +struct authority_directive { + + explicit authority_directive(const std::string &authority) + : authority(authority) {} + + template + void operator()(Uri &uri) const { + uri.append(authority); + } + + std::string authority; +}; + +inline authority_directive authority(const std::string &authority) { + return authority_directive(authority); +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_DIRECTIVES_AUTHORITY_INC__ diff --git a/cpp-netlib/boost/network/uri/directives/fragment.hpp b/cpp-netlib/boost/network/uri/directives/fragment.hpp new file mode 100644 index 00000000..6f3291d9 --- /dev/null +++ b/cpp-netlib/boost/network/uri/directives/fragment.hpp @@ -0,0 +1,37 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_DIRECTIVES_FRAGMENT_INC__ +#define __BOOST_NETWORK_URI_DIRECTIVES_FRAGMENT_INC__ + +#include +#include +#include + +namespace boost { +namespace network { +namespace uri { +struct fragment_directive { + + explicit fragment_directive(const std::string &fragment) + : fragment(fragment) {} + + template + void operator()(Uri &uri) const { + uri.append("#"); + uri.append(fragment); + } + + std::string fragment; +}; + +inline fragment_directive fragment(const std::string &fragment) { + return fragment_directive(fragment); +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_DIRECTIVES_FRAGMENT_INC__ diff --git a/cpp-netlib/boost/network/uri/directives/host.hpp b/cpp-netlib/boost/network/uri/directives/host.hpp new file mode 100644 index 00000000..ac1d2ab5 --- /dev/null +++ b/cpp-netlib/boost/network/uri/directives/host.hpp @@ -0,0 +1,34 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_DIRECTIVES_HOST_INC__ +#define __BOOST_NETWORK_URI_DIRECTIVES_HOST_INC__ + +#include +#include + +namespace boost { +namespace network { +namespace uri { +struct host_directive { + + explicit host_directive(const std::string &host) : host(host) {} + + template + void operator()(Uri &uri) const { + uri.append(host); + } + + std::string host; +}; + +inline host_directive host(const std::string &host) { + return host_directive(host); +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_DIRECTIVES_HOST_INC__ diff --git a/cpp-netlib/boost/network/uri/directives/path.hpp b/cpp-netlib/boost/network/uri/directives/path.hpp new file mode 100644 index 00000000..21af8ca2 --- /dev/null +++ b/cpp-netlib/boost/network/uri/directives/path.hpp @@ -0,0 +1,51 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_DIRECTIVES_PATH_INC__ +#define __BOOST_NETWORK_URI_DIRECTIVES_PATH_INC__ + +#include +#include + +namespace boost { +namespace network { +namespace uri { +struct path_directive { + + explicit path_directive(const std::string &path) : path(path) {} + + template + void operator()(Uri &uri) const { + uri.append(path); + } + + std::string path; +}; + +struct encoded_path_directive { + + explicit encoded_path_directive(const std::string &path) : path(path) {} + + void operator()(uri &uri_) const { + std::string encoded_path; + encode(path, std::back_inserter(encoded_path)); + uri_.append(encoded_path); + } + + std::string path; +}; + +inline path_directive path(const std::string &path) { + return path_directive(path); +} + +inline encoded_path_directive encoded_path(const std::string &path) { + return encoded_path_directive(path); +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_DIRECTIVES_PATH_INC__ diff --git a/cpp-netlib/boost/network/uri/directives/port.hpp b/cpp-netlib/boost/network/uri/directives/port.hpp new file mode 100644 index 00000000..181bf6b8 --- /dev/null +++ b/cpp-netlib/boost/network/uri/directives/port.hpp @@ -0,0 +1,44 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_DIRECTIVES_PORT_INC__ +#define __BOOST_NETWORK_URI_DIRECTIVES_PORT_INC__ + +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace uri { +struct port_directive { + + explicit port_directive(const std::string &port) : port(port) {} + + explicit port_directive(boost::uint16_t port) + : port(boost::lexical_cast(port)) {} + + template + void operator()(Uri &uri) const { + uri.append(":"); + uri.append(port); + } + + std::string port; +}; + +inline port_directive port(const std::string &port) { + return port_directive(port); +} + +inline port_directive port(boost::uint16_t port) { + return port_directive(port); +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_DIRECTIVES_PORT_INC__ diff --git a/cpp-netlib/boost/network/uri/directives/query.hpp b/cpp-netlib/boost/network/uri/directives/query.hpp new file mode 100644 index 00000000..07987867 --- /dev/null +++ b/cpp-netlib/boost/network/uri/directives/query.hpp @@ -0,0 +1,63 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_DIRECTIVES_QUERY_INC__ +#define __BOOST_NETWORK_URI_DIRECTIVES_QUERY_INC__ + +#include +#include +#include + +namespace boost { +namespace network { +namespace uri { +struct query_directive { + + explicit query_directive(const std::string &query) : query(query) {} + + template + void operator()(Uri &uri) const { + uri.append("?"); + uri.append(query); + } + + std::string query; +}; + +inline query_directive query(const std::string &query) { + return query_directive(query); +} + +struct query_key_query_directive { + + query_key_query_directive(const std::string &key, const std::string &query) + : key(key), query(query) {} + + template + void operator()(Uri &uri) const { + std::string encoded_key, encoded_query; + if (boost::empty(uri.query())) { + uri.append("?"); + } else { + uri.append("&"); + } + uri.append(key); + uri.append("="); + uri.append(query); + } + + std::string key; + std::string query; +}; + +inline query_key_query_directive query(const std::string &key, + const std::string &query) { + return query_key_query_directive(key, query); +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_DIRECTIVES_QUERY_INC__ diff --git a/cpp-netlib/boost/network/uri/directives/scheme.hpp b/cpp-netlib/boost/network/uri/directives/scheme.hpp new file mode 100644 index 00000000..7787d350 --- /dev/null +++ b/cpp-netlib/boost/network/uri/directives/scheme.hpp @@ -0,0 +1,48 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_DIRECTIVES_SCHEME_INC__ +#define __BOOST_NETWORK_URI_DIRECTIVES_SCHEME_INC__ + +#include +#include +#include + +namespace boost { +namespace network { +namespace uri { +struct scheme_directive { + + explicit scheme_directive(const std::string &scheme) : scheme(scheme) {} + + template + void operator()(Uri &uri) const { + uri.append(scheme); + if (opaque_schemes::exists(scheme)) { + uri.append(":"); + } else { + uri.append("://"); + } + } + + std::string scheme; +}; + +inline scheme_directive scheme(const std::string &scheme) { + return scheme_directive(scheme); +} + +namespace schemes { +inline uri &http(uri &uri_) { return uri_ << scheme("http"); } + +inline uri &https(uri &uri_) { return uri_ << scheme("https"); } + +inline uri &file(uri &uri_) { return uri_ << scheme("file"); } +} // namespace schemes +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_DIRECTIVES_SCHEME_INC__ diff --git a/cpp-netlib/boost/network/uri/directives/user_info.hpp b/cpp-netlib/boost/network/uri/directives/user_info.hpp new file mode 100644 index 00000000..003469ae --- /dev/null +++ b/cpp-netlib/boost/network/uri/directives/user_info.hpp @@ -0,0 +1,36 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_DIRECTIVES_USER_INFO_INC__ +#define __BOOST_NETWORK_URI_DIRECTIVES_USER_INFO_INC__ + +#include +#include + +namespace boost { +namespace network { +namespace uri { +struct user_info_directive { + + explicit user_info_directive(const std::string &user_info) + : user_info(user_info) {} + + template + void operator()(Uri &uri) const { + uri.append(user_info); + uri.append("@"); + } + + std::string user_info; +}; + +inline user_info_directive user_info(const std::string &user_info) { + return user_info_directive(user_info); +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_DIRECTIVES_USER_INFO_INC__ diff --git a/cpp-netlib/boost/network/uri/encode.hpp b/cpp-netlib/boost/network/uri/encode.hpp new file mode 100644 index 00000000..bf6b0768 --- /dev/null +++ b/cpp-netlib/boost/network/uri/encode.hpp @@ -0,0 +1,153 @@ +// Copyright (c) Glyn Matthews 2011. +// 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 __BOOST_NETWORK_URI_ENCODE_INC__ +#define __BOOST_NETWORK_URI_ENCODE_INC__ + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace uri { +namespace detail { +template +inline CharT hex_to_letter(CharT in) { + switch (in) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + return in + '0'; + case 10: + case 11: + case 12: + case 13: + case 14: + default: + return in - 10 + 'A'; + } + return CharT(); +} + +template +void encode_char(CharT in, OutputIterator &out) { + switch (in) { + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case 'h': + case 'H': + case 'i': + case 'I': + case 'j': + case 'J': + case 'k': + case 'K': + case 'l': + case 'L': + case 'm': + case 'M': + case 'n': + case 'N': + case 'o': + case 'O': + case 'p': + case 'P': + case 'q': + case 'Q': + case 'r': + case 'R': + case 's': + case 'S': + case 't': + case 'T': + case 'u': + case 'U': + case 'v': + case 'V': + case 'w': + case 'W': + case 'x': + case 'X': + case 'y': + case 'Y': + case 'z': + case 'Z': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + case '.': + case '_': + case '~': + case '/': + out++ = in; + break; + default: + out++ = '%'; + out++ = hex_to_letter((in >> 4) & 0x0f); + out++ = hex_to_letter(in & 0x0f); + ; + } +} +} // namespace detail + +template +OutputIterator encode(const InputIterator &in_begin, + const InputIterator &in_end, + const OutputIterator &out_begin) { + InputIterator it = in_begin; + OutputIterator out = out_begin; + while (it != in_end) { + detail::encode_char(*it, out); + ++it; + } + return out; +} + +template +inline OutputIterator encode(const SinglePassRange &range, + const OutputIterator &out) { + return encode(boost::begin(range), boost::end(range), out); +} + +inline std::string encoded(const std::string &input) { + std::string encoded; + encode(input, std::back_inserter(encoded)); + return encoded; +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_ENCODE_INC__ diff --git a/cpp-netlib/boost/network/uri/schemes.hpp b/cpp-netlib/boost/network/uri/schemes.hpp new file mode 100644 index 00000000..6aef3726 --- /dev/null +++ b/cpp-netlib/boost/network/uri/schemes.hpp @@ -0,0 +1,29 @@ +// Copyright 2012 Glyn Matthews. +// 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 __BOOST_NETWORK_URI_SCHEMES_INC__ +#define __BOOST_NETWORK_URI_SCHEMES_INC__ + +#include + +namespace boost { +namespace network { +namespace uri { +class hierarchical_schemes { + + public: + static bool exists(const std::string &scheme); +}; + +class opaque_schemes { + + public: + static bool exists(const std::string &scheme); +}; +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_SCHEMES_INC__ diff --git a/cpp-netlib/boost/network/uri/uri.hpp b/cpp-netlib/boost/network/uri/uri.hpp new file mode 100644 index 00000000..d2df2282 --- /dev/null +++ b/cpp-netlib/boost/network/uri/uri.hpp @@ -0,0 +1,375 @@ +// Copyright 2009, 2010, 2011, 2012 Dean Michael Berris, Jeroen Habraken, Glyn +// Matthews. +// 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 __BOOST_NETWORK_URI_INC__ +#define __BOOST_NETWORK_URI_INC__ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace uri { +namespace detail { +bool parse(std::string::const_iterator first, std::string::const_iterator last, + uri_parts &parts); +} // namespace detail + +class BOOST_URI_DECL uri { + + friend class builder; + + public: + typedef std::string string_type; + typedef string_type::value_type value_type; + typedef string_type::const_iterator const_iterator; + typedef boost::iterator_range const_range_type; + + uri() : is_valid_(false) {} + + // uri(const value_type *uri) + // : uri_(uri), is_valid_(false) { + // parse(); + //} + + uri(const string_type &uri) : uri_(uri), is_valid_(false) { parse(); } + + template + uri(const FwdIter &first, const FwdIter &last) + : uri_(first, last), is_valid_(false) { + parse(); + } + + uri(const uri &other) : uri_(other.uri_) { parse(); } + + uri &operator=(const uri &other) { + uri(other).swap(*this); + return *this; + } + + uri &operator=(const string_type &uri_string) { + uri(uri_string).swap(*this); + return *this; + } + + ~uri() {} + + void swap(uri &other) { + boost::swap(uri_, other.uri_); + other.parse(); + boost::swap(is_valid_, other.is_valid_); + } + + const_iterator begin() const { return uri_.begin(); } + + const_iterator end() const { return uri_.end(); } + + const_range_type scheme_range() const { return uri_parts_.scheme; } + + const_range_type user_info_range() const { + return uri_parts_.hier_part.user_info ? uri_parts_.hier_part.user_info.get() + : const_range_type(); + } + + const_range_type host_range() const { + auto result = uri_parts_.hier_part.host ? uri_parts_.hier_part.host.get() + : const_range_type(); + if (result.begin () != result.end ()) + if (result [0] == '[') + result = {result.begin () + 1, result.end () - 1}; + return result; + } + + const_range_type port_range() const { + return uri_parts_.hier_part.port ? uri_parts_.hier_part.port.get() + : const_range_type(); + } + + const_range_type path_range() const { + return uri_parts_.hier_part.path ? uri_parts_.hier_part.path.get() + : const_range_type(); + } + + const_range_type query_range() const { + return uri_parts_.query ? uri_parts_.query.get() : const_range_type(); + } + + const_range_type fragment_range() const { + return uri_parts_.fragment ? uri_parts_.fragment.get() : const_range_type(); + } + + string_type scheme() const { + const_range_type range = scheme_range(); + return range ? string_type(boost::begin(range), boost::end(range)) + : string_type(); + } + + string_type user_info() const { + const_range_type range = user_info_range(); + return range ? string_type(boost::begin(range), boost::end(range)) + : string_type(); + } + + string_type host() const { + const_range_type range = host_range(); + return range ? string_type(boost::begin(range), boost::end(range)) + : string_type(); + } + + string_type port() const { + const_range_type range = port_range(); + return range ? string_type(boost::begin(range), boost::end(range)) + : string_type(); + } + + string_type path() const { + const_range_type range = path_range(); + return range ? string_type(boost::begin(range), boost::end(range)) + : string_type(); + } + + string_type query() const { + const_range_type range = query_range(); + return range ? string_type(boost::begin(range), boost::end(range)) + : string_type(); + } + + string_type fragment() const { + const_range_type range = fragment_range(); + return range ? string_type(boost::begin(range), boost::end(range)) + : string_type(); + } + + string_type string() const { return uri_; } + + bool is_valid() const { return is_valid_; } + + void append(const string_type &data) { + uri_.append(data); + parse(); + } + + template + void append(const FwdIter &first, const FwdIter &last) { + uri_.append(first, last); + parse(); + } + + private: + void parse(); + + string_type uri_; + detail::uri_parts uri_parts_; + bool is_valid_; +}; + +inline void uri::parse() { + const_iterator first(boost::begin(uri_)), last(boost::end(uri_)); + is_valid_ = detail::parse(first, last, uri_parts_); + if (is_valid_) { + if (!uri_parts_.scheme) { + uri_parts_.scheme = + const_range_type(boost::begin(uri_), boost::begin(uri_)); + } + uri_parts_.update(); + } +} + +inline uri::string_type scheme(const uri &uri_) { return uri_.scheme(); } + +inline uri::string_type user_info(const uri &uri_) { return uri_.user_info(); } + +inline uri::string_type host(const uri &uri_) { return uri_.host(); } + +inline uri::string_type port(const uri &uri_) { return uri_.port(); } + +inline boost::optional port_us(const uri &uri_) { + uri::string_type port = uri_.port(); + return (port.empty()) ? boost::optional() + : boost::optional( + boost::lexical_cast(port)); +} + +inline uri::string_type path(const uri &uri_) { return uri_.path(); } + +inline uri::string_type query(const uri &uri_) { return uri_.query(); } + +inline uri::string_type fragment(const uri &uri_) { return uri_.fragment(); } + +inline uri::string_type hierarchical_part(const uri &uri_) { + uri::string_type::const_iterator first, last; + uri::const_range_type user_info = uri_.user_info_range(); + uri::const_range_type host = uri_.host_range(); + uri::const_range_type port = uri_.port_range(); + uri::const_range_type path = uri_.path_range(); + if (user_info) { + first = boost::begin(user_info); + } else { + first = boost::begin(host); + } + if (path) { + last = boost::end(path); + } else if (port) { + last = boost::end(port); + } else { + last = boost::end(host); + } + return uri::string_type(first, last); +} + +inline uri::string_type authority(const uri &uri_) { + uri::string_type::const_iterator first, last; + uri::const_range_type user_info = uri_.user_info_range(); + uri::const_range_type host = uri_.host_range(); + uri::const_range_type port = uri_.port_range(); + if (user_info) { + first = boost::begin(user_info); + } else { + first = boost::begin(host); + } + + if (port) { + last = boost::end(port); + } else { + last = boost::end(host); + } + return uri::string_type(first, last); +} + +inline bool valid(const uri &uri_) { return uri_.is_valid(); } + +inline bool is_absolute(const uri &uri_) { + return uri_.is_valid() && !boost::empty(uri_.scheme_range()); +} + +inline bool is_relative(const uri &uri_) { + return uri_.is_valid() && boost::empty(uri_.scheme_range()); +} + +inline bool is_hierarchical(const uri &uri_) { + return is_absolute(uri_) && hierarchical_schemes::exists(scheme(uri_)); +} + +inline bool is_opaque(const uri &uri_) { + return is_absolute(uri_) && opaque_schemes::exists(scheme(uri_)); +} + +inline bool is_valid(const uri &uri_) { return valid(uri_); } + +inline void swap(uri &lhs, uri &rhs) { lhs.swap(rhs); } + +inline std::size_t hash_value(const uri &uri_) { + std::size_t seed = 0; + for (uri::const_iterator it = begin(uri_); it != end(uri_); ++it) { + hash_combine(seed, *it); + } + return seed; +} + +inline bool operator==(const uri &lhs, const uri &rhs) { + return boost::equal(lhs, rhs); +} + +inline bool operator==(const uri &lhs, const uri::string_type &rhs) { + return boost::equal(lhs, rhs); +} + +inline bool operator==(const uri::string_type &lhs, const uri &rhs) { + return boost::equal(lhs, rhs); +} + +inline bool operator==(const uri &lhs, const uri::value_type *rhs) { + return boost::equal(lhs, boost::as_literal(rhs)); +} + +inline bool operator==(const uri::value_type *lhs, const uri &rhs) { + return boost::equal(boost::as_literal(lhs), rhs); +} + +inline bool operator!=(const uri &lhs, const uri &rhs) { return !(lhs == rhs); } + +inline bool operator<(const uri &lhs, const uri &rhs) { + return lhs.string() < rhs.string(); +} +} // namespace uri +} // namespace network +} // namespace boost + +#include +#include +#include + +namespace boost { +namespace network { +namespace uri { +inline uri from_parts(const uri &base_uri, const uri::string_type &path_, + const uri::string_type &query_, + const uri::string_type &fragment_) { + uri uri_(base_uri); + builder(uri_).path(path_).query(query_).fragment(fragment_); + return uri_; +} + +inline uri from_parts(const uri &base_uri, const uri::string_type &path_, + const uri::string_type &query_) { + uri uri_(base_uri); + builder(uri_).path(path_).query(query_); + return uri_; +} + +inline uri from_parts(const uri &base_uri, const uri::string_type &path_) { + uri uri_(base_uri); + builder(uri_).path(path_); + return uri_; +} + +inline uri from_parts(const uri::string_type &base_uri, + const uri::string_type &path, + const uri::string_type &query, + const uri::string_type &fragment) { + return from_parts(uri(base_uri), path, query, fragment); +} + +inline uri from_parts(const uri::string_type &base_uri, + const uri::string_type &path, + const uri::string_type &query) { + return from_parts(uri(base_uri), path, query); +} + +inline uri from_parts(const uri::string_type &base_uri, + const uri::string_type &path) { + return from_parts(uri(base_uri), path); +} +} // namespace uri +} // namespace network +} // namespace boost + +#include + +namespace boost { +namespace network { +namespace uri { +inline uri from_file(const filesystem::path &path_) { + uri uri_; + builder(uri_).scheme("file").path(path_.string()); + return uri_; +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_INC__ diff --git a/cpp-netlib/boost/network/uri/uri.ipp b/cpp-netlib/boost/network/uri/uri.ipp new file mode 100644 index 00000000..c58bd295 --- /dev/null +++ b/cpp-netlib/boost/network/uri/uri.ipp @@ -0,0 +1,255 @@ +// Copyright 2009, 2010, 2011, 2012 Dean Michael Berris, Jeroen Habraken, Glyn +// Matthews. +// 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) + +#include +#include +#include +#include + +BOOST_FUSION_ADAPT_TPL_STRUCT( + (FwdIter), (boost::network::uri::detail::hierarchical_part)(FwdIter), + (boost::optional >, + user_info)(boost::optional >, + host)(boost::optional >, + port)(boost::optional >, + path)); + +BOOST_FUSION_ADAPT_TPL_STRUCT( + (FwdIter), (boost::network::uri::detail::uri_parts)(FwdIter), + (boost::iterator_range, + scheme)(boost::network::uri::detail::hierarchical_part, + hier_part)(boost::optional >, + query)(boost::optional >, + fragment)); + +namespace boost { +namespace network { +namespace uri { +namespace detail { +namespace qi = boost::spirit::qi; + +template +struct uri_grammar + : qi::grammar()> { + + typedef String string_type; + typedef typename String::const_iterator const_iterator; + + uri_grammar() : uri_grammar::base_type(start, "uri") { + // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + gen_delims %= qi::char_(":/?#[]@"); + // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," + // / ";" / "=" + sub_delims %= qi::char_("!$&'()*+,;="); + // reserved = gen-delims / sub-delims + reserved %= gen_delims | sub_delims; + // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + unreserved %= qi::alnum | qi::char_("-._~"); + // pct-encoded = "%" HEXDIG HEXDIG + pct_encoded %= qi::char_("%") >> qi::repeat(2)[qi::xdigit]; + + // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + pchar %= qi::raw[unreserved | pct_encoded | sub_delims | qi::char_(":@")]; + + // segment = *pchar + segment %= qi::raw[*pchar]; + // segment-nz = 1*pchar + segment_nz %= qi::raw[+pchar]; + // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) + segment_nz_nc %= + qi::raw[+(unreserved | pct_encoded | sub_delims | qi::char_("@"))]; + // path-abempty = *( "/" segment ) + path_abempty %= qi::raw[*(qi::char_("/") >> segment)]; + // path-absolute = "/" [ segment-nz *( "/" segment ) ] + path_absolute %= qi::raw + [qi::char_("/") >> -(segment_nz >> *(qi::char_("/") >> segment))]; + // path-rootless = segment-nz *( "/" segment ) + path_rootless %= qi::raw[segment_nz >> *(qi::char_("/") >> segment)]; + // path-empty = 0 + path_empty %= qi::raw[qi::eps]; + + // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + scheme %= qi::raw[qi::alpha >> *(qi::alnum | qi::char_("+.-"))]; + + // user_info = *( unreserved / pct-encoded / sub-delims / ":" ) + user_info %= + qi::raw[*(unreserved | pct_encoded | sub_delims | qi::char_(":"))]; + + ip_literal %= qi::lit('[') >> (ipv6address | ipvfuture) >> ']'; + + ipvfuture %= + qi::lit('v') >> +qi::xdigit >> '.' >> +(unreserved | sub_delims | ':'); + + ipv6addresses[0] %= qi::repeat(6)[h16 >> ':'] >> ls32; + ipv6addresses[1] %= "::" >> qi::repeat(5)[h16 >> ':'] >> ls32; + ipv6addresses[2] %= -qi::raw[h16] >> "::" >> qi::repeat(4)[h16 >> ':'] + >> ls32; + ipv6addresses[3] %= -qi::raw[h16] >> "::" >> qi::repeat(3)[h16 >> ':'] + >> ls32; + ipv6addresses[4] %= -qi::raw[h16] >> "::" >> qi::repeat(2)[h16 >> ':'] + >> ls32; + ipv6addresses[5] %= -qi::raw[h16] >> "::" >> h16 >> ':' >> ls32; + ipv6addresses[6] %= -qi::raw[h16] >> "::" >> ls32; + ipv6addresses[7] %= -qi::raw[h16] >> "::" >> h16; + ipv6addresses[8] %= -qi::raw[h16] >> "::"; + ipv6addresses[9] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> + "::" >> qi::repeat(3)[h16 >> ':'] >> ls32; + ipv6addresses[10] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> + "::" >> qi::repeat(2)[h16 >> ':'] >> ls32; + ipv6addresses[11] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> + "::" >> h16 >> ':' >> ls32; + ipv6addresses[12] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> + "::" >> ls32; + ipv6addresses[13] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> + "::" >> h16; + ipv6addresses[14] %= -qi::raw[qi::repeat(1)[(h16 >> ':')] >> h16] >> + "::"; + ipv6addresses[15] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> + "::" >> qi::repeat(2)[h16 >> ':'] >> ls32; + ipv6addresses[16] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> + "::" >> h16 >> ':' >> ls32; + ipv6addresses[17] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> + "::" >> ls32; + ipv6addresses[18] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> + "::" >> h16; + ipv6addresses[19] %= -qi::raw[qi::repeat(2)[(h16 >> ':')] >> h16] >> + "::"; + ipv6addresses[20] %= -qi::raw[qi::repeat(3)[(h16 >> ':')] >> h16] >> + "::" >> h16 >> ':' >> ls32; + ipv6addresses[21] %= -qi::raw[qi::repeat(3)[(h16 >> ':')] >> h16] >> + "::" >> ls32; + ipv6addresses[22] %= -qi::raw[qi::repeat(3)[(h16 >> ':')] >> h16] >> + "::" >> h16; + ipv6addresses[23] %= -qi::raw[qi::repeat(3)[(h16 >> ':')] >> h16] >> + "::"; + ipv6addresses[24] %= -qi::raw[qi::repeat(4)[(h16 >> ':')] >> h16] >> + "::" >> ls32; + ipv6addresses[25] %= -qi::raw[qi::repeat(4)[(h16 >> ':')] >> h16] >> + "::" >> h16; + ipv6addresses[26] %= -qi::raw[qi::repeat(4)[(h16 >> ':')] >> h16] >> + "::"; + ipv6addresses[27] %= -qi::raw[qi::repeat(5)[(h16 >> ':')] >> h16] >> + "::" >> h16; + ipv6addresses[28] %= -qi::raw[qi::repeat(5)[(h16 >> ':')] >> h16] >> + "::"; + ipv6addresses[29] %= -qi::raw[qi::repeat(6)[(h16 >> ':')] >> h16] >> + "::"; + + ipv6address %= qi::raw + [ipv6addresses[0] | + ipv6addresses[1] | + ipv6addresses[2] | + ipv6addresses[3] | + ipv6addresses[4] | + ipv6addresses[5] | + ipv6addresses[6] | + ipv6addresses[7] | + ipv6addresses[8] | + ipv6addresses[9] | + ipv6addresses[10] | + ipv6addresses[11] | + ipv6addresses[12] | + ipv6addresses[13] | + ipv6addresses[14] | + ipv6addresses[15] | + ipv6addresses[16] | + ipv6addresses[17] | + ipv6addresses[18] | + ipv6addresses[19] | + ipv6addresses[20] | + ipv6addresses[21] | + ipv6addresses[22] | + ipv6addresses[23] | + ipv6addresses[24] | + ipv6addresses[25] | + ipv6addresses[26] | + ipv6addresses[27] | + ipv6addresses[28] | + ipv6addresses[29]]; + + // ls32 = ( h16 ":" h16 ) / IPv4address + ls32 %= (h16 >> ':' >> h16) | ipv4address; + + // h16 = 1*4HEXDIG + h16 %= qi::repeat(1, 4)[qi::xdigit]; + + // dec-octet = DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 + // DIGIT / "25" %x30-35 + dec_octet %= !(qi::lit('0') >> qi::digit) >> + qi::raw[qi::uint_parser()]; + + // IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet + ipv4address %= + qi::raw[dec_octet >> qi::repeat(3)[qi::lit('.') >> dec_octet]]; + + // reg-name = *( unreserved / pct-encoded / sub-delims ) + reg_name %= qi::raw[*(unreserved | pct_encoded | sub_delims)]; + + // TODO, host = IP-literal / IPv4address / reg-name + host %= qi::raw[ip_literal | ipv4address | reg_name]; + + // port %= qi::ushort_; + port %= qi::raw[*qi::digit]; + + // query = *( pchar / "/" / "?" ) + query %= qi::raw[*(pchar | qi::char_("/?"))]; + + // fragment = *( pchar / "/" / "?" ) + fragment %= qi::raw[*(pchar | qi::char_("/?"))]; + + // hier-part = "//" authority path-abempty / path-absolute / + // path-rootless / path-empty + // authority = [ userinfo "@" ] host [ ":" port ] + hier_part %= ((("//" >> user_info >> '@') | "//") >> host >> + -(':' >> port) >> path_abempty) | + (qi::attr(iterator_range()) >> + qi::attr(iterator_range()) >> + qi::attr(iterator_range()) >> + (path_absolute | path_rootless | path_empty)); + + start %= + (scheme >> ':') >> hier_part >> -('?' >> query) >> -('#' >> fragment); + } + + qi::rule::value_type()> gen_delims, + sub_delims, reserved, unreserved; + qi::rule pct_encoded, pchar; + + qi::rule segment, segment_nz, segment_nz_nc; + qi::rule()> path_abempty, + path_absolute, path_rootless, path_empty; + + qi::rule dec_octet, ipv4address, reg_name, + ipv6address, ipvfuture, ip_literal; + + qi::rule ipv6addresses[30]; + + qi::rule h16, ls32; + + qi::rule()> host, port; + + qi::rule()> scheme, user_info, + query, fragment; + + qi::rule()> hier_part; + + // actual uri parser + qi::rule()> start; +}; + +bool parse(std::string::const_iterator first, std::string::const_iterator last, + uri_parts &parts) { + namespace qi = boost::spirit::qi; + static detail::uri_grammar grammar; + bool is_valid = qi::parse(first, last, grammar, parts); + return is_valid && (first == last); +} +} // namespace detail +} // namespace uri +} // namespace network +} // namespace boost diff --git a/cpp-netlib/boost/network/uri/uri_io.hpp b/cpp-netlib/boost/network/uri/uri_io.hpp new file mode 100644 index 00000000..5b7b22bc --- /dev/null +++ b/cpp-netlib/boost/network/uri/uri_io.hpp @@ -0,0 +1,22 @@ +// Copyright (c) Glyn Matthews 2011, 2012. +// 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 __BOOST_NETWORK_URI_URI_IO_INC__ +#define __BOOST_NETWORK_URI_URI_IO_INC__ + +#include + +namespace boost { +namespace network { +namespace uri { + +inline std::ostream &operator<<(std::ostream &os, const uri &uri_) { + return os << uri_.string(); +} +} // namespace uri +} // namespace network +} // namespace boost + +#endif // __BOOST_NETWORK_URI_URI_IO_INC__ diff --git a/cpp-netlib/boost/network/utils/base64/encode-io.hpp b/cpp-netlib/boost/network/utils/base64/encode-io.hpp new file mode 100644 index 00000000..704cc5af --- /dev/null +++ b/cpp-netlib/boost/network/utils/base64/encode-io.hpp @@ -0,0 +1,270 @@ +#ifndef BOOST_NETWORK_UTILS_BASE64_ENCODE_IO_HPP +#define BOOST_NETWORK_UTILS_BASE64_ENCODE_IO_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace utils { + +// Offers an interface to the BASE64 converter from encode.hpp, which is +// based on stream manipulators to be friendly to the usage with output +// streams combining heterogenous output by using the output operators. +// The encoding state is serialized to long and maintained in te +// extensible +// internal array of the output stream. +// +// Summarized interface - ostream manipulators and one function: +// +// encode(InputIterator begin, InputIterator end) +// encode(InputRange const & value) +// encode(char const * value) +// encode_rest +// clear_state +// bool empty_state(std::basic_ostream & output) + +namespace base64 { +namespace io { + +// force using the ostream_iterator from boost::archive to write wide +// characters reliably, althoth wchar_t may not be a native character +// type +using namespace boost::archive::iterators; + +namespace detail { + +// Enables transferring of the input sequence for the BASE64 +// encoding into +// the ostream operator defined for it, which performs the +// operation. It +// is to be used from ostream manipulators. +// +// std::basic_ostream & output = ...; +// output << input_wrapper(value.begin(), +// value.end()); +template +struct input_wrapper { + input_wrapper(InputIterator begin, InputIterator end) + : begin(begin), end(end) {} + + private: + InputIterator begin, end; + + // only encoding of an input sequence needs access to it + template + friend std::basic_ostream &operator<<( + std::basic_ostream &output, + input_wrapper input_wrapper); +}; + +// The output stream state should be used only in a single scope +// around +// encoding operations. Constructor performs initialization from +// the +// output stream internal extensible array and destructor updates it +// according to the encoding result. It inherits from the +// base64::state +// to gain access to its protected members and allow easy value +// passing +// to base64::encode. +// +// +// std::basic_ostream & output = ...; +// { +// state rest(output); +// base64::encode(..., ostream_iterator(output), rest); +// } +template +struct state : public boost::network::utils::base64::state { + typedef boost::network::utils::base64::state super_t; + + // initialize the (inherited) contents of the base64::state<> from + // the + // output stream internal extensible array + state(std::basic_ostream &output) : super_t(), output(output) { + const unsigned triplet_index_size = sizeof(super_t::triplet_index) * 8; + unsigned long data = static_cast(storage()); + // mask the long value with the bit-size of the triplet_index + // member + super_t::triplet_index = data & ((1 << triplet_index_size) - 1); + // shift the long value right to remove the the triplet_index + // value; + // masking is not necessary because the last_encoded_value it is + // the + // last record stored in the data value + super_t::last_encoded_value = data >> triplet_index_size; + } + + // update the value in the output stream internal extensible array + // by + // the last (inherited) contents of the base64::state<> + ~state() { + const unsigned triplet_index_size = sizeof(super_t::triplet_index) * 8; + // store the last_encoded_value in the data value first + unsigned long data = + static_cast(super_t::last_encoded_value); + // shift the long data value left to make place for storing the + // full triplet_index value there + data <<= triplet_index_size; + data |= static_cast(super_t::triplet_index); + storage() = static_cast(data); + } + + private: + // all data of the base64::state<> must be serializable into a + // long + // value allocated in the output stream internal extensible array + BOOST_STATIC_ASSERT(sizeof(super_t) <= sizeof(long)); + + // allow only the construction with an output stream (strict RAII) + state(); + state(state const &); + + std::basic_ostream &output; + + long &storage() { + static int index = std::ios_base::xalloc(); + return output.iword(index); + } +}; + +// Output operator implementing the BASE64 encoding for an input +// sequence +// which was wrapped by the ostream manipulator; the state must be +// preserved +// because multiple sequences can be sent in the ouptut by this +// operator. +template +std::basic_ostream &operator<<(std::basic_ostream &output, + input_wrapper input) { + typedef typename iterator_value::type value_type; + state rest(output); + base64::encode(input.begin, input.end, ostream_iterator(output), rest); + return output; +} + +} // namespace detail + +// Encoding ostream manipulator for sequences specified by the pair of +// begin +// and end iterators. +// +// std::vector buffer = ...; +// std::basic_ostream & output = ...; +// output << base64::io::encode(buffer.begin(), buffer.end()) << ... +// << +// base64::io::encode_rest; +template +detail::input_wrapper encode(InputIterator begin, + InputIterator end) { + return detail::input_wrapper(begin, end); +} + +// Encoding ostream manipulator processing whole sequences which +// either +// support begin() and end() methods returning boundaries of the +// sequence +// or the boundaries can be computed by the Boost::Range. +// +// Warning: Buffers identified by C-pointers are processed including +// their +// termination character, if they have any. This is unexpected at +// least +// for the storing literals, which have a specialization here to avoid +// it. +// +// std::vector buffer = ...; +// std::basic_ostream & output = ...; +// output << base64::io::encode(buffer) << ... << +// base64::io::encode_rest; +template +detail::input_wrapper::type> +encode(InputRange const &value) { + typedef typename boost::range_const_iterator::type InputIterator; + return detail::input_wrapper(boost::begin(value), + boost::end(value)); +} + +// Encoding ostream manipulator processing string literals; the usual +// expectation from their encoding is processing only the string +// content +// without the terminating zero character. +// +// std::basic_ostream & output = ...; +// output << base64::io::encode("ab") << ... << +// base64::io::encode_rest; +inline detail::input_wrapper encode(char const *value) { + return detail::input_wrapper(value, value + strlen(value)); +} + +// Encoding ostream manipulator which finishes encoding of the +// previously +// processed chunks. If their total byte-length was divisible by +// three, +// nothing is needed, if not, the last quantum will be encoded as if +// padded +// with zeroes, which will be indicated by appending '=' characters to +// the +// output. This manipulator must be always used at the end of +// encoding, +// after previous usages of the encode manipulator. +// +// std::basic_ostream & output = ...; +// output << base64::io::encode("ab") << ... << +// base64::io::encode_rest; +template +std::basic_ostream &encode_rest(std::basic_ostream &output) { + detail::state rest(output); + base64::encode_rest(ostream_iterator(output), rest); + return output; +} + +// Clears the encoding state in the internal array of the output +// stream. +// Use it to re-use a state object in an unknown state only; Encoding +// of +// the last chunk must be followed by encode_rest otherwise the end of +// the +// input sequence may be missing in the encoded output. The +// encode_rest +// ensures that the rest of the input sequence will be encoded +// corectly and +// the '=' padding applied as necessary. The encode rest clears the +// state +// when finished. +// +// std::basic_ostream & output = ...; +// output << base64::io::encode("ab") << ...; +// output << clear_state; +template +std::basic_ostream &clear_state(std::basic_ostream &output) { + detail::state rest(output); + rest.clear(); + return output; +} + +// Checks if the encoding state in the internal array of the output +// stream +// is empty. +// +// std::basic_ostream & output = ...; +// output << base64::io::encode("ab") << ...; +// bool is_complete = base64::io::empty_state(output); +template +bool empty_state(std::basic_ostream &output) { + detail::state rest(output); + return rest.empty(); +} + +} // namespace io +} // namespace base64 + +} // namespace utils +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_UTILS_BASE64_ENCODE_IO_HPP diff --git a/cpp-netlib/boost/network/utils/base64/encode.hpp b/cpp-netlib/boost/network/utils/base64/encode.hpp new file mode 100644 index 00000000..f7f98a5f --- /dev/null +++ b/cpp-netlib/boost/network/utils/base64/encode.hpp @@ -0,0 +1,418 @@ +#ifndef BOOST_NETWORK_UTILS_BASE64_ENCODE_HPP +#define BOOST_NETWORK_UTILS_BASE64_ENCODE_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace utils { + +// Implements a BASE64 converter working on an iterator range. +// If the input sequence does not end at the three-byte boundary, the last +// encoded value part is remembered in an encoding state to be able to +// continue with the next chunk; the BASE64 encoding processes the input +// by byte-triplets. +// +// Summarized interface: +// +// struct state { +// bool empty () const; +// void clear(); +// } +// +// OutputIterator encode(InputIterator begin, InputIterator end, +// OutputIterator output, State & rest) +// OutputIterator encode_rest(OutputIterator output, State & rest) +// OutputIterator encode(InputRange const & input, OutputIterator output, +// State & rest) +// OutputIterator encode(char const * value, OutputIterator output, +// state & rest) +// std::basic_string encode(InputRange const & value, State & rest) +// std::basic_string encode(char const * value, state & rest) +// +// OutputIterator encode(InputIterator begin, InputIterator end, +// OutputIterator output) +// OutputIterator encode(InputRange const & input, OutputIterator output) +// OutputIterator encode(char const * value, OutputIterator output) +// std::basic_string encode(InputRange const & value) +// std::basic_string encode(char const * value) { +// +// See also http://libb64.sourceforge.net, which served as inspiration. +// See also http://tools.ietf.org/html/rfc4648 for the specification. + +namespace base64 { + +namespace detail { + +// Picks a character from the output alphabet for another 6-bit value +// from the input sequence to encode. +template +char encode_value(Value value) { + static char const encoding[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + "+/"; + return encoding[static_cast(value)]; +} + +} // namespace detail + +// Stores the state after processing the last chunk by the encoder. If +// the +// chunk byte-length is not divisible by three, the last (incomplete) +// value +// quantum canot be encoded right away; it has to wait for the next +// chunk +// of octets which will be processed joined (as if the trailing rest +// from +// the previous one was at its beinning). +template +struct state { + state() : triplet_index(0), last_encoded_value(0) {} + + state(state const& source) + : triplet_index(source.triplet_index), + last_encoded_value(source.last_encoded_value) {} + + bool empty() const { return triplet_index == 0; } + + void clear() { + // indicate that no rest has been left in the last encoded value + // and no padding is needed for the encoded output + triplet_index = 0; + // the last encoded value, which may have been left from the last + // encoding step, must be zeroed too; it is important before the + // next encoding begins, because it works as a cyclic buffer and + // must start empty - with zero + last_encoded_value = 0; + } + + protected: + // number of the octet in the incomplete quantum, which has been + // processed the last time; 0 means that the previous quantum was + // complete 3 octets, 1 that just one octet was avalable and 2 that + // two octets were available + unsigned char triplet_index; + // the value made of the previously shifted and or-ed octets which + // was not completely split to 6-bit codes, because the last quantum + // did not stop on the boundary of three octets + Value last_encoded_value; + + // encoding of an input chunk needs to read and update the state + template + friend OutputIterator encode(InputIterator begin, InputIterator end, + OutputIterator output, State& rest); + + // finishing the encoding needs to read and clear the state + template + friend OutputIterator encode_rest(OutputIterator output, State& rest); +}; + +// Encodes an input sequence to BASE64 writing it to the output iterator +// and stopping if the last input tree-octet quantum was not complete, +// in +// which case it stores the state for the later continuation, when +// another +// input chunk is ready for the encoding. The encoding must be finished +// by calling the encode_rest after processing the last chunk. +// +// std::vector buffer = ...; +// std::basic_string result; +// std::back_insert_iterator > appender(result); +// base64::state rest; +// base64::encode(buffer.begin(), buffer.end(), appender, rest); +// ... +// base64::encode_rest(appender, rest); +template +OutputIterator encode(InputIterator begin, InputIterator end, + OutputIterator output, State& rest) { + typedef typename iterator_value::type value_type; + // continue with the rest of the last chunk - 2 or 4 bits which + // are already shifted to the left and need to be or-ed with the + // continuing data up to the target 6 bits + value_type encoded_value = rest.last_encoded_value; + // if the previous chunk stopped at encoding the first (1) or the + // second + // (2) octet of the three-byte quantum, jump to the right place, + // otherwise start the loop with an empty encoded value buffer + switch (rest.triplet_index) { + // this loop processes the input sequence of bit-octets by bits, + // shifting the current_value (used as a cyclic buffer) left and + // or-ing next bits there, while pulling the bit-sextets from the + // high word of the current_value + for (value_type current_value;;) { + case 0: + // if the input sequence is empty or reached its end at the + // 3-byte boundary, finish with an empty encoding state + if (begin == end) { + rest.triplet_index = 0; + // the last encoded value is not interesting - it would not + // be used, because processing of the next chunk will start + // at the 3-byte boundary + rest.last_encoded_value = 0; + return output; + } + // read the first octet from the current triplet + current_value = *begin++; + // use just the upper 6 bits to encode it to the target alphabet + encoded_value = (current_value & 0xfc) >> 2; + *output++ = detail::encode_value(encoded_value); + // shift the remaining two bits up to make place for the upoming + // part of the next octet + encoded_value = (current_value & 0x03) << 4; + case 1: + // if the input sequence reached its end after the first octet + // from the quantum triplet, store the encoding state and finish + if (begin == end) { + rest.triplet_index = 1; + rest.last_encoded_value = encoded_value; + return output; + } + // read the second first octet from the current triplet + current_value = *begin++; + // combine the upper four bits (as the lower part) with the + // previous two bits to encode it to the target alphabet + encoded_value |= (current_value & 0xf0) >> 4; + *output++ = detail::encode_value(encoded_value); + // shift the remaining four bits up to make place for the + // upoming + // part of the next octet + encoded_value = (current_value & 0x0f) << 2; + case 2: + // if the input sequence reached its end after the second octet + // from the quantum triplet, store the encoding state and finish + if (begin == end) { + rest.triplet_index = 2; + rest.last_encoded_value = encoded_value; + return output; + } + // read the third octet from the current triplet + current_value = *begin++; + // combine the upper two bits (as the lower part) with the + // previous four bits to encode it to the target alphabet + encoded_value |= (current_value & 0xc0) >> 6; + *output++ = detail::encode_value(encoded_value); + // encode the remaining 6 bits to the target alphabet + encoded_value = current_value & 0x3f; + *output++ = detail::encode_value(encoded_value); + } + } + return output; +} + +// Finishes encoding of the previously processed chunks. If their total +// byte-length was divisible by three, nothing is needed, if not, the +// last +// quantum will be encoded as if padded with zeroes, which will be +// indicated +// by appending '=' characters to the output. This method must be +// always +// used at the end of encoding, if the previous chunks were encoded by +// the +// method overload accepting the encoding state. +// +// std::vector buffer = ...; +// std::basic_string result; +// std::back_insert_iterator > appender(result); +// base64::state rest; +// base64::encode(buffer.begin(), buffer.end(), appender, rest); +// ... +// base64::encode_rest(appender, rest); +template +OutputIterator encode_rest(OutputIterator output, State& rest) { + if (!rest.empty()) { + // process the last part of the trailing octet (either 4 or 2 bits) + // as if the input was padded with zeros - without or-ing the next + // input value to it; it has been already shifted to the left + *output++ = detail::encode_value(rest.last_encoded_value); + // at least one padding '=' will be always needed - at least two + // bits are missing in the finally encoded 6-bit value + *output++ = '='; + // if the last octet was the first in the triplet (the index was + // 1), four bits are missing in the finally encoded 6-bit value; + // another '=' character is needed for the another two bits + if (rest.triplet_index < 2) *output++ = '='; + // clear the state all the time to make sure that another call to + // the encode_rest would not cause damage; the last encoded value, + // which may have been left there, must be zeroed too; it is + // important before the next encoding begins, because it works as + // a cyclic buffer and must start empty - with zero + rest.clear(); + } + return output; +} + +// Encodes a part of an input sequence specified by the pair of begin +// and +// end iterators.to BASE64 writing it to the output iterator. If its +// total +// byte-length was not divisible by three, the output will be padded by +// the +// '=' characters. If you encode an input consisting of mutiple chunks, +// use the method overload maintaining the encoding state. +// +// std::vector buffer = ...; +// std::basic_string result; +// base64::encode(buffer.begin(), buffer.end(), +// std::back_inserter(result)); +template +OutputIterator encode(InputIterator begin, InputIterator end, + OutputIterator output) { + state::type> rest; + output = encode(begin, end, output, rest); + return encode_rest(output, rest); +} + +// Encodes an entire input sequence to BASE64, which either supports +// begin() +// and end() methods returning boundaries of the sequence or the +// boundaries +// can be computed by the Boost::Range, writing it to the output +// iterator +// and stopping if the last input tree-octet quantum was not complete, +// in +// which case it stores the state for the later continuation, when +// another +// input chunk is ready for the encoding. The encoding must be finished +// by calling the encode_rest after processing the last chunk. +// +// Warning: Buffers identified by C-pointers are processed including +// their +// termination character, if they have any. This is unexpected at least +// for the storing literals, which have a specialization here to avoid +// it. +// +// std::vector buffer = ...; +// std::basic_string result; +// std::back_insert_iterator > appender(result); +// base64::state rest; +// base64::encode(buffer, appender, rest); +// ... +// base64::encode_rest(appender, rest); +template +OutputIterator encode(InputRange const& input, OutputIterator output, + State& rest) { + return encode(boost::begin(input), boost::end(input), output, rest); +} + +// Encodes an entire string literal to BASE64, writing it to the output +// iterator and stopping if the last input tree-octet quantum was not +// complete, in which case it stores the state for the later +// continuation, +// when another input chunk is ready for the encoding. The encoding +// must +// be finished by calling the encode_rest after processing the last +// chunk. +// +// The string literal is encoded without processing its terminating zero +// character, which is the usual expectation. +// +// std::basic_string result; +// std::back_insert_iterator > appender(result); +// base64::state rest; +// base64::encode("ab", appender, rest); +// ... +// base64::encode_rest(appender, rest); +template +OutputIterator encode(char const* value, OutputIterator output, + state& rest) { + return encode(value, value + strlen(value), output, rest); +} + +// Encodes an entire input sequence to BASE64 writing it to the output +// iterator, which either supports begin() and end() methods returning +// boundaries of the sequence or the boundaries can be computed by the +// Boost::Range. If its total byte-length was not divisible by three, +// the output will be padded by the '=' characters. If you encode an +// input consisting of mutiple chunks, use the method overload +// maintaining +// the encoding state. +// +// Warning: Buffers identified by C-pointers are processed including +// their +// termination character, if they have any. This is unexpected at least +// for the storing literals, which have a specialization here to avoid +// it. +// +// std::vector buffer = ...; +// std::basic_string result; +// base64::encode(buffer, std::back_inserter(result)); +template +OutputIterator encode(InputRange const& value, OutputIterator output) { + return encode(boost::begin(value), boost::end(value), output); +} + +// Encodes an entire string literal to BASE64 writing it to the output +// iterator. If its total length (without the trailing zero) was not +// divisible by three, the output will be padded by the '=' characters. +// If you encode an input consisting of mutiple chunks, use the method +// overload maintaining the encoding state. +// +// The string literal is encoded without processing its terminating zero +// character, which is the usual expectation. +// +// std::basic_string result; +// base64::encode("ab", std::back_inserter(result)); +template +OutputIterator encode(char const* value, OutputIterator output) { + return encode(value, value + strlen(value), output); +} + +// Encodes an entire input sequence to BASE64 returning the result as +// string, which either supports begin() and end() methods returning +// boundaries of the sequence or the boundaries can be computed by the +// Boost::Range. If its total byte-length was not divisible by three, +// the output will be padded by the '=' characters. If you encode an +// input consisting of mutiple chunks, use other method maintaining +// the encoding state writing to an output iterator. +// +// Warning: Buffers identified by C-pointers are processed including +// their +// termination character, if they have any. This is unexpected at least +// for the storing literals, which have a specialization here to avoid +// it. +// +// std::vector buffer = ...; +// std::basic_string result = base64::encode(buffer); +template +std::basic_string encode(InputRange const& value) { + std::basic_string result; + encode(value, std::back_inserter(result)); + return result; +} + +// Encodes an entire string literal to BASE64 returning the result as +// string. If its total byte-length was not divisible by three, the +// output will be padded by the '=' characters. If you encode an +// input consisting of mutiple chunks, use other method maintaining +// the encoding state writing to an output iterator. +// +// The string literal is encoded without processing its terminating zero +// character, which is the usual expectation. +// +// std::basic_string result = base64::encode("ab"); +template +std::basic_string encode(char const* value) { + std::basic_string result; + encode(value, std::back_inserter(result)); + return result; +} + +// The function overloads for string literals encode the input without +// the terminating zero, which is usually expected, because the trailing +// zero byte is not considered a part of the string value; the overloads +// for an input range would wrap the string literal by Boost.Range and +// encode the full memory occupated by the string literal - including +// the +// unwanted last zero byte. + +} // namespace base64 + +} // namespace utils +} // namespace network +} // namespace boost + +#endif // BOOST_NETWORK_UTILS_BASE64_ENCODE_HPP diff --git a/cpp-netlib/boost/network/utils/thread_pool.hpp b/cpp-netlib/boost/network/utils/thread_pool.hpp new file mode 100644 index 00000000..3f33cf6f --- /dev/null +++ b/cpp-netlib/boost/network/utils/thread_pool.hpp @@ -0,0 +1,110 @@ +#ifndef BOOST_NETWORK_UTILS_THREAD_POOL_HPP_20101020 +#define BOOST_NETWORK_UTILS_THREAD_POOL_HPP_20101020 + +// Copyright 2010 Dean Michael Berris. +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace network { +namespace utils { + +typedef boost::shared_ptr io_service_ptr; +typedef boost::shared_ptr worker_threads_ptr; +typedef boost::shared_ptr sentinel_ptr; + +template +struct basic_thread_pool { + basic_thread_pool(std::size_t threads = 1, + io_service_ptr io_service = io_service_ptr(), + worker_threads_ptr worker_threads = worker_threads_ptr()) + : threads_(threads), + io_service_(io_service), + worker_threads_(worker_threads), + sentinel_() { + bool commit = false; + BOOST_SCOPE_EXIT_TPL( + (&commit)(&io_service_)(&worker_threads_)(&sentinel_)) { + if (!commit) { + sentinel_.reset(); + io_service_.reset(); + if (worker_threads_.get()) { + worker_threads_->interrupt_all(); + worker_threads_->join_all(); + } + worker_threads_.reset(); + } + } + BOOST_SCOPE_EXIT_END + + if (!io_service_.get()) { + io_service_.reset(new boost::asio::io_service); + } + + if (!worker_threads_.get()) { + worker_threads_.reset(new boost::thread_group); + } + + if (!sentinel_.get()) { + sentinel_.reset(new boost::asio::io_service::work(*io_service_)); + } + + for (std::size_t counter = 0; counter < threads_; ++counter) + worker_threads_->create_thread( + boost::bind(&boost::asio::io_service::run, io_service_)); + + commit = true; + } + + std::size_t thread_count() const { return threads_; } + + void post(boost::function f) { io_service_->post(f); } + + ~basic_thread_pool() throw() { + sentinel_.reset(); + try { + worker_threads_->join_all(); + } + catch (...) { + BOOST_ASSERT(false && + "A handler was not supposed to throw, but one did."); + } + } + + void swap(basic_thread_pool &other) { + std::swap(other.threads_, threads_); + std::swap(other.io_service_, io_service_); + std::swap(other.worker_threads_, worker_threads_); + std::swap(other.sentinel_, sentinel_); + } + + protected: + std::size_t threads_; + io_service_ptr io_service_; + worker_threads_ptr worker_threads_; + sentinel_ptr sentinel_; + + private: + basic_thread_pool(basic_thread_pool const &); // no copies please + basic_thread_pool &operator=(basic_thread_pool); // no assignment + // please +}; + +typedef basic_thread_pool thread_pool; + +} /* utils */ + +} /* network */ + +} /* boost */ + +#endif /* BOOST_NETWORK_UTILS_THREAD_POOL_HPP_20101020 */ diff --git a/cpp-netlib/boost/network/version.hpp b/cpp-netlib/boost/network/version.hpp new file mode 100644 index 00000000..14d6770f --- /dev/null +++ b/cpp-netlib/boost/network/version.hpp @@ -0,0 +1,22 @@ +#ifndef BOOST_NETWORK_VERSION_HPP_20091214 +#define BOOST_NETWORK_VERSION_HPP_20091214 + +// Copyright 2009, 2013 Dean Michael Berris +// Copyright Glyn Matthews 2010. +// 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) + +#include + +#define BOOST_NETLIB_VERSION_MAJOR 0 +#define BOOST_NETLIB_VERSION_MINOR 11 +#define BOOST_NETLIB_VERSION_INCREMENT 2 + +#ifndef BOOST_NETLIB_VERSION +#define BOOST_NETLIB_VERSION \ + BOOST_STRINGIZE(BOOST_NETLIB_VERSION_MAJOR) "." BOOST_STRINGIZE( \ + BOOST_NETLIB_VERSION_MINOR) "." BOOST_STRINGIZE(BOOST_NETLIB_VERSION_INCREMENT) +#endif // BOOST_NETLIB_VERSION + +#endif // BOOST_NETWORK_VERSION_HPP_20091214 diff --git a/cpp-netlib/cppnetlibConfig.cmake.in b/cpp-netlib/cppnetlibConfig.cmake.in new file mode 100644 index 00000000..952a5f63 --- /dev/null +++ b/cpp-netlib/cppnetlibConfig.cmake.in @@ -0,0 +1,24 @@ +# - Config file for the cppnetlib package +# It defines the following variables +# CPPNETLIB_INCLUDE_DIRS - include directories for cppnetlib +# CPPNETLIB_LIBRARIES - libraries to link against +# CPPNETLIB_EXECUTABLE - the bar executable + +# Compute paths +get_filename_component(CPPNETLIB_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +set(CPPNETLIB_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@") + +# Our library dependencies (contains definitions for IMPORTED targets) +if( NOT TARGET cppnetlib-client-connections + AND NOT TARGET cppnetlib-server-parsers + AND NOT TARGET cppnetlib-uri + AND NOT CPPNETLIB_BINARY_DIR) + include("${CPPNETLIB_CMAKE_DIR}/cppnetlibTargets.cmake") +endif() + +# These are IMPORTED targets created by cppnetlibTargets.cmake +set(CPPNETLIB_LIBRARIES + cppnetlib-client-connections + cppnetlib-server-parsers + cppnetlib-uri) +#set(CPPNETLIB_EXECUTABLE ...) # maybe the examples? diff --git a/cpp-netlib/cppnetlibConfigVersion.cmake.in b/cpp-netlib/cppnetlibConfigVersion.cmake.in new file mode 100644 index 00000000..e459ca32 --- /dev/null +++ b/cpp-netlib/cppnetlibConfigVersion.cmake.in @@ -0,0 +1,11 @@ +set(PACKAGE_VERSION "@CPPNETLIB_VERSION_STRING@") + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() \ No newline at end of file diff --git a/cpp-netlib/index.html b/cpp-netlib/index.html new file mode 100644 index 00000000..2cac53c9 --- /dev/null +++ b/cpp-netlib/index.html @@ -0,0 +1,25 @@ + + + + + + + + + + + + Automatic redirection failed, please go to index.html. + + + + diff --git a/cpp-netlib/libs/mime/To-Do.txt b/cpp-netlib/libs/mime/To-Do.txt new file mode 100644 index 00000000..690daeaf --- /dev/null +++ b/cpp-netlib/libs/mime/To-Do.txt @@ -0,0 +1,16 @@ +To Do list for Boost.Mime: + +General: +* Finish the test suites +** Compare results to python parser +** Try to parse some bad mime inputs +--> Added 0019-NoBoundary test +* Integrate into cpp-netlib +* Write some docs + +Specific: +* Rename make_mime into something better. Parse, Encode? +--> Changed the name to 'parse_mime', and made the stream and iterator versions use the same name +* Start using boost::exception +* Look into making the parsing restartable +* Figure out how to \ No newline at end of file diff --git a/cpp-netlib/libs/mime/doc/mime.qbk b/cpp-netlib/libs/mime/doc/mime.qbk new file mode 100644 index 00000000..b51bf064 --- /dev/null +++ b/cpp-netlib/libs/mime/doc/mime.qbk @@ -0,0 +1,58 @@ +[/ + (C) Copyright 2010 Marshall Clow + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt). +] + +[article C++ Mime Library + [quickbook 1.4] + [version 0.5] + [authors [Clow, Marshall]] + [copyright 2010 Marshall Clow] + [purpose C++ library for MIME parsing, manipulation and printing] + [category text] + [license + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + [@http://www.boost.org/LICENSE_1_0.txt]) + ] +] + + +[def __boost__ [@http://www.boost.org/ the Boost C++ Libraries]] +[def __boost_org__ [@http://www.boost.org/]] +[def __boost_asio__ [@http://www.boost.org/libs/asio/index.html Boost.Asio]] +[def __boost_system__ [@http://www.boost.org/libs/system/index.html Boost.System]] +[def __boost_type_traits__ [@http://www.boost.org/libs/type_traits/index.html Boost.TypeTraits]] +[def __boost_doc__ [@http://www.boost.org/doc/libs/]] +[def __pion__ [@http://www.pion.org/projects/pion-network-library the Pion Network Library]] +[def __cnl__ C++ Network Library] +[def __message__ `basic_message`] +[def __uri__ `basic_uri`] +[def __python__ [@http://www.python.org Python]] +[def __libcurl__ [@http://curl.haxx.se/ libcurl]] +[def __mozilla_netlib__ [@http://www.mozilla.org/projects/netlib/ mozilla-netlib]] +[def __sf_cpp_netlib__ [@http://sourceforge.net/projects/cpp-netlib/ sourceforge]] +[def __github__ [@http://github.com/mikhailberis/cpp-netlib github]] +[def __default_constructible__ [@http://www.boost.org/doc/html/DefaultConstructible.html DefaultConstructible]] +[def __copy_constructible__ [@http://www.boost.org/doc/html/CopyConstructible.html CopyConstructible]] +[def __assignable__ [@http://www.boost.org/doc/html/Assignable.html Assignable]] +[def __equality_comparable__ [@http://www.boost.org/doc/html/Assignable.html Assignable]] + + +[def __quick_start__ quick start] + + +[include quick_start.qbk] +#[include intro.qbk] +#[include using.qbk] +#[/include architecture.qbk] +#[include message.qbk] +#[include uri.qbk] +#[include protocol.qbk] +#[include examples.qbk] +#[include reference.qbk] +#[include acknowledgements.qbk] +#[include appendices.qbk] +#[include contributors.qbk] diff --git a/cpp-netlib/libs/mime/doc/quick_start.qbk b/cpp-netlib/libs/mime/doc/quick_start.qbk new file mode 100644 index 00000000..2ed1ec7a --- /dev/null +++ b/cpp-netlib/libs/mime/doc/quick_start.qbk @@ -0,0 +1,11 @@ +[/ + (C) Copyright 2010 Marshall Clow + 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). +] + + +[section:quick_start Quick Start] + +[endsect] [/ quick_start] diff --git a/cpp-netlib/libs/mime/example/basic_parsing.cpp b/cpp-netlib/libs/mime/example/basic_parsing.cpp new file mode 100644 index 00000000..bdf7a029 --- /dev/null +++ b/cpp-netlib/libs/mime/example/basic_parsing.cpp @@ -0,0 +1,127 @@ +// +// Copyright Marshall Clow 2009-2010 +// 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) +// +// + +#include + +#include +#include +#include +#include + +struct my_traits { + typedef std::string string_type; + // typedef std::pair < std::string, string_type > header_type; + typedef std::string body_type; +}; + +// typedef boost::mime::mime_part<> mime_part; +typedef boost::mime::basic_mime mime_part; + +template +void DumpContainer(std::ostream &out, const std::string &prefix, + const Container &c) { + out << prefix << ' '; + if (c.size() < 10) { + for (typename Container::const_iterator iter = c.begin(); iter != c.end(); + ++iter) + out << (int)*iter << ' '; + } else { + for (int i = 0; i < 5; i++) out << int(c.begin()[i]) << ' '; + out << "... "; + for (int i = 0; i < 5; i++) out << int(c.rbegin()[i]) << ' '; + } + out << std::endl; +} + +void DumpStructure(std::ostream &out, const char *title, const mime_part &mp, + std::string prefix) { + std::string content_type = mp.get_content_type(); + if (NULL != title) out << prefix << "Data from: " << title << std::endl; + out << prefix << "Content-Type: " << content_type << std::endl; + out << prefix << "There are " + << std::distance(mp.header_begin(), mp.header_end()) << " headers" + << std::endl; + size_t subpart_count = std::distance(mp.subpart_begin(), mp.subpart_end()); + switch (mp.get_part_kind()) { + case mime_part::simple_part: + if (subpart_count != 0) + out << str(boost::format("%s ### %d subparts on a simple (%s) type!") % + prefix % subpart_count % content_type) << std::endl; + out << prefix << "The body is " << mp.body_size() << " bytes long" + << std::endl; + DumpContainer(out, prefix, *mp.body()); + break; + + case mime_part::multi_part: + break; + + case mime_part::message_part: + if (boost::iequals(content_type, "message/delivery-status")) + out << prefix << "The body is " << mp.body_size() << " bytes long" + << std::endl; + else if (1 != subpart_count) + out << str(boost::format("%s ### %d subparts on a message (%s) type!") % + subpart_count % prefix % content_type) << std::endl; + break; + } + + if (subpart_count != 0) { + out << prefix << "There are " + << std::distance(mp.subpart_begin(), mp.subpart_end()) << " sub parts" + << std::endl; + for (mime_part::constPartIter iter = mp.subpart_begin(); + iter != mp.subpart_end(); ++iter) + DumpStructure(out, NULL, **iter, prefix + " "); + } +} + +int main(int argc, char *argv[]) { + + if (argc == 1) + std::cerr << "Usage: basic_parsing " << std::endl; + + for (int i = 1; i < argc; ++i) { + boost::shared_ptr rmp; + try { + std::ifstream in(argv[i]); + if (!in) { + std::cerr << "Can't open file " << argv[i] << std::endl; + continue; + } + + in >> std::noskipws; + std::cout << "**********************************" << std::endl; + rmp = mime_part::parse_mime(in); + } + catch (const boost::mime::mime_parsing_error &err) { + std::cout << "Caught an error parsing '" << argv[i] << "'" << std::endl; + std::cout << " " << err.what() << std::endl; + continue; + } + catch (const boost::exception &berr) { + std::cout << "Caught an boost error parsing '" << argv[i] << "'" + << std::endl; + // std::cout << " " << berr.what () << std::endl; + continue; + } + + try { + DumpStructure(std::cout, argv[i], *rmp, std::string()); + // std::ofstream out ( (std::string ( argv[i] ) + "-Results").c_str (), + // std::ios::binary ); + // out << rmp; + } + catch (const std::runtime_error &err) { + std::cout << "Caught an error writing '" << argv[i] << "'" << std::endl; + std::cout << " " << err.what() << std::endl; + continue; + } + } + + return 0; +} diff --git a/cpp-netlib/libs/mime/example/basic_usage.cpp b/cpp-netlib/libs/mime/example/basic_usage.cpp new file mode 100644 index 00000000..b90e3ff4 --- /dev/null +++ b/cpp-netlib/libs/mime/example/basic_usage.cpp @@ -0,0 +1,70 @@ +// +// Copyright Marshall Clow 2009-2010 +// 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) +// +// + +#include + +#include +#include +#include +#include + +struct my_traits { + typedef std::string string_type; + // typedef std::pair < std::string, string_type > header_type; + typedef std::string body_type; +}; + +typedef boost::mime::basic_mime mime_part; + +int main(int argc, char* argv[]) { + + // (1) a really simple part + mime_part mp("text", "plain"); + mp.set_body("Hello World\n", 12); + std::cout << mp; + + // Three trips around the house before we go through the door. + // Make a part, copy it onto the heap, and wrap it into a shared pointer. + std::cout << "*******" << std::endl; + std::string str("Hi Mom!\n"); + boost::shared_ptr mp0(new mime_part( + mime_part::make_simple_part("text", "html", str.begin(), str.end()))); + std::cout << mp0; + + std::cout << "*******" << std::endl; + boost::shared_ptr mp1(new mime_part("text", "plain")); + mp1->set_body("This is a test.....\n", 20); + mp1->append_phrase_to_content_type("charset", "usascii"); + std::cout << mp1; + + // Build a multipart + mime_part mp2("multipart", "multiple"); + mp2.set_body("This is the body of a multipart\n", 32); + mp2.append_part(mp0); + mp2.append_part(mp1); + + // stream it out to a string, then make a new part from the string + std::ostringstream os1, os2; + os1 << mp2; + std::istringstream is(os1.str()); + is >> std::noskipws; + boost::shared_ptr strmp = mime_part::parse_mime(is); + os2 << strmp; + if (os1.str() == os2.str()) + std::cout << "Strings match!!" << std::endl; + else { + // Write the differences out to files for examination + std::cout << "##Strings differ!!" << std::endl; + std::ofstream t1("test1.out", std::ios::binary); + t1 << os1.str(); + std::ofstream t2("test2.out", std::ios::binary); + t2 << os2.str(); + } + + return 0; +} diff --git a/cpp-netlib/libs/mime/test/CMakeLists.txt b/cpp-netlib/libs/mime/test/CMakeLists.txt new file mode 100644 index 00000000..f81f8a39 --- /dev/null +++ b/cpp-netlib/libs/mime/test/CMakeLists.txt @@ -0,0 +1,16 @@ +include_directories(${CPP-NETLIB_SOURCE_DIR}) +file ( COPY TestMessages DESTINATION ${CMAKE_CURRENT_BINARY_DIR} ) + +#This test causes a "too many sections" error on Windows MinGW64 +#(MSVC has /bigobj, MinGW does not) +if (NOT(${CMAKE_CXX_COMPILER_ID} MATCHES GNU AND ${CMAKE_SYSTEM_NAME} MATCHES "Windows")) + if ( Boost_FOUND ) + add_executable ( mime-roundtrip mime-roundtrip.cpp ) + target_link_libraries ( mime-roundtrip ${Boost_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT}) + set_target_properties( mime-roundtrip + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CPP-NETLIB_BINARY_DIR}/tests) + add_test ( mime-roundtrip ${CPP-NETLIB_BINARY_DIR}/tests/mime-roundtrip ) + endif () +endif() + diff --git a/cpp-netlib/libs/mime/test/TestMessages/.gitattributes b/cpp-netlib/libs/mime/test/TestMessages/.gitattributes new file mode 100644 index 00000000..2bdd027c --- /dev/null +++ b/cpp-netlib/libs/mime/test/TestMessages/.gitattributes @@ -0,0 +1 @@ +* -crlf diff --git a/cpp-netlib/libs/mime/test/TestMessages/00000001 b/cpp-netlib/libs/mime/test/TestMessages/00000001 new file mode 100644 index 00000000..b6c9dd6c --- /dev/null +++ b/cpp-netlib/libs/mime/test/TestMessages/00000001 @@ -0,0 +1,40 @@ +Resent-To: mail.app@flagg2.qualcomm.com +Resent-From: win-eudora-bugs@flagg2.qualcomm.com +Resent-Message-Id: +Resent-Date: Mon, 1 Nov 2004 15:38:13 -0800 +Received: from flagg2.qualcomm.com [129.46.154.229] + by localhost with IMAP (fetchmail-6.2.5) + for marshall@localhost (single-drop); Tue, 02 Nov 2004 11:38:25 -0800 (PST) +Received: from snape.qualcomm.com (unverified [129.46.132.184]) (using TLSv1 with Cipher RC4(128), Exch RSA_SIGN(1024), Hash MD5(128)) by flagg2.qualcomm.com + (Rockliffe SMTPRA 6.1.16) with ESMTP id for ; + Mon, 1 Nov 2004 15:38:13 -0800 +Received: from sabrina.qualcomm.com (sabrina.qualcomm.com [129.46.61.150]) + by snape.qualcomm.com (8.12.10/8.12.3/1.0) with ESMTP id iA1NcAcH015308 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); + Mon, 1 Nov 2004 15:38:11 -0800 (PST) +Received: from moria.qualcomm.com (qualcomm.com [199.106.114.68]) + by sabrina.qualcomm.com (8.12.10/8.12.5/1.0) with ESMTP id iA1Nc8HJ019370 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) + for ; Mon, 1 Nov 2004 15:38:09 -0800 (PST) +Received: from isengard.qualcomm.com (isengard.qualcomm.com [199.106.114.75]) by moria.qualcomm.com (qualnet-external) with ESMTP id iA1Nc7Rg028808 for ; Mon, 1 Nov 2004 15:38:07 -0800 (PST) +Received: from coyote.rain.org (coyote.rain.org [198.68.144.2]) by isengard.qualcomm.com with ESMTP id iA1Nc7uA020987 for ; Mon, 1 Nov 2004 15:38:07 -0800 (PST) +Received: from sanders.rain.org (maxmp-189.rain.org [198.68.144.189]) + by coyote.rain.org (Postfix) with ESMTP id 648227775 + for ; Mon, 1 Nov 2004 15:38:06 -0800 (PST) +Message-Id: <5.0.2.1.2.20041101153017.00a26ec0@rain.org> +X-Sender: maia3@rain.org +X-Mailer: QUALCOMM Windows Eudora Version 5.0.2 +Date: Mon, 01 Nov 2004 15:31:46 -0800 +To: win-eudora6-bugs@qualcomm.com +From: Maia +Subject: New Bugs +Mime-Version: 1.0 +Content-Type: text/plain; charset="us-ascii"; format=flowed +X-PMX-Version: 4.6.0.97784, Antispam-Core: 4.6.0.97340, Antispam-Data: 2004.11.1.3 + +Just now, without any reason, an email of mine was turned into a mixture of +text and directions and numbers and letters and is now unusable. Do you +know why this is happening? + Thanks, Maia + + diff --git a/cpp-netlib/libs/mime/test/TestMessages/00000019 b/cpp-netlib/libs/mime/test/TestMessages/00000019 new file mode 100644 index 00000000..47961876 --- /dev/null +++ b/cpp-netlib/libs/mime/test/TestMessages/00000019 @@ -0,0 +1,81 @@ +Resent-To: mail.app@flagg2.qualcomm.com +Resent-From: win-eudora-bugs@flagg2.qualcomm.com +Resent-Message-Id: +Resent-Date: Mon, 1 Nov 2004 16:01:16 -0800 +Received: from flagg2.qualcomm.com [129.46.154.229] + by localhost with IMAP (fetchmail-6.2.5) + for marshall@localhost (single-drop); Tue, 02 Nov 2004 11:38:27 -0800 (PST) +Received: from snape.qualcomm.com (unverified [129.46.132.184]) (using TLSv1 with Cipher RC4(128), Exch RSA_SIGN(1024), Hash MD5(128)) by flagg2.qualcomm.com + (Rockliffe SMTPRA 6.1.16) with ESMTP id for ; + Mon, 1 Nov 2004 16:01:16 -0800 +Received: from neophyte.qualcomm.com (neophyte.qualcomm.com [129.46.61.149]) + by snape.qualcomm.com (8.12.10/8.12.3/1.0) with ESMTP id iA201FcH022189 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); + Mon, 1 Nov 2004 16:01:15 -0800 (PST) +Received: from hobbiton.qualcomm.com (hobbiton.qualcomm.com [199.106.114.69]) + by neophyte.qualcomm.com (8.12.10/8.12.5/1.0) with ESMTP id iA201D9A029029 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) + for ; Mon, 1 Nov 2004 16:01:13 -0800 (PST) +Received: from isengard.qualcomm.com (isengard.qualcomm.com [199.106.114.75]) by hobbiton.qualcomm.com (qualnet-external) with ESMTP id iA201BhJ016885 for ; Mon, 1 Nov 2004 16:01:12 -0800 (PST) +Received: from localhost (localhost) by isengard.qualcomm.com id iA201CuA023535; Mon, 1 Nov 2004 16:01:12 -0800 (PST) +Date: Mon, 1 Nov 2004 16:01:12 -0800 (PST) +From: Mail Delivery Subsystem +Message-Id: <200411020001.iA201CuA023535@isengard.qualcomm.com> +To: +MIME-Version: 1.0 +Content-Type: multipart/report; report-type=delivery-status; + boundary="iA201CuA023535.1099353672/isengard.qualcomm.com" +Subject: Returned mail: see transcript for details +Auto-Submitted: auto-generated (failure) +X-PMX-Version: 4.6.0.99824, Antispam-Core: 4.6.0.97340, Antispam-Data: 2004.11.1.3 + +This is a MIME-encapsulated message + +--iA201CuA023535.1099353672/isengard.qualcomm.com + +The original message was received at Mon, 1 Nov 2004 16:01:09 -0800 (PST) +from [210.193.18.250] + + ----- The following addresses had permanent fatal errors ----- + + (reason: 550 5.6.1 Prohibited attachment type) + + ----- Transcript of session follows ----- +... while talking to hobbiton.qualcomm.com.: +>>> DATA +<<< 550 5.6.1 Prohibited attachment type +554 5.0.0 Service unavailable + +--iA201CuA023535.1099353672/isengard.qualcomm.com +Content-Type: message/delivery-status + +Reporting-MTA: dns; isengard.qualcomm.com +Received-From-MTA: DNS; [210.193.18.250] +Arrival-Date: Mon, 1 Nov 2004 16:01:09 -0800 (PST) + +Final-Recipient: RFC822; win-eudora6-bugs@eudora.com +Action: failed +Status: 5.6.1 +Remote-MTA: DNS; hobbiton.qualcomm.com +Diagnostic-Code: SMTP; 550 5.6.1 Prohibited attachment type +Last-Attempt-Date: Mon, 1 Nov 2004 16:01:12 -0800 (PST) + +--iA201CuA023535.1099353672/isengard.qualcomm.com +Content-Type: text/rfc822-headers + +Return-Path: +Received: from eudora.com ([210.193.18.250]) by isengard.qualcomm.com with ESMTP id iA2018uA023523 for ; Mon, 1 Nov 2004 16:01:09 -0800 (PST) +Message-Id: <200411020001.iA2018uA023523@isengard.qualcomm.com> +From: win-eudora6-bugs@eudora.com +To: win-eudora6-bugs@eudora.com +Subject: Re: Excel file +Date: Tue, 2 Nov 2004 08:00:34 +0800 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_NextPart_000_0001_00000AE6.000070CC" +X-Priority: 3 +X-MSMail-Priority: Normal + +--iA201CuA023535.1099353672/isengard.qualcomm.com-- + + diff --git a/cpp-netlib/libs/mime/test/TestMessages/00000431 b/cpp-netlib/libs/mime/test/TestMessages/00000431 new file mode 100644 index 00000000..7559066c --- /dev/null +++ b/cpp-netlib/libs/mime/test/TestMessages/00000431 @@ -0,0 +1,140 @@ +Marshall-Sez: This message has nested multiparts; with the last part of a + multipart being another multipart +Resent-To: mail.app@flagg2.qualcomm.com +Resent-From: eudora-suggest@flagg2.qualcomm.com +Resent-Message-Id: +Resent-Date: Mon, 1 Nov 2004 22:33:29 -0800 +Received: from flagg2.qualcomm.com [129.46.154.229] + by localhost with IMAP (fetchmail-6.2.5) + for marshall@localhost (single-drop); Tue, 02 Nov 2004 11:39:31 -0800 (PST) +Received: from snape.qualcomm.com (unverified [129.46.132.184]) (using TLSv1 with Cipher RC4(128), Exch RSA_SIGN(1024), Hash MD5(128)) by flagg2.qualcomm.com + (Rockliffe SMTPRA 6.1.16) with ESMTP id for ; + Mon, 1 Nov 2004 22:33:29 -0800 +Received: from sabrina.qualcomm.com (sabrina.qualcomm.com [129.46.61.150]) + by snape.qualcomm.com (8.12.10/8.12.3/1.0) with ESMTP id iA26XQcH013328 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) + for ; Mon, 1 Nov 2004 22:33:26 -0800 (PST) +Received: from moria.qualcomm.com (qualcomm.com [199.106.114.68]) + by sabrina.qualcomm.com (8.12.10/8.12.5/1.0) with ESMTP id iA26XNHJ013973 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) + for ; Mon, 1 Nov 2004 22:33:24 -0800 (PST) +Received: from isengard.qualcomm.com (isengard.qualcomm.com [199.106.114.75]) by moria.qualcomm.com (qualnet-external) with ESMTP id iA26XMha015651 for ; Mon, 1 Nov 2004 22:33:22 -0800 (PST) +Received: from d60-65-159-220.col.wideopenwest.com (d60-65-159-220.col.wideopenwest.com [65.60.220.159]) by isengard.qualcomm.com with ESMTP id iA26XFuA029259 for ; Mon, 1 Nov 2004 22:33:16 -0800 (PST) +Received: from lopezclub.com (lopezclub-com.mr.outblaze.com [205.158.62.177]) + by d60-65-159-220.col.wideopenwest.com with esmtp + id 1F1D2A4AC2 for ; Tue, 02 Nov 2004 00:35:33 -0600 +Message-ID: <010001c4c0a6$2e00ef5b$f3fa62fd@lopezclub.com> +From: "Coarsest A. Spading" +To: Eudora +Subject: =?windows-1251?B?zeUg5OD+8iDv8O717uTgIOru4uDr5fD7Pw==?= +Date: Tue, 02 Nov 2004 00:35:33 -0600 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_NextPart_000_0036_D092C96B.3CE29AF1" +X-Priority: 3 +X-MSMail-Priority: Normal +X-Mailer: Microsoft Outlook Express 6.00.2800.1106 +X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 +X-RAV-Antivirus: This e-mail has been scanned for viruses on host: d60-65-159-220.col.wideopenwest.com +X-PMX-Version: 4.6.0.97784, Antispam-Core: 4.6.0.97340, Antispam-Data: 2004.11.1.6 +X-PerlMx-Spam: Gauge=XXXXXXXXXIIIIII, Probability=96%, Report='MR_OUTBLAZE 5, IMGSPAM_BODY 3.2, RCVD_IN_CBL 3, __SANE_MSGID 0, __TO_MALFORMED_2 0, __MIME_VERSION 0, __NEXTPART_NORMAL 0, __NEXTPART_ALL 0, __CT 0, __CTYPE_HAS_BOUNDARY 0, __CTYPE_MULTIPART 0, __HAS_X_PRIORITY 0, __HAS_MSMAIL_PRI 0, __OUTLOOK_MUA_1 0, __HAS_X_MAILER 0, SUBJ_FULL_OF_8BITS 0, __HIGHBITS 0, __IMGSPAM_BODY 0, __TAG_EXISTS_BODY 0, __TAG_EXISTS_META 0, __TAG_EXISTS_HTML 0, HTML_FONT_COLOR_BLUE 0, __TAG_EXISTS_HEAD 0, __IMGSPAM_BODY_1 0, HTML_90_100 0, __HAS_MSGID 0, __OUTLOOK_MUA 0, IMGSPAM_BODY_1 0, __OUTLOOK_MSGID_1 0' +X-Maybe-Spam: X-Maybe-Spam + +This is a multi-part message in MIME format. + +------=_NextPart_000_0036_D092C96B.3CE29AF1 +Content-Type: multipart/related; + type="multipart/alternative"; + boundary="----=_NextPart_001_0037_D092C96B.3CE29AF1" + +------=_NextPart_001_0037_D092C96B.3CE29AF1 +Content-Type: image/gif; + name="ani.gif" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="ani.gif" +Content-ID: + +R0lGODlh/ABLAMQAAP///wAAgAAA/wAAADMzmRERiEREoVVVqoiIw+7u9szM5SIikLu73d3d +7qqq1GZmsnd3u5mZzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +ACH5BAAAAAAALAAAAAD8AEsAAAX/ICCOZGmeaKqubOu+cCzPdG2LCUQEQXEwt6BwyIoYCrzk +gsgcGpHJwJLIIzmg0cCjye3GGossjwD0mltgcYDMrOKQi3IigkSc73jAooBQ5P8re313bgAP +UiYKiICMQg4Bfo2SI4+RhAEjYQ4nhSJGSQeWIp0ApJ2kB1VqSSOopIkHcHYlCQ9IPg0kBwQA +DDtrsyQKqWIsDbY9D7mjq5gqw7Imx7fKury+Y8EknzyhJYVXzswjCgYnirwjv1ll4ySm4qXx +iqrNrfOsKY9Z6SINWEk2iSDw4FCWAst62VOxL0oBgc3imWiYpB8AijweqisoBiGJdVHaycOR +zx2KBAiQ/7RDsGZZgx0W4X2L12ndTE7xbJ7kASEBAAU7gtXxeayHz1Jh2ABoYGARgB0Pjpo8 +kQDJAZ8JUhWQOjVFAp4+gQaYVTXAVQBZjY5KWoapU5YEXMJ85yxCgAg3cWYUGSYh2lMSZd6j +FKBpYIkmHxlOAcGssEUstQFoDIHZlI93u45kXLhE08p0WzQ+8HhKY3MkPls2sQOvngB+v9J0 +RuDyYL1j/OIMzfu2yTD08goH/kodpBRNTXxNx0MgCQZrRCAxUdy4SIUWN6/YIarEjuvQmQdw +PiK8CsB/JWtHwUCr7gQMEBxB33uqG5akBefFv144bjWaudMYAaJUF6B+5yFW3/9t1ZECn3xQ +hBbLbizwJwIDYRTjW1foleUTgoN52N+CMy3UoDiGaYhCcSCuqOCGDL5YCIYA3tMchT8ZwBVv +0EkBQQQKyLYgglUcMkuLIxkZ4JJMipAcjksBZOCI/U0Jo3+3PUmdMz0u8GOQ6B1C3m9auCiC +Jv6BCJgiBcDIIiQ9XGlcd5hdV8IhdiqWWplNfleCeSSewF0Kfj4XnSEB5NnZa2PSV6hv+4yJ +KGn9sTQbloA15RySPGgqpwiNbTHCV6YtWt6ij2T3mmsA2BXTi6Ca6mQAoH1aQqgkkBoraiOo +dtGhJIThGimW8sbmdjwgcNQwPCwThqi1JCGVmrM5VaX/gkoEStJYIohFFhIG5MKAQQk1pRQ2 +FiHh15RlnZXWVljuxO1PQb1hFlZaSWVuGehmwme0PEwrziG1ogBSEhp5IgYEYbQTUY3yHOcm +tjwUCOuv/FihxpgH95AQwfGWgNGNIZ8wskUjj+ddRwnZlQXDiW6IhMATpUiAetgUBgR0vD6s +YqeYUsxrkz8Rs4B6tUDxwwkI/LKAqN3GWTIJ0ySzI9HCGK1e1QVExbTTUJf3iwE7m9oJSz1f +nIeVk7Tt9ttwu8B23HTXbTcjc9+t995835B334AHLviWgxdu+OGIJ6744ow37vjjkEcu+eSU +Bz7A5Zg3PgAAm+stwOefnyBA/wmggw5A6aafjvoIpUfe+QivJ5655ySMXvvpKNhuuwm7izB6 +770zHjvnlccdPPC488567qQr//jwnb8u/ewiUM/55SdIDzv22XNfvffaY8499cMnb37ovrO+ ++/rN37588OnH7/zy7d/+O/18iw/+97BX37//xAMgCbQXwAL+L4AEjB4BC1g+/K2Pfb6DoPnk +Jz8JUhB16Dve/NRXQcBBD4D7Y+D/FnjA8plQBdHjnwBJqLz76Q5394OhDOvXQQpOEH4RbB0N +HYi/vX2QeJtL4PZmx8Lrkc96AhwgEYFYQvGpwIXJg+ILobhD3WGwhxN0Xxa3WEMu1u2H4xvh +AUtoAv8hJvGMIrzeCsf4RBlOcYZS3GAU66dB0WnRi+fD4t3AmMI0prGIZvQeGRGowDUaMgUW +TKQeb2jD9MEPh4xspBYtqDf9LTCIlhyiEht4ySB2L3bY66MfjchGHpqyiw9MHRcxGDpW2vB3 +q8uj+tDnuB8W75a4LGMJGvg4Vvryl8AMpjCHSUxh5vKYyEymMpfJzGY685nQjKY0p0nNalrz +mtjMpja3yc1uevOb4AynOMdJznKa85zoTKc618nOdrrznfCMpzznSc96WlMR5mgAMQ6QELHw +iRlRmBWdijYGh2WBEr8ggKT8sc+E6LMbukHoGJzjAKepx54naAoQANKmn2T/zKMHVcjQopaF +TdAjoACwVBRYRQKOjsClJlBpEvDisigUDKPKQYSFUmGHVIAmFXh5BKVKEIYdpUJULFmCUE1Q +BxGwpKMk2Cm3pKqepqY0Tk1xTXDeuYoU2KUyTYkEPtfTmcicoDEsBYCWRmLWNCEmrFEzB1w9 +OlKyIsYutmFnV1GQCiCgBz2pyJABLAGdoZ4jOoHtVCSaMgu0EW4w9NlTY2VlGI/Ik21Ftata ++WSQp4ghEroilMo65oeXREFVmo3sCExbkRJAoQAD1avaNoOekwb0CK45RD+qkwZR4VYEuo2S +QyL610uV4B/DNUFwLztbN9CnHGu4AlR7Uxzkhu0my4x16qFUNBL6RCG7V0Xt38jJNjfMday0 +6ExTaKYZ5BZsvZA17nclNtbzLoq7VTgCe+PJth3kgqqbBUICPJUKSh2CUsthamZ04ZhJAcCq +SY1pg3l6VUpR2LXzinCBgdtg/hqXwWWAaWNO6w+OHqWwdwIQchHmk5EtFKYPdojJxLCJFWdk +GeP9pmoVBpq0mCUhEIjGag3DzxGgFcMacsuPxVbQkzR0VE8+Qc6UspQoU8meoSVCZnG6zLkK +QRGG5TIy0SsEL4v5zGiOWwgAADs= + +------=_NextPart_001_0037_D092C96B.3CE29AF1 +Content-Type: multipart/alternative; + boundary="----=_NextPart_002_0038_D092C96B.3CE29AF1" + +------=_NextPart_002_0038_D092C96B.3CE29AF1 +Content-Type: text/plain; + charset=windows-1251 +Content-Transfer-Encoding: quoted-printable + +=c2=e4=ee=e1=e0=e2=ee=ea =ea =f0=e0=f1=f1=ea=e0=e7=e0=ec =ee =f1=f2=f0= +=e0=ed=ed=fb=f5 =ef=f0=ee=e8=f1=f8=e5=f1=f2=e2=e8=ff=f5 +------=_NextPart_002_0038_D092C96B.3CE29AF1 +Content-Type: text/html; + charset=windows-1251 +Content-Transfer-Encoding: quoted-printable + + + + + + + + +
+
 
+
 
+
=f1=ee=e2=f0=e5=ec=e5=ed=ed=e0=ff =ed=e0=f3=ea=e0=2e = +=c8=ed=ee=e3=e4=e0 =f2=e0=ea=ee=e9 =ea=eb=fe=f7 =e1=fc=e5=f2 =e8=e7
+ +------=_NextPart_002_0038_D092C96B.3CE29AF1-- + +------=_NextPart_001_0037_D092C96B.3CE29AF1-- + +------=_NextPart_000_0036_D092C96B.3CE29AF1-- + + + diff --git a/cpp-netlib/libs/mime/test/TestMessages/00000975 b/cpp-netlib/libs/mime/test/TestMessages/00000975 new file mode 100644 index 00000000..7b3ef638 --- /dev/null +++ b/cpp-netlib/libs/mime/test/TestMessages/00000975 @@ -0,0 +1,115 @@ +Resent-To: mail.app@flagg2.qualcomm.com +Resent-From: eudora-suggest@flagg2.qualcomm.com +Resent-Message-Id: +Resent-Date: Tue, 2 Nov 2004 08:05:31 -0800 +Received: from flagg2.qualcomm.com [129.46.154.229] + by localhost with IMAP (fetchmail-6.2.5) + for marshall@localhost (single-drop); Tue, 02 Nov 2004 11:40:47 -0800 (PST) +Received: from snape.qualcomm.com (unverified [129.46.132.184]) (using TLSv1 with Cipher RC4(128), Exch RSA_SIGN(1024), Hash MD5(128)) by flagg2.qualcomm.com + (Rockliffe SMTPRA 6.1.16) with ESMTP id for ; + Tue, 2 Nov 2004 08:05:31 -0800 +Received: from neophyte.qualcomm.com (neophyte.qualcomm.com [129.46.61.149]) + by snape.qualcomm.com (8.12.10/8.12.3/1.0) with ESMTP id iA2G5TcH006140 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) + for ; Tue, 2 Nov 2004 08:05:30 -0800 (PST) +Received: from hobbiton.qualcomm.com (hobbiton.qualcomm.com [199.106.114.69]) + by neophyte.qualcomm.com (8.12.10/8.12.5/1.0) with ESMTP id iA2G5R9A004119 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) + for ; Tue, 2 Nov 2004 08:05:28 -0800 (PST) +Received: from mailserver.internal.evanstech.com ([216.235.152.49]) by hobbiton.qualcomm.com (qualnet-external) with ESMTP id iA2G5QBU029487 for ; Tue, 2 Nov 2004 08:05:26 -0800 (PST) +From: postmaster@evanstech.com +To: eudora-suggest@qualcomm.com +Date: Tue, 2 Nov 2004 11:04:00 -0500 +MIME-Version: 1.0 +Content-Type: multipart/report; report-type=delivery-status; + boundary="9B095B5ADSN=_01C4A240558054EB0030F626mailserver.inter" +X-DSNContext: 335a7efd - 4457 - 00000001 - 80040546 +Message-ID: +Subject: Delivery Status Notification (Failure) +X-PMX-Version: 4.6.0.99824, Antispam-Core: 4.6.0.97340, Antispam-Data: 2004.11.1.8 +X-PerlMx-Spam: Gauge=XXXXX, Probability=50%, Report='VBOUNCE 5, __TO_MALFORMED_2 0, __MIME_VERSION 0, __CT 0, __CTYPE_HAS_BOUNDARY 0, __CTYPE_MULTIPART 0, __HAS_MSGID 0, __SANE_MSGID 0, __UNUSABLE_MSGID 0, __VIRUS_MYDOOM_1 0, NO_REAL_NAME 0' + +This is a MIME-formatted message. +Portions of this message may be unreadable without a MIME-capable mail program. + +--9B095B5ADSN=_01C4A240558054EB0030F626mailserver.inter +Content-Type: text/plain; charset=us-ascii +Content-Transfer-Encoding: 7bit + +------------------ Virus Warning Message (on echelon) + +Found virus WORM_SWASH.A in file message.pif (in message.zip) +The uncleanable file is deleted. + +Visit http://qualnet.qualcomm.com/it/virus for more information + +--------------------------------------------------------- + +--9B095B5ADSN=_01C4A240558054EB0030F626mailserver.inter +Content-Type: text/plain; charset=unicode-1-1-utf-7 + +This is an automatically generated Delivery Status Notification. + +Delivery to the following recipients failed. + + john@evanstech.com + + + + +--9B095B5ADSN=_01C4A240558054EB0030F626mailserver.inter +Content-Type: message/delivery-status + +Reporting-MTA: dns;mailserver.internal.evanstech.com +Received-From-MTA: dns;qualcomm.com +Arrival-Date: Tue, 2 Nov 2004 11:03:49 -0500 + +Final-Recipient: rfc822;john@evanstech.com +Action: failed +Status: 5.1.1 + +--9B095B5ADSN=_01C4A240558054EB0030F626mailserver.inter +Content-Type: message/rfc822 + +Received: from qualcomm.com ([80.231.132.37] RDNS failed) by mailserver.internal.evanstech.com with Microsoft SMTPSVC(5.0.2195.6713); + Tue, 2 Nov 2004 11:03:49 -0500 +From: eudora-suggest@qualcomm.com +To: john@evanstech.com +Subject: Status +Date: Tue, 2 Nov 2004 17:03:42 +0100 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_NextPart_000_0007_BF11B844.031F7FC2" +X-Priority: 3 +X-MSMail-Priority: Normal +Return-Path: eudora-suggest@qualcomm.com +Message-ID: +X-OriginalArrivalTime: 02 Nov 2004 16:03:50.0928 (UTC) FILETIME=[8B44D100:01C4C0F5] + +This is a multi-part message in MIME format. + +------=_NextPart_000_0007_BF11B844.031F7FC2 +Content-Type: text/html; + charset="Windows-1252" +Content-Transfer-Encoding: 7bit + +The message cannot be represented in 7-bit ASCII encoding and has been sent as a binary attachment. + + +------=_NextPart_000_0007_BF11B844.031F7FC2 +Content-Type: text/plain; charset=us-ascii +Content-Transfer-Encoding: 7bit + + +------------------ Virus Warning Message (on echelon) + +message.zip is removed from here because it contains a virus. + +--------------------------------------------------------- +------=_NextPart_000_0007_BF11B844.031F7FC2-- + + + + +--9B095B5ADSN=_01C4A240558054EB0030F626mailserver.inter-- + diff --git a/cpp-netlib/libs/mime/test/TestMessages/0019-NoBoundary b/cpp-netlib/libs/mime/test/TestMessages/0019-NoBoundary new file mode 100644 index 00000000..df297920 --- /dev/null +++ b/cpp-netlib/libs/mime/test/TestMessages/0019-NoBoundary @@ -0,0 +1,80 @@ +Resent-To: mail.app@flagg2.qualcomm.com +Resent-From: win-eudora-bugs@flagg2.qualcomm.com +Resent-Message-Id: +Resent-Date: Mon, 1 Nov 2004 16:01:16 -0800 +Received: from flagg2.qualcomm.com [129.46.154.229] + by localhost with IMAP (fetchmail-6.2.5) + for marshall@localhost (single-drop); Tue, 02 Nov 2004 11:38:27 -0800 (PST) +Received: from snape.qualcomm.com (unverified [129.46.132.184]) (using TLSv1 with Cipher RC4(128), Exch RSA_SIGN(1024), Hash MD5(128)) by flagg2.qualcomm.com + (Rockliffe SMTPRA 6.1.16) with ESMTP id for ; + Mon, 1 Nov 2004 16:01:16 -0800 +Received: from neophyte.qualcomm.com (neophyte.qualcomm.com [129.46.61.149]) + by snape.qualcomm.com (8.12.10/8.12.3/1.0) with ESMTP id iA201FcH022189 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); + Mon, 1 Nov 2004 16:01:15 -0800 (PST) +Received: from hobbiton.qualcomm.com (hobbiton.qualcomm.com [199.106.114.69]) + by neophyte.qualcomm.com (8.12.10/8.12.5/1.0) with ESMTP id iA201D9A029029 + (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) + for ; Mon, 1 Nov 2004 16:01:13 -0800 (PST) +Received: from isengard.qualcomm.com (isengard.qualcomm.com [199.106.114.75]) by hobbiton.qualcomm.com (qualnet-external) with ESMTP id iA201BhJ016885 for ; Mon, 1 Nov 2004 16:01:12 -0800 (PST) +Received: from localhost (localhost) by isengard.qualcomm.com id iA201CuA023535; Mon, 1 Nov 2004 16:01:12 -0800 (PST) +Date: Mon, 1 Nov 2004 16:01:12 -0800 (PST) +From: Mail Delivery Subsystem +Message-Id: <200411020001.iA201CuA023535@isengard.qualcomm.com> +To: +MIME-Version: 1.0 +Content-Type: multipart/report; report-type=delivery-status +Subject: Returned mail: see transcript for details +Auto-Submitted: auto-generated (failure) +X-PMX-Version: 4.6.0.99824, Antispam-Core: 4.6.0.97340, Antispam-Data: 2004.11.1.3 + +This is a MIME-encapsulated message + +--iA201CuA023535.1099353672/isengard.qualcomm.com + +The original message was received at Mon, 1 Nov 2004 16:01:09 -0800 (PST) +from [210.193.18.250] + + ----- The following addresses had permanent fatal errors ----- + + (reason: 550 5.6.1 Prohibited attachment type) + + ----- Transcript of session follows ----- +... while talking to hobbiton.qualcomm.com.: +>>> DATA +<<< 550 5.6.1 Prohibited attachment type +554 5.0.0 Service unavailable + +--iA201CuA023535.1099353672/isengard.qualcomm.com +Content-Type: message/delivery-status + +Reporting-MTA: dns; isengard.qualcomm.com +Received-From-MTA: DNS; [210.193.18.250] +Arrival-Date: Mon, 1 Nov 2004 16:01:09 -0800 (PST) + +Final-Recipient: RFC822; win-eudora6-bugs@eudora.com +Action: failed +Status: 5.6.1 +Remote-MTA: DNS; hobbiton.qualcomm.com +Diagnostic-Code: SMTP; 550 5.6.1 Prohibited attachment type +Last-Attempt-Date: Mon, 1 Nov 2004 16:01:12 -0800 (PST) + +--iA201CuA023535.1099353672/isengard.qualcomm.com +Content-Type: text/rfc822-headers + +Return-Path: +Received: from eudora.com ([210.193.18.250]) by isengard.qualcomm.com with ESMTP id iA2018uA023523 for ; Mon, 1 Nov 2004 16:01:09 -0800 (PST) +Message-Id: <200411020001.iA2018uA023523@isengard.qualcomm.com> +From: win-eudora6-bugs@eudora.com +To: win-eudora6-bugs@eudora.com +Subject: Re: Excel file +Date: Tue, 2 Nov 2004 08:00:34 +0800 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_NextPart_000_0001_00000AE6.000070CC" +X-Priority: 3 +X-MSMail-Priority: Normal + +--iA201CuA023535.1099353672/isengard.qualcomm.com-- + + diff --git a/cpp-netlib/libs/mime/test/mime-roundtrip.cpp b/cpp-netlib/libs/mime/test/mime-roundtrip.cpp new file mode 100644 index 00000000..f5bca8ac --- /dev/null +++ b/cpp-netlib/libs/mime/test/mime-roundtrip.cpp @@ -0,0 +1,118 @@ +/* + Read in a mime structure, parse it, and write it back to a file + with the same name as the input file, but with "-Results" appended to the + name + + We don't just write to stdout, because we want to read/write binary data, + and stdout on some systems eats CRLF, and turns them into newlines. + + Returns 0 for success, non-zero for failure + +*/ + +#include +#include + +#ifdef BOOST_TEST_DYN_LINK +#define BOOST_TEST_ALTERNATIVE_INIT_API +#endif +#include + +#include +#include +#include +#include +#include +#include + +namespace { + +std::string readfile(const char *fileName) { + std::ifstream in(fileName); + if (!in) { + std::cerr << std::string("Can't open file: ") + fileName << std::endl; + throw std::runtime_error(std::string("Can't open file: ") + fileName); + } + + std::istreambuf_iterator src(in); + std::istreambuf_iterator eof; + std::string retVal; + + in >> std::noskipws; + std::copy(src, eof, std::back_inserter(retVal)); + return retVal; +} + +struct my_traits { + typedef std::string string_type; + // typedef std::pair < std::string, string_type > header_type; + typedef std::string body_type; +}; + +// using namespace boost::mime; +typedef boost::mime::basic_mime mime_part; +typedef boost::shared_ptr smp; + +smp to_mime(const char *fileName) { + std::ifstream in(fileName); + if (!in) { + std::cerr << std::string("Can't open file: ") + fileName << std::endl; + throw std::runtime_error(std::string("Can't open file: ") + fileName); + } + + in >> std::noskipws; + return mime_part::parse_mime(in); +} + +std::string from_mime(smp mp) { + std::ostringstream oss; + oss << *mp; + return oss.str(); +} + +void test_roundtrip(const char *fileName) { + smp mp; + BOOST_REQUIRE_NO_THROW(mp = to_mime(fileName)); + BOOST_CHECK_EQUAL(readfile(fileName), from_mime(mp)); +} + +} + +using namespace boost::unit_test; + +#ifdef BOOST_TEST_DYN_LINK +bool init_unit_test() +#else +test_suite *init_unit_test_suite(int, char **) +#endif +{ + framework::master_test_suite().add( + BOOST_TEST_CASE(boost::bind(test_roundtrip, "TestMessages/00000001"))); + framework::master_test_suite().add( + BOOST_TEST_CASE(boost::bind(test_roundtrip, "TestMessages/00000019"))); + framework::master_test_suite().add( + BOOST_TEST_CASE(boost::bind(test_roundtrip, "TestMessages/00000431"))); + framework::master_test_suite().add( + BOOST_TEST_CASE(boost::bind(test_roundtrip, "TestMessages/00000975"))); + + // Following test is removed because the file it used often tripped + // false-positives when scanned by virus checkers. + // framework::master_test_suite().add ( BOOST_TEST_CASE( boost::bind ( + // test_roundtrip, "TestMessages/00001136" ))); + + // test cases that fail + // framework::master_test_suite().add ( BOOST_TEST_CASE( boost::bind ( + // test_roundtrip, "TestMessages/0019-NoBoundary" ))); + return +#ifdef BOOST_TEST_DYN_LINK + true; +#else + 0; +#endif +} + +#ifdef BOOST_TEST_DYN_LINK +int main(int argc, char *argv[]) { + return unit_test_main(&init_unit_test, argc, argv); +} +#endif diff --git a/cpp-netlib/libs/mime/test/mime-structure.cpp b/cpp-netlib/libs/mime/test/mime-structure.cpp new file mode 100644 index 00000000..6e148c69 --- /dev/null +++ b/cpp-netlib/libs/mime/test/mime-structure.cpp @@ -0,0 +1,123 @@ +/* + Read in a mime structure, parse it, dump the structure to stdout + + Returns 0 for success, non-zero for failure +*/ + +#include + +#include +#include +#include +#include + +struct my_traits { + typedef std::string string_type; + // typedef std::pair < std::string, string_type > header_type; + typedef std::string body_type; +}; + +typedef boost::mime::basic_mime mime_part; + +template +void DumpContainer(std::ostream &out, const std::string &prefix, + const Container &c) { + out << prefix << ' '; + if (c.size() < 10) { + for (typename Container::const_iterator iter = c.begin(); iter != c.end(); + ++iter) + out << (int)*iter << ' '; + } else { + for (int i = 0; i < 5; i++) out << int(c.begin()[i]) << ' '; + out << "... "; + for (int i = 0; i < 5; i++) out << int(c.rbegin()[i]) << ' '; + } + out << std::endl; +} + +void DumpStructure(std::ostream &out, const char *title, const mime_part &mp, + std::string prefix) { + std::string content_type = mp.get_content_type(); + if (NULL != title) out << prefix << "Data from: " << title << std::endl; + out << prefix << "Content-Type: " << content_type << std::endl; + out << prefix << "There are " + << std::distance(mp.header_begin(), mp.header_end()) << " headers" + << std::endl << std::flush; + size_t subpart_count = std::distance(mp.subpart_begin(), mp.subpart_end()); + switch (mp.get_part_kind()) { + case mime_part::simple_part: + if (subpart_count != 0) + out << str(boost::format("%s ### %d subparts on a simple (%s) type!") % + prefix % subpart_count % content_type) << std::endl; + out << prefix << "The body is " << mp.body_size() << " bytes long" + << std::endl; + DumpContainer(out, prefix, *mp.body()); + break; + + case mime_part::multi_part: + break; + + case mime_part::message_part: + if (boost::iequals(content_type, "message/delivery-status")) + out << prefix << "The body is " << mp.body_size() << " bytes long" + << std::endl; + else if (1 != subpart_count) + out << str(boost::format("%s ### %d subparts on a message (%s) type!") % + subpart_count % prefix % content_type) << std::endl; + break; + } + + if (subpart_count != 0) { + out << prefix << "There are " + << std::distance(mp.subpart_begin(), mp.subpart_end()) << " sub parts" + << std::endl << std::flush; + for (mime_part::constPartIter iter = mp.subpart_begin(); + iter != mp.subpart_end(); ++iter) + DumpStructure(out, NULL, **iter, prefix + " "); + } +} + +int main(int argc, char *argv[]) { + int retVal = 0; + + for (int i = 1; i < argc; ++i) { + boost::shared_ptr rmp; + try { + std::ifstream in(argv[i]); + if (!in) { + std::cerr << "Can't open file " << argv[i] << std::endl; + retVal += 100; + continue; + } + + in >> std::noskipws; + std::cout << "**********************************" << std::endl; + rmp = mime_part::parse_mime(in); + } + + catch (const boost::mime::mime_parsing_error &err) { + std::cout << "Caught an error parsing '" << argv[i] << "'" << std::endl; + std::cout << " " << err.what() << std::endl; + retVal += 10; + continue; + } + catch (const boost::exception &berr) { + std::cout << "Caught an boost error parsing '" << argv[i] << "'" + << std::endl; + // std::cout << " " << berr.what () << std::endl; + retVal += 10; + continue; + } + catch (const std::runtime_error &rerr) { + std::cout << "Caught an runtime error parsing '" << argv[i] << "'" + << std::endl; + std::cout << " " << rerr.what() << std::endl; + retVal += 10; + continue; + } + + DumpStructure(std::cout, argv[i], *rmp, std::string()); + } + + return retVal; +} diff --git a/cpp-netlib/libs/mime/test/mimeParse.py b/cpp-netlib/libs/mime/test/mimeParse.py new file mode 100755 index 00000000..7db7bef2 --- /dev/null +++ b/cpp-netlib/libs/mime/test/mimeParse.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +# +# A python program to compare against the output from "mime-structure" tool. +# +# Usage: python mimeParse.py +# + +import sys +import email + +def parseOne ( msg, title, prefix ): +# if prefix != "": +# print msg + if title != None: + print "%sData from: %s" % ( prefix, title ) + print "%sContent-Type: %s" % ( prefix, msg.get_content_type ()) + print "%sThere are %d headers" % ( prefix, msg.__len__ ()) + payload = msg.get_payload (); + if msg.is_multipart (): + print "%sThere are %s sub parts" % ( prefix, len ( payload )) + for p in payload: + parseOne ( p, None, prefix + " " ) + else: + bodyLen = 0 + aBody = "" + for p in payload: + bodyLen += len (p) + aBody += p + + print "%sThe body is %d bytes long" % ( prefix, bodyLen ) + print prefix, + if bodyLen < 10: + for c in aBody: + print ord(c), + else: + for i in range(0,5): + print ord (aBody[i]), + + print "... ", + for i in range(1,6): + print ord (aBody[-i]), + print '' + +# _structure ( msg ) + + +def main(): + for a in sys.argv[1:]: + print "**********************************" + parseOne ( email.message_from_file ( open ( a )), a, "" ) + +main () \ No newline at end of file diff --git a/cpp-netlib/libs/network/benchmarks/README.rst b/cpp-netlib/libs/network/benchmarks/README.rst new file mode 100644 index 00000000..edf40940 --- /dev/null +++ b/cpp-netlib/libs/network/benchmarks/README.rst @@ -0,0 +1,3 @@ +Here we can collect some statistics about different areas of +performance in the :mod:`cpp-netlib`, including run-time and +compile-time. diff --git a/cpp-netlib/libs/network/build/CMakeLists.txt b/cpp-netlib/libs/network/build/CMakeLists.txt new file mode 100644 index 00000000..dc1c0d0b --- /dev/null +++ b/cpp-netlib/libs/network/build/CMakeLists.txt @@ -0,0 +1,6 @@ +include_directories(${CPP-NETLIB_SOURCE_DIR}) +find_package( Boost 1.45.0 COMPONENTS unit_test_framework system regex thread filesystem ) + +add_library(cppnetlib-uri STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/parse_uri_impl.cpp) +add_library(cppnetlib-server-parsers STATIC ${CPP-NETLIB_SOURCE_DIR}/libs/network/src/server_request_parsers_impl.cpp) + diff --git a/cpp-netlib/libs/network/doc/.gitignore b/cpp-netlib/libs/network/doc/.gitignore new file mode 100644 index 00000000..9c5f5782 --- /dev/null +++ b/cpp-netlib/libs/network/doc/.gitignore @@ -0,0 +1 @@ +_build \ No newline at end of file diff --git a/cpp-netlib/libs/network/doc/_ext/adjusts.py b/cpp-netlib/libs/network/doc/_ext/adjusts.py new file mode 100644 index 00000000..c03554b4 --- /dev/null +++ b/cpp-netlib/libs/network/doc/_ext/adjusts.py @@ -0,0 +1,11 @@ +from sphinx.writers import html as sphinx_htmlwriter + +class CppNetlibHTMLTranslator(sphinx_htmlwriter.SmartyPantsHTMLTranslator): + """ + cpp-netlib-customized HTML transformations of documentation. Based on + djangodocs.DjangoHTMLTranslator + """ + + def visit_section(self, node): + node['ids'] = map(lambda x: "cpp-netlib-%s" % x, node['ids']) + sphinx_htmlwriter.SmartyPantsHTMLTranslator.visit_section(self, node) diff --git a/cpp-netlib/libs/network/doc/_static/Button-Info-icon.png b/cpp-netlib/libs/network/doc/_static/Button-Info-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4f318491f2c20870226089e7009da2218819ced7 GIT binary patch literal 3499 zcmV;c4OH@pP);<+r55qHw6!kuR2D@o zIaONiu_zWRTDK}H3PmUw#RY;O31nZ$^0K^T`p=!Y@80{~OKKJE>74VQJDGRy-1+|h z`76E@2ol+7M7nBzw&FkWai6pb-f_WnDEA4*aJ~wlY-f#@hRo2rxY!&pd(qFlc zP`zE=%N~#E{ekEYfTRt37sjKM9rWx)&gkjl2z23HBr?E)EC8*+w0KM7eRi&XWbT$ zPD=JQhw#kKdiHPji|6kI4s4gd{*`485*$0#Yp-Wnj^HrD_m>IE$imDq1yoXyq0CL% zA*GthZUM5iuE+Z#G0Z+TkIpO$>Txn?vwTwx_ILDJ7LfWEB5oBq4O@&}{HRfg5G(yJ zH*)@{mUAp*Sve4ZQHHr(o=jZ2k`q&@m{6RJNyD<$`bb9+BJ)YTZqTJ~!?^ zdt`jv1W?z}hdVYNP~*}KY!otjh9v}TV><2Nkc;{%!k@2~(W%p*wJlF10(jam(@8%B zPMwF`fEP24%?G*kf~|#H^odi7l4dLo`f=B3!;?%L3P-Wvg}sV8CS(VV)VSa@@$&9w zw8-eRi6i;uKS9&`;#2@+d9Ve8iU?O$aA}Z1r;Q4VJO*K;R)VsCvV;jhjcfJBEugL8 zbGz{9jFFV>b2}{XUR@XN-CSd8+q8rtqYxrK3#ahrt}x#Etd-Ck68OV>;BcM%bqaLZ zVF$3*Kz7be0u#tUI{+E;s}RWb=2=?P!L$VAC z8EZ+TP$HF5MI~FyVqX}SmyRBG>JK@>aA{$qi|*K{6Tij`AZTGLd{D>EEThsxmjPWZ zJ(8g;2hBI$$nrZ(nM*kP8sX;JhP5xNF%=r5>A7!2mpFyA2NSGBMrQ1n<3eZ?sbnWi zk2m`|kqO)HLX8>yn27fo2(cAJG|Cb5l~sf-Yvt(8EXzy)ud|$i`Huj_qcJGMi;=k* zDkBVJfw=Z*Kxd9?8#ZmjuJJ_eJ1rn1|Gt(G4tIxvYEH}*SIMW}V3{UgBX?4D$jHgS z&({;&ZZSB^hrEDKTR;NP%5#}M5C@=nZ~94`5ESD|v#&dXzV0x&BSH-EyOEpbq1u2~ z^qCNqhAqc6c^}h05Yzs^7HID36AdyNMWTfJFBAy1$xTraX^(yv$DImXevh%}!t69; zrg>}t^g{aspdDItM?@i)&1Hkqs4O>Kj2;}on4$m;5Bfz0J8@?uMkjBm;@e{Oh+_kw z`!Vg%awDMuboNF>eS5Fb#}kVMKG`IdaI##+k69{k#uZ#LEimX(z}2Ro9nYYSK_9Z{ zl-M_^!~GdW0W2yXj54+$rEuuiYCCb|J2m~#M^PoIA5+r9xudazDHM}_u$l?Mm$d^9KvHm}((>`tjn1|~g29B9zXxhVzPfMhbX#vx*?a|3jC!YW96Nk|F zqJYB!D?V$(l8>8{9X2WQShTVCdBYN+nc4XdXNb-xA2mP_);}!p;%YhH z0xOXne>(5QmRYoM%f-3`u_bsvplTtvx|)_yHIlA{xTSNXI52fMa?`yI06+P(SyUYA zjMqP^?h$H7X4X8sP@^AH3pM*9q8A;t=!BIw3cSBDp2$=wkr@nNIhRBpcbrDX)lMO| z8JVDdmrq;%fN5L=zIIBnBZ+YpfzoZY_`E0DZ?$RA$Uz-V6-^hXBh5=E<}$WHR`+$k{Q67~g(=LCZ~hBa)oiaWZpz_mU%txTwY+W5rQp&pr6)u zBwN6tbxk2N^2B161zvs%`2C$Jx0JG}P5t1ZgykG(0|8AJ6M*&sw;h0$tv3{8(9EMU z9RQwV&0kdAPRH(T6aP5lXq;KwNuTyath&cep{Q-4b{{auySfB!;5^lMu-{F+Z1Tur z7B0CCxNIS@6%+ur1}8NmjKa(fZbyE=q0(F`NOPV(RD9Hgr8^sF!}O721#9?`*6vhg zgVO>L9#qN83E+w40#7|Cr(cJDj#Xq+2U{L*79QaH%Et2I73aMknVnPkg_c9d9} z3orn|RjNJFIVkin@4SAH>2p{>u5Cp}AN}fZuZWt*CdtK`6(Y4Yx;Y?(!)yVWL=LyI zimouW z_8DroB`ypYbt0_s7Mb*<1$sExESb-2e@m|G3m@*vW*x7eelBqPazch*cswo|;`bQG zE{-UqGIa7Gfc1{#4U4Jygqo+8_ti$(9O@zba-qP+7l8lrc-?H)2aaz~CEU#gR4_1TGJcBL8gr?o3X1BSj?N1{Z;bGuk?w@ zPABz|&+8-1zd>L=`*~KTj7&7l=N84h1x?i z+%Mvce!(nY;v~T9)_KF0CjeVn98=MS!z8wE1D<=9V+&U>jrG9S{GmIsCI72IUOr*+ z6oK+`F0)DrLyCkEe&yyM)Gbh3$K_%bp|Vn7>lUE7$^4%1jsB}aV*9`SXOC3vfAa4( Z{|4w49dFB_+JyiB002ovPDHLkV1i-~hynlr literal 0 HcmV?d00001 diff --git a/cpp-netlib/libs/network/doc/_static/Button-Warning-icon.png b/cpp-netlib/libs/network/doc/_static/Button-Warning-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..edcd6624b9b2adbdac1e54db074fced010ae9c48 GIT binary patch literal 2911 zcmV-l3!wCgP)gI6cjm9C@Esm zDo3luH`d3g%0m>22#CnT5EKzm%o12aHVN5HX6E+(^Vpr)EF87GdQLazWB&PP_MiLx z_xta?|11dq;~zZP2Arw{e2hyNCHDDN#z&0CQ=Nbu@7IjS8O15rDj5?Q|6tImNI;G? zi!ojifLC-2&@Va#%>IwRj?o9@G0+Y3zB!Bu$BM+UBru-wr%+J9q7fmyxTD`R5cxy= zS+ye$!xu&{Qg6uq-`PY?83NrH8-qUdEg4$~=e6@SADPYm{JTaNTvi43jU?AXFGl&P zKtPW19^;CcLv!f9%d)rw5i(nmXxrDkZtPt{)Ue;|FIyg^NsDV_{}RTP@Lx*lSP;0D zvAAooD%MOcBA*JNocT*s`%EJAwKShWjdi50oe9Rye_>oB>N_J0+bT7A?K;L=CzF6& zrJERMzja?L7<^79h&C62I^Z!m+nyVV|Fl)V2cz;+Sn_29T>F;;vimDWPe$xy5s+bV z=9N7Hu=w5r#EeW*2h9h}EI>#~Bhh9Vp|)Z)QPW`c*J9{?+Qop1t0j0(RB z*=wg3L6_nT6rFA$an^NmP$b*v)VBW3o22h}4YvQFVV|jCifa(%OI;Y@6HVY*#)xr4 zvS8*-xxkAS)ZSA7h409tN+w1lXzQl|G#r3QFCT)r@7KyJ3mJEwNCLeXt6S%Yj4vK5 zrreeSl+L%I2zBRZQw#c6|4u6*rSky9Ko%L1&0uVQ0joJDoI9x!_th9pe7Qek{fQtT z7%LbT&mWPGBQ6aRX0->k^X;Zo(3cCMs5C7BBfN|w(jl|0Z+{-Cb{8%DupUP*JSh8C zF$T%ojyHju8H>(sp8=~MDFQ`NKy)0=3%Ae`c}5N>o$g5cMSaI}K#esPorWqtUj(|Y zL;r`u@Wn3a1Q^bE>39-o!Pq7c+P(j9Aq?yqK+Nk(SUk{LtjHcf6_j%(BxcNvBdU475nf4Dy$x5E$7sm(D&QjHJHD+e-)BV7srJF6+ej6uLe{z zJ)2Ut|O017l9bfLw z*mbN4NNwIU`B&LAWmpbtJqXykKPOya8=54boP947EAbGZ=vFYkp4W^3$5o`N)tubw zVcN?zIODaby#5MUYweg37|8grZAekJ%qxaqCKvp<-2nX|YXtO;COX^+qF|6`0HbOJ z7`vXePMrAUNGTQpI#dqzF$21fsf4`|UfBSbGFBc70y1pM_}uIH@gW>Gu!R{aA*-V` z>%4Hy>2y56ZKdsvDB2G5c)-~E3K)A|ZRP>~5|Y7vwL5sjS%WXHtf$-OMC2_S!OAyB z4XZzffXtB3^y})UWitvHeWk6LQ*s@6>Aba#U zK;2H%HG@hgSHUOS;?lN}U}gNDO@OBw%6W@e{PE+hp?7CLZ`ZTE(n%vB%;$=<%S_Ke zTE!%w>Q61%xFzIjODREP6xMBz!zB~<$t|edN6XF9p`S}YR*CoDUK+%w#^n=FKSH38 zKnO@g9=C)XZv@XmwZ{t{4``cj1*reVk{OvH%gWr22jty`fe@==z3FgQ*+G1MX}#>7 z4b~p|Cllz**qD`xfh|wB!J>SYPDT(x4UlW*<)3|yR`QZ$e7UHezswYhMZh3!Ln%Ph zp`@`y*8OCTVE1ubi4ogejhud0+wuTdomvA({mgo`1|E9O+GBdss|!s6MszJ{6*s$*m%Rpz)HOg>+mHk~!5KtvuWo=Fryr1Z z%C~#xL(1E|bOi2YlwH;8#fBDWvyl`}wG#w6t6;`W`L|{JS zH+Ns%63WKpvvEA6K$`%X5+Wsqz!40O<+13^m&}8EZZ874`tKw8lPhkQTfn z>pb`?V{|$K@=fx_P_|Gv{jC@Z@)RyBeYQkQ5=ptZ2*E1xtH za-;*gl#>&c8exC64n0R!LL_R)7fQYCHQ`b2QpRO-@5!UPuWiX;#E+!<2%VW$!191N zvIi15ptNiI)pES$jLYRH4gvXw z?2VH48TiS(BJu}#_Wik*-famF&4)zcL%kU!; zaO9-(Q+O{OkLl2FOc=NBYLX*d&v?^JJB-g5J>Pw#084uZ2>p3n@3*iBD7JBy;m*;K zj$GExd4hm)#=A@)KZU?S(Dz)G%(_M*11AkN5~QrQtDl+<6UD1x+4>k>_27Ovf_x)* zfi$BZV|AY{K3F-oh@Z~Z1kd0=j#ju#)qJy%3f_<^zjE5^{QZ1SbRZ^Re1AhT{gYew z?zRi^9+E#U)a^Di^uTdpSX*JHgZ}cdQyEic-<1bruFFF3wIFEOArX1pTK9xai-606K~ei{R^t)@Y5s#`IFD^ z<+BQ5K#u@xpUdU!&fqe#xd&2b-*aT!3!i2W@;r!!pwOXC68xx7x%3MNns zt2V`;bb^@*7RkrTz3#9Tvs**I5{TF zc~lZOkFma8fg;u|D1!W4#hTsBBEYOJEU8v(s7Rl`kZujwiB9Ljp|VQD)tlqAW@{X{pp&C6V+>`~x~r88u!^MLGERq6^RtKXXRwOS zCMQCqeq`UdVEuMg0LhKx$@)lt><26JegP@JYX1K}dz|dge*i0f#X4kQN2>q;002ov JPDHLkV1feQcf