Skip to content

Commit 32d730c

Browse files
deanberrisglynos
authored andcommitted
Body generator for PUT/POST APIs
This commit does the following things: - Add overloads to the HTTP Client implementation that takes a generator callback to generate chunks of the POST or PUT requests. - Fixes #245 which happens when a resolution error occurs, which leaks futures and potentially threads associated with futures. - Formats the files touched using clang-format in Google's style. Unfortunately the API cannot be tested without starting a POST/PUT capable server. A future commit should add an end-to-end test that uses the HTTP server implementation and the HTTP client implementation to verify end-to-end correctness.
1 parent a5feaa6 commit 32d730c

File tree

11 files changed

+1673
-1346
lines changed

11 files changed

+1673
-1346
lines changed

boost/network/protocol/http/client/async_impl.hpp

Lines changed: 63 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -15,82 +15,78 @@
1515
#include <boost/make_shared.hpp>
1616
#include <boost/bind.hpp>
1717

18-
namespace boost { namespace network { namespace http {
18+
namespace boost {
19+
namespace network {
20+
namespace http {
1921

20-
template <class Tag, unsigned version_major, unsigned version_minor>
21-
struct basic_client_impl;
22+
template <class Tag, unsigned version_major, unsigned version_minor>
23+
struct basic_client_impl;
2224

23-
namespace impl {
24-
template <class Tag, unsigned version_major, unsigned version_minor>
25-
struct async_client :
26-
connection_policy<Tag,version_major,version_minor>::type
27-
{
28-
typedef
29-
typename connection_policy<Tag,version_major,version_minor>::type
30-
connection_base;
31-
typedef
32-
typename resolver<Tag>::type
33-
resolver_type;
34-
typedef
35-
typename string<Tag>::type
36-
string_type;
25+
namespace impl {
26+
template <class Tag, unsigned version_major, unsigned version_minor>
27+
struct async_client
28+
: connection_policy<Tag, version_major, version_minor>::type {
29+
typedef typename connection_policy<Tag, version_major, version_minor>::type
30+
connection_base;
31+
typedef typename resolver<Tag>::type resolver_type;
32+
typedef typename string<Tag>::type string_type;
3733

38-
typedef
39-
function<void(boost::iterator_range<char const *> const &, system::error_code const &)>
40-
body_callback_function_type;
34+
typedef function<void(boost::iterator_range<char const*> const&,
35+
system::error_code const&)> body_callback_function_type;
4136

42-
async_client(bool cache_resolved, bool follow_redirect, boost::shared_ptr<boost::asio::io_service> service, optional<string_type> const & certificate_filename, optional<string_type> const & verify_path)
43-
: connection_base(cache_resolved, follow_redirect),
44-
service_ptr(service.get() ? service : boost::make_shared<boost::asio::io_service>()),
37+
typedef function<bool(string_type&)> body_generator_function_type;
38+
39+
async_client(bool cache_resolved,
40+
bool follow_redirect,
41+
boost::shared_ptr<boost::asio::io_service> service,
42+
optional<string_type> const& certificate_filename,
43+
optional<string_type> const& verify_path)
44+
: connection_base(cache_resolved, follow_redirect),
45+
service_ptr(service.get()
46+
? service
47+
: boost::make_shared<boost::asio::io_service>()),
4548
service_(*service_ptr),
4649
resolver_(service_),
4750
sentinel_(new boost::asio::io_service::work(service_)),
4851
certificate_filename_(certificate_filename),
49-
verify_path_(verify_path)
50-
{
51-
connection_base::resolver_strand_.reset(new
52-
boost::asio::io_service::strand(service_));
53-
lifetime_thread_.reset(new boost::thread(
54-
boost::bind(
55-
&boost::asio::io_service::run,
56-
&service_
57-
)));
58-
}
59-
60-
~async_client() throw ()
61-
{
62-
sentinel_.reset();
63-
if (lifetime_thread_.get()) {
64-
lifetime_thread_->join();
65-
lifetime_thread_.reset();
66-
}
67-
}
68-
69-
basic_response<Tag> const request_skeleton(
70-
basic_request<Tag> const & request_,
71-
string_type const & method,
72-
bool get_body,
73-
body_callback_function_type callback
74-
)
75-
{
76-
typename connection_base::connection_ptr connection_;
77-
connection_ = connection_base::get_connection(resolver_, request_, certificate_filename_, verify_path_);
78-
return connection_->send_request(method, request_, get_body, callback);
79-
}
80-
81-
boost::shared_ptr<boost::asio::io_service> service_ptr;
82-
boost::asio::io_service & service_;
83-
resolver_type resolver_;
84-
boost::shared_ptr<boost::asio::io_service::work> sentinel_;
85-
boost::shared_ptr<boost::thread> lifetime_thread_;
86-
optional<string_type> certificate_filename_, verify_path_;
87-
};
88-
} // namespace impl
52+
verify_path_(verify_path) {
53+
connection_base::resolver_strand_.reset(
54+
new boost::asio::io_service::strand(service_));
55+
lifetime_thread_.reset(new boost::thread(
56+
boost::bind(&boost::asio::io_service::run, &service_)));
57+
}
8958

90-
} // namespace http
59+
~async_client() throw() {
60+
sentinel_.reset();
61+
if (lifetime_thread_.get()) {
62+
lifetime_thread_->join();
63+
lifetime_thread_.reset();
64+
}
65+
}
9166

92-
} // namespace network
67+
basic_response<Tag> const request_skeleton(
68+
basic_request<Tag> const& request_,
69+
string_type const& method,
70+
bool get_body,
71+
body_callback_function_type callback,
72+
body_generator_function_type generator) {
73+
typename connection_base::connection_ptr connection_;
74+
connection_ = connection_base::get_connection(
75+
resolver_, request_, certificate_filename_, verify_path_);
76+
return connection_->send_request(
77+
method, request_, get_body, callback, generator);
78+
}
9379

94-
} // namespace boost
80+
boost::shared_ptr<boost::asio::io_service> service_ptr;
81+
boost::asio::io_service& service_;
82+
resolver_type resolver_;
83+
boost::shared_ptr<boost::asio::io_service::work> sentinel_;
84+
boost::shared_ptr<boost::thread> lifetime_thread_;
85+
optional<string_type> certificate_filename_, verify_path_;
86+
};
87+
} // namespace impl
88+
} // namespace http
89+
} // namespace network
90+
} // namespace boost
9591

96-
#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623
92+
#endif // BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_ASYNC_IMPL_HPP_20100623

boost/network/protocol/http/client/connection/async_base.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ASYNC_CONNECTION_BASE_20100529
22
#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_ASYNC_CONNECTION_BASE_20100529
33

4-
// Copyright 2010 (C) Dean Michael Berris
4+
// Copryight 2013 Google, Inc.
5+
// Copyright 2010 Dean Michael Berris <dberris@google.com>
56
// Copyright 2010 (C) Sinefunc, Inc.
67
// Distributed under the Boost Software License, Version 1.0.
78
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -26,6 +27,7 @@ namespace boost { namespace network { namespace http { namespace impl {
2627
typedef iterator_range<char const *> char_const_range;
2728
typedef function<void(char_const_range const &, system::error_code const &)>
2829
body_callback_function_type;
30+
typedef function<bool(string_type&)> body_generator_function_type;
2931
typedef shared_ptr<this_type> connection_ptr;
3032

3133
// This is the factory function which constructs the appropriate async
@@ -61,7 +63,8 @@ namespace boost { namespace network { namespace http { namespace impl {
6163
request const & request,
6264
string_type const & method,
6365
bool get_body,
64-
body_callback_function_type callback) = 0;
66+
body_callback_function_type callback,
67+
body_generator_function_type generator) = 0;
6568

6669
virtual ~async_connection_base() {}
6770

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy