|
Boost : |
From: Abu Amar (alwaysme109_at_[hidden])
Date: 2008-08-21 14:50:07
Hi,
I am trying to do a simple POP3S client. I am using the boost::asio sockets and SSL wrapper. Somehow, the output from the sock read is directed to the input of the sock write. Any idea?
The code snippet is below, but here is the output of my program first (I replaced the IP with x's)
-bash# ./main 209.85.199.111 995 foo.bar_at_[hidden] pass_in_plain_text
Got RES (66) bytes
+OK Gpop ready for requests from xxx.xxx.xxx.xxx c20pf1156691rvf.3
Sent REQ: APOP foo.bar_at_[hidden] pass_in_plain_text
Got RES (36) bytes
-ERR bad command c20pf1156691rvf.3
Sent REQ: STAT
Read failed: End of file
Exception: End of file
and here is the code snippet that produced this input
enum { max_length = 8192 };
class client
{
public:
client(boost::asio::io_service& io_service, boost::asio::ssl::context& context,
boost::asio::ip::tcp::endpoint& endpoint)
: socket_(io_service, context)
{
//connect to the pop3 server
socket_.lowest_layer().async_connect(endpoint,
boost::bind(&client::handle_connect, this,
boost::asio::placeholders::error));
}
~client()
{
socket_.lowest_layer().close();
}
void handle_connect(const boost::system::error_code& error)
{
if (!error)
{
//do the SSL handshake
socket_.async_handshake(boost::asio::ssl::stream_base::client,
boost::bind(&client::handle_handshake, this,
boost::asio::placeholders::error));
}
else
{
std::cerr << "Connection failed: " << error << "\n";
boost::asio::detail::throw_error(error);
}
}
void handle_handshake(const boost::system::error_code& error)
{
if (error)
{
std::cerr << "SSL Handshaking failed: " << error << "\n";
boost::asio::detail::throw_error(error);
}
}
void write(std::string buffer)
{
str_req=buffer;
boost::asio::async_write(socket_,
boost::asio::buffer(str_req),
boost::bind(&client::handle_write, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_write(const boost::system::error_code& error,
size_t bytes)
{
if (!error)
{
std::cout << "Sent REQ: " << str_req <<std::endl;
try{
boost::asio::async_read_until(socket_, buff_, "\r\n",
boost::bind(&client::handle_read_until, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}catch(const boost::system::system_error &err){
std::cerr << " code: " << err.code().value() << " :" << err.code().message() << std::endl;
}
}
else
{
std::cerr << "Write failed: " << error.message() << "\n";
boost::asio::detail::throw_error(error);
}
}
void read()
{
try{
boost::asio::async_read_until(socket_, buff_, "\r\n",
boost::bind(&client::handle_read_until, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}catch(const boost::system::system_error &err){
std::cerr << " code: " << err.code().value() << " :" << err.code().message() << std::endl;
}
}
void handle_read_until(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
std::cout << "Got RES (" << bytes_transferred<<") bytes\n";
std::cout << &buff_;
std::cout << "\n";
}
else
{
std::cout << "Read failed: " << error.message() << "\n";
boost::asio::detail::throw_error(error);
}
}
private:
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
boost::asio::streambuf buff_; //for receiving
std::string str_req; //for sending
};
int main(int argc, char* argv[])
{
try
{
if (argc != 5)
{
std::cerr << "Usage: " << argv[0] << " <host> <port> <user> <pass>\n";
return 1;
}
boost::asio::io_service io_service;
boost::asio::ssl::context ctx(io_service, boost::asio::ssl::context::sslv23);
ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
boost::asio::ip::tcp::endpoint endpoint(
boost::asio::ip::address::from_string(argv[1]), atoi(argv[2]));
client c(io_service, ctx, endpoint);
io_service.run(); //should execute till handshake completes
//read the pop3 greeting
io_service.reset();
io_service.post(boost::bind(&client::read,&c));
io_service.run();
//send the authentication command
std::string str_cmd="APOP " + std::string(argv[3]) + " " + std::string(argv[4]) +"\r\n";
io_service.reset();
io_service.post(boost::bind(&client::write,&c,str_cmd));
io_service.run();
//get how many messages are in the inbox
str_cmd="STAT\r\n";
io_service.reset();
io_service.post(boost::bind(&client::write,&c,str_cmd));
io_service.run();
//quit the pop3 session
str_cmd="QUIT\r\n";
io_service.reset();
io_service.post(boost::bind(&client::write,&c,str_cmd));
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk