10 #ifndef __PION_TCPCONNECTION_HEADER__
11 #define __PION_TCPCONNECTION_HEADER__
16 #pragma GCC system_header
18 #include <boost/asio/ssl.hpp>
21 #include <boost/noncopyable.hpp>
22 #include <boost/shared_ptr.hpp>
23 #include <boost/lexical_cast.hpp>
24 #include <boost/enable_shared_from_this.hpp>
25 #include <boost/asio.hpp>
26 #include <boost/array.hpp>
27 #include <boost/function.hpp>
28 #include <boost/function/function1.hpp>
29 #include <pion/PionConfig.hpp>
40 public boost::enable_shared_from_this<TCPConnection>,
41 private boost::noncopyable
47 LIFECYCLE_CLOSE, LIFECYCLE_KEEPALIVE, LIFECYCLE_PIPELINED
51 enum { READ_BUFFER_SIZE = 8192 };
60 typedef boost::asio::ip::tcp::socket
Socket;
64 typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket>
SSLSocket;
67 typedef boost::asio::ssl::context SSLContext;
71 SSLSocket(boost::asio::io_service& io_service) : m_socket(io_service) {}
72 inline Socket& next_layer(
void) {
return m_socket; }
73 inline const Socket& next_layer(
void)
const {
return m_socket; }
74 inline Socket& lowest_layer(
void) {
return m_socket.lowest_layer(); }
75 inline const Socket& lowest_layer(
void)
const {
return m_socket.lowest_layer(); }
79 typedef int SSLContext;
92 static inline boost::shared_ptr<TCPConnection>
create(boost::asio::io_service& io_service,
93 SSLContext& ssl_context,
97 return boost::shared_ptr<TCPConnection>(
new TCPConnection(io_service, ssl_context,
98 ssl_flag, finished_handler));
107 explicit TCPConnection(boost::asio::io_service& io_service,
const bool ssl_flag =
false)
110 m_ssl_context(io_service, boost::asio::ssl::context::sslv23),
111 m_ssl_socket(io_service, m_ssl_context),
112 m_ssl_flag(ssl_flag),
115 m_ssl_socket(io_service),
118 m_lifecycle(LIFECYCLE_CLOSE)
132 m_ssl_context(io_service, boost::asio::ssl::context::sslv23),
133 m_ssl_socket(io_service, ssl_context), m_ssl_flag(true),
136 m_ssl_socket(io_service), m_ssl_flag(false),
138 m_lifecycle(LIFECYCLE_CLOSE)
145 return const_cast<SSLSocket&
>(m_ssl_socket).lowest_layer().is_open();
150 if (m_ssl_socket.lowest_layer().is_open())
151 m_ssl_socket.lowest_layer().close();
174 template <
typename AcceptHandler>
176 AcceptHandler handler)
178 tcp_acceptor.async_accept(m_ssl_socket.lowest_layer(), handler);
189 inline boost::system::error_code
accept(boost::asio::ip::tcp::acceptor& tcp_acceptor)
191 boost::system::error_code ec;
192 tcp_acceptor.accept(m_ssl_socket.lowest_layer(), ec);
204 template <
typename ConnectHandler>
206 ConnectHandler handler)
208 m_ssl_socket.lowest_layer().async_connect(tcp_endpoint, handler);
220 template <
typename ConnectHandler>
222 const unsigned int remote_port,
223 ConnectHandler handler)
225 boost::asio::ip::tcp::endpoint tcp_endpoint(remote_addr, remote_port);
237 inline boost::system::error_code
connect(boost::asio::ip::tcp::endpoint& tcp_endpoint)
239 boost::system::error_code ec;
240 m_ssl_socket.lowest_layer().connect(tcp_endpoint, ec);
253 inline boost::system::error_code
connect(
const boost::asio::ip::address& remote_addr,
254 const unsigned int remote_port)
256 boost::asio::ip::tcp::endpoint tcp_endpoint(remote_addr, remote_port);
269 inline boost::system::error_code
connect(
const std::string& remote_server,
270 const unsigned int remote_port)
273 boost::system::error_code ec;
274 boost::asio::ip::tcp::resolver resolver(m_ssl_socket.lowest_layer().get_io_service());
275 boost::asio::ip::tcp::resolver::query query(remote_server,
276 boost::lexical_cast<std::string>(remote_port),
277 boost::asio::ip::tcp::resolver::query::numeric_service);
278 boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query, ec);
283 ec = boost::asio::error::host_not_found;
284 boost::asio::ip::tcp::resolver::iterator end;
285 while (ec && endpoint_iterator != end) {
286 boost::asio::ip::tcp::endpoint ep(endpoint_iterator->endpoint());
303 template <
typename SSLHandshakeHandler>
306 m_ssl_socket.async_handshake(boost::asio::ssl::stream_base::client, handler);
318 template <
typename SSLHandshakeHandler>
321 m_ssl_socket.async_handshake(boost::asio::ssl::stream_base::server, handler);
334 boost::system::error_code ec;
336 m_ssl_socket.handshake(boost::asio::ssl::stream_base::client, ec);
350 boost::system::error_code ec;
352 m_ssl_socket.handshake(boost::asio::ssl::stream_base::server, ec);
365 template <
typename ReadHandler>
369 m_ssl_socket.async_read_some(boost::asio::buffer(m_read_buffer),
373 m_ssl_socket.next_layer().async_read_some(boost::asio::buffer(m_read_buffer),
385 template <
typename ReadBufferType,
typename ReadHandler>
387 ReadHandler handler) {
390 m_ssl_socket.async_read_some(read_buffer, handler);
393 m_ssl_socket.next_layer().async_read_some(read_buffer, handler);
404 inline std::size_t
read_some(boost::system::error_code& ec) {
407 return m_ssl_socket.read_some(boost::asio::buffer(m_read_buffer), ec);
410 return m_ssl_socket.next_layer().read_some(boost::asio::buffer(m_read_buffer), ec);
422 template <
typename ReadBufferType>
423 inline std::size_t
read_some(ReadBufferType read_buffer,
424 boost::system::error_code& ec)
428 return m_ssl_socket.read_some(read_buffer, ec);
431 return m_ssl_socket.next_layer().read_some(read_buffer, ec);
443 template <
typename CompletionCondition,
typename ReadHandler>
444 inline void async_read(CompletionCondition completion_condition,
449 boost::asio::async_read(m_ssl_socket, boost::asio::buffer(m_read_buffer),
450 completion_condition, handler);
453 boost::asio::async_read(m_ssl_socket.next_layer(), boost::asio::buffer(m_read_buffer),
454 completion_condition, handler);
467 template <
typename MutableBufferSequence,
typename CompletionCondition,
typename ReadHandler>
469 CompletionCondition completion_condition,
474 boost::asio::async_read(m_ssl_socket, buffers,
475 completion_condition, handler);
478 boost::asio::async_read(m_ssl_socket.next_layer(), buffers,
479 completion_condition, handler);
492 template <
typename CompletionCondition>
493 inline std::size_t
read(CompletionCondition completion_condition,
494 boost::system::error_code& ec)
498 return boost::asio::async_read(m_ssl_socket, boost::asio::buffer(m_read_buffer),
499 completion_condition, ec);
502 return boost::asio::async_read(m_ssl_socket.next_layer(), boost::asio::buffer(m_read_buffer),
503 completion_condition, ec);
517 template <
typename MutableBufferSequence,
typename CompletionCondition>
518 inline std::size_t
read(
const MutableBufferSequence& buffers,
519 CompletionCondition completion_condition,
520 boost::system::error_code& ec)
524 return boost::asio::read(m_ssl_socket, buffers,
525 completion_condition, ec);
528 return boost::asio::read(m_ssl_socket.next_layer(), buffers,
529 completion_condition, ec);
540 template <
typename ConstBufferSequence,
typename WriteHandler>
541 inline void async_write(
const ConstBufferSequence& buffers, WriteHandler handler) {
544 boost::asio::async_write(m_ssl_socket, buffers, handler);
547 boost::asio::async_write(m_ssl_socket.next_layer(), buffers, handler);
559 template <
typename ConstBufferSequence>
560 inline std::size_t
write(
const ConstBufferSequence& buffers,
561 boost::system::error_code& ec)
565 return boost::asio::write(m_ssl_socket, buffers,
566 boost::asio::transfer_all(), ec);
569 return boost::asio::write(m_ssl_socket.next_layer(), buffers,
570 boost::asio::transfer_all(), ec);
576 inline void finish(
void) {
if (m_finished_handler) m_finished_handler(shared_from_this()); }
588 inline bool getKeepAlive(
void)
const {
return m_lifecycle != LIFECYCLE_CLOSE; }
591 inline bool getPipelined(
void)
const {
return m_lifecycle == LIFECYCLE_PIPELINED; }
603 m_read_position.first = read_ptr;
604 m_read_position.second = read_end_ptr;
614 read_ptr = m_read_position.first;
615 read_end_ptr = m_read_position.second;
620 boost::asio::ip::tcp::endpoint remote_endpoint;
623 remote_endpoint =
const_cast<SSLSocket&
>(m_ssl_socket).lowest_layer().remote_endpoint();
624 }
catch (boost::system::system_error& ) {
627 return remote_endpoint;
642 return m_ssl_socket.lowest_layer().get_io_service();
670 SSLContext& ssl_context,
675 m_ssl_context(io_service, boost::asio::ssl::context::sslv23),
676 m_ssl_socket(io_service, ssl_context), m_ssl_flag(ssl_flag),
679 m_ssl_socket(io_service), m_ssl_flag(false),
681 m_lifecycle(LIFECYCLE_CLOSE),
682 m_finished_handler(finished_handler)
691 typedef std::pair<const char*, const char*> ReadPosition;
695 SSLContext m_ssl_context;
698 SSLSocket m_ssl_socket;
707 ReadPosition m_read_position;
718 typedef boost::shared_ptr<TCPConnection> TCPConnectionPtr;