Making SSL Connection using Boost Asio

2019-03-07 04:43发布

问题:

Basically a have the code to make an http call to server and handle the response but I want to secure the data travelling and make the call https.

For that I have this executor.hpp

class Executor
{
public :
  Executor(Cli &cli):ssock(svc)
  {
      //! Get a list of endpoints corresponding to the server name.
    boost::asio::ip::tcp::resolver resolver(svc);
    boost::asio::ip::tcp::resolver::query query(cli.getIP(), "8080");
    endpoint_iterator = resolver.resolve(query);
  }

  int connect();
  int write(RequestCreator &requestcreator);

boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &getSocket() { return    ssock; }

private :

boost::asio::io_service svc;
boost::asio::ssl::context ctx(svc, ssl::context::method::sslv23_client);
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssock(svc, ctx);
boost::asio::ip::tcp::resolver::iterator endpoint_iterator;

};

and this executor.cpp

int Executor::connect()
{
  boost::system::error_code ec ;
  boost::asio::connect(ssock.lowest_layer(), endpoint_iterator );
  ssock.handshake(boost::asio::ssl::stream_base::handshake_type::client);

  if (ec)
  {
    ssock.lowest_layer().close();
    svc.stop();
    return 0;
  }
  return 1;
 }

 int Executor::write(RequestCreator &requestCreator)
 {
   boost::system::error_code ec ;
   boost::asio::write(ssock, requestCreator.getRequest(), ec);
   if (ec)
   {
     ssock.lowest_layer().close();
     svc.stop();
     return 0;
   }
  return 1;
}

and below is the full error on compiler

c:\cygwin64\home\admin\sandbox\webcli\executor.hpp(30) : error C2061:   syntax error : identifier 'svc'
c:\cygwin64\home\admin\sandbox\webcli\executor.hpp(31) : error C2061: syntax error : identifier 'svc'
c:\cygwin64\home\admin\sandbox\webcli\executor.hpp(15) : error C2436: 'ssock' : member function or nested class in constructor initializer list
c:\cygwin64\home\admin\sandbox\webcli\executor.hpp(25) : error C3867: 'Executor::ssock': function call missing argument list; use '&Executor::ssock' to create a pointer to member
c:\cygwin64\home\admin\sandbox\webcli\executor.hpp(25) : error C2440:  'return' : cannot convert from 'boost::asio::ssl::stream<Stream> (__cdecl   Executor::* )(void)' to 'boost::asio::ssl::stream<Stream> &'
    with
    [
        Stream=boost::asio::ip::tcp::socket
    ]

回答1:

  1. The error message refers to a class Executor which isn't in your code. Are you compiling the right thing?

  2. boost::asio::ssl::context ctx(svc, ssl::context::method::sslv23_client);

    this should not compile, unless svc is also a type in your code. Use braces.

  3. boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssock(svc, ctx);

    This will most definitely not compile then. Same problem.

  4. Connect(Data &data) : socket(ioService) {

    • Socket is not declared. What is it? (Assuming you might have meant ssock).
    • ioService is not declared. What is it? (Assuming you might have meant svc).
  5. Contrast

     int Connect::write(CreatRequest &requestCreator) {
    

    with

     int write(RequestCreator &requestcreator);
    

    Which is it? Compilers are not going to guess what you mean. If you mean RequestCreator you're gonna have to type that, and not CreatRequest.

All in all, there's no real question, just a lot of blindly copied/paste "code-like" text.

Fixing all the above in the most straightforward way possible:

Live On Coliru

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

struct Data {
    std::string getIP() const { return "localhost"; }
};


class Connect {
  public:
    Connect(Data &data) {
        //! Get a list of endpoints corresponding to the server name.
        boost::asio::ip::tcp::resolver resolver(svc);
        boost::asio::ip::tcp::resolver::query query(data.getIP(), "8080");
        endpoint_iterator = resolver.resolve(query);
    }

    int connectServer();
    struct RequestCreator {
        auto getRequest() const { return boost::asio::buffer("GET / HTTP/1.1\r\n\r\n"); }
    };
    int write(RequestCreator &requestcreator);

    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &getSocket() { return ssock; }

  private:
    boost::asio::io_service svc;
    boost::asio::ssl::context ctx{svc, boost::asio::ssl::context::method::sslv23_client};
    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssock{svc, ctx};
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator;
};

int Connect::connectServer() {
    boost::system::error_code ec;

    boost::asio::connect(ssock.lowest_layer(), endpoint_iterator);
    if (ec) {
        ssock.lowest_layer().close();
        svc.stop();
        return 0;
    }
    return 1;
}

int Connect::write(RequestCreator &requestCreator) {
    boost::system::error_code ec;

    boost::asio::write(ssock, requestCreator.getRequest(), ec);
    if (ec) {
        ssock.lowest_layer().close();
        svc.stop();
        return 0;
    }
    return 1;
}

main() {
    Data data;
    Connect c(data);
}