diff options
author | lloyd <[email protected]> | 2012-01-07 02:02:06 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-01-07 02:02:06 +0000 |
commit | fb9d993c7922012c359253e0dfeac05621c1c269 (patch) | |
tree | eca48d8b014320a9a44ab850de092790b678257a /doc/examples | |
parent | 8ca42a2f4243954ccfe304fb465cc66c2698b42a (diff) |
Avoid overlapping writes. Pretend to be an HTTP server
Diffstat (limited to 'doc/examples')
-rw-r--r-- | doc/examples/asio_tls_server.cpp | 98 |
1 files changed, 79 insertions, 19 deletions
diff --git a/doc/examples/asio_tls_server.cpp b/doc/examples/asio_tls_server.cpp index 9a1c3cefd..457460d41 100644 --- a/doc/examples/asio_tls_server.cpp +++ b/doc/examples/asio_tls_server.cpp @@ -1,8 +1,11 @@ #include <iostream> #include <string> +#include <vector> + #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> + #include <asio.hpp> #include <botan/tls_server.h> @@ -49,6 +52,11 @@ class tls_server_session : public boost::enable_shared_from_this<tls_server_sess asio::placeholders::bytes_transferred)); } + void stop() + { + m_socket.close(); + } + private: tls_server_session(asio::io_service& io_service, Botan::TLS_Session_Manager& session_manager, @@ -71,7 +79,16 @@ class tls_server_session : public boost::enable_shared_from_this<tls_server_sess { if(!error) { - m_tls.received_data(m_read_buf, bytes_transferred); + try + { + m_tls.received_data(m_read_buf, bytes_transferred); + } + catch(std::exception& e) + { + printf("Failed - %s\n", e.what()); + stop(); + return; + } m_socket.async_read_some( asio::buffer(m_read_buf, sizeof(m_read_buf)), @@ -80,56 +97,99 @@ class tls_server_session : public boost::enable_shared_from_this<tls_server_sess asio::placeholders::bytes_transferred)); } else - printf("Error in read: %s\n", error.message().c_str()); + { + stop(); + //printf("Error in read: %s\n", error.message().c_str()); + } } - void handle_write(const asio::error_code& error) + void handle_write(const asio::error_code& error, + size_t bytes_transferred) { if(!error) { + m_write_buf.clear(); + // initiate another write if needed + tls_output_wanted(NULL, 0); } else - printf("Error in write: %s\n", error.message().c_str()); + { + //printf("Error in write: %s\n", error.message().c_str()); + stop(); + } } void tls_output_wanted(const byte buf[], size_t buf_len) { - memcpy(&m_write_buf[0], buf, buf_len); - - asio::async_write(m_socket, - asio::buffer(m_write_buf, buf_len), - boost::bind(&tls_server_session::handle_write, this, - asio::placeholders::error)); + if(buf_len > 0) + m_outbox.insert(m_outbox.end(), buf, buf + buf_len); + // no write pending and have output pending + if(m_write_buf.empty() && !m_outbox.empty()) + { + std::swap(m_outbox, m_write_buf); + + asio::async_write(m_socket, + asio::buffer(&m_write_buf[0], m_write_buf.size()), + boost::bind(&tls_server_session::handle_write, + shared_from_this(), + asio::placeholders::error, + asio::placeholders::bytes_transferred)); + } } void tls_data_recv(const byte buf[], size_t buf_len, Botan::u16bit alert_info) { if(buf_len == 0 && alert_info != Botan::NULL_ALERT) - printf("Alert: %d\n", alert_info); + { + //printf("Alert: %d\n", alert_info); + if(alert_info == 0) + { + m_tls.close(); + return; + } + } + - printf("Got %d bytes: ", (int)buf_len); - for(size_t i = 0; i != buf_len; ++i) + + //printf("Got %d bytes: ", (int)buf_len); + + if(buf_len > 4) { - if(isprint(buf[i])) - printf("%c", buf[i]); + std::string out; + out += "\r\n"; + out += "HTTP/1.0 200 OK\r\n"; + out += "Server: Botan ASIO test server\r\n"; + out += "Host: 192.168.10.5\r\n"; + out += "Content-Type: text/html\r\n"; + out += "\r\n"; + out += "<html><body>Greets. You said: "; + out += std::string((const char*)buf, buf_len); + out += "</body></html>\r\n\r\n"; + + m_tls.queue_for_sending(reinterpret_cast<const byte*>(&out[0]), + out.size()); + m_tls.close(); } - printf("\n"); } bool tls_handshake_complete(const Botan::TLS_Session& session) { - printf("handshake complete\n"); + //printf("handshake complete\n"); return true; } tcp::socket m_socket; - Botan::TLS_Server m_tls; unsigned char m_read_buf[Botan::MAX_TLS_RECORD_SIZE]; - unsigned char m_write_buf[Botan::MAX_TLS_RECORD_SIZE]; + + // used to hold the data currently being written by the system + std::vector<byte> m_write_buf; + + // used to hold data queued for writing + std::vector<byte> m_outbox; }; class Credentials_Manager_Simple : public Botan::Credentials_Manager |