ことはじめ

にほんごのれんしゅうにっき

cpp-netlibを導入した

C++でHTTP通信がしたくなったのでcpp-netlibに手を出したのだが...
情弱ゆえにおかしな行動をとって勝手に嵌っていた.
結論まで読み飛ばしてOKです.

ここから古いものを落として使っていた

https://github.com/cpp-netlib/cpp-netlib/downloads
→ 型が合わないとかで上手くビルドできない
一部の必要な共有ライブラリはビルドできていたのだがまともに使えず(後述).

最新をcloneしてくれば良いのでは??

cpp-netlibをcloneしてくる
git submodule init
git submodule update
cmake .
uri, deps/gmock, deps/gtest のCMakeLists.txtが無いと怒られる(git submodule で引っ張ってくるんじゃないのかよ...)
uri, deps/gmock, deps/gtest は別途cloneする必要がある
その後cmake . するも
/deps/igloo/igloo/external/snowhouse の中身がないとエラー
これも別途cloneが必要
http/test/v2/client/features 以下にある.cpp でエラーがでるので
return TestRunner::RunAllTests(argc, const_cast(argv));

return TestRunner::RunAllTests(argc, argv);
と書き換えて無理やりテストを通す

→ ライブラリが生成されない (テストはしらせてただけっぽい?)

多分設定でどうにか出来るんだろうけどそれまでがめんどくさすぎる...

結論

ここから新しいの持ってきて使いましょう(解決)
http://cpp-netlib.org/
気付かなかった自分が悪い (何故か見逃していた)
基本的にCMakeすればおわりです.
ビルド大変って聞いていたけど昔の話だったようだ.
BoostやOpenSSLが入ってればパス通すだけです.

サンプル

TwitterAPI にあくせす

#define BOOST_NETWORK_ENABLE_HTTPS
#include <boost/network/protocol/http/client.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/asio.hpp>

void callback(boost::shared_ptr<boost::asio::io_service>& io_service,
              const boost::iterator_range<const char*>& range,
              const boost::system::error_code& error) {
    if (!error) {
        std::cout << range << std::endl;
        io_service->stop();
    }
}

int main() {
    using namespace boost::network;
    using client_t = boost::network::http::basic_client<boost::network::http::tags::http_async_8bit_tcp_resolve, 1, 1>;
    using respons_headers = boost::network::headers_range<client_t::response>::type;
    using client_options = boost::network::http::client_options<boost::network::http::tags::http_async_8bit_tcp_resolve>;
    using string_t = boost::network::string<boost::network::http::tags::http_async_8bit_tcp_resolve>::type;

    // Twitterのアクセストークンを手に入れたい
    const std::string credentials = "consumer_key と comsumer_secret をコロンでつなげてbase64エンコードしたもの";
    client_t::request request("https://api.twitter.com/oauth2/token");
    request << header("User-Agent", "asio")
            << header("Connection", "close")
            << header("Authorization", "Basic " + credentials)
            << header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
            << header("Content-Length", "29");
    
    auto io_service = boost::make_shared<boost::asio::io_service>(); // std::sharedだと怒られる...
    client_options options;
    options.io_service(io_service);
    client_t client(options);
    client_t::response response = client.post(request,
                                              string_t("grant_type=client_credentials"),
                                              boost::bind(&callback, io_service, _1, _2));
    io_service->run();                                        
}

HTTPのリクエストヘッダの追加など見やすくていい感じ.
io_service->run() でPOSTして, 返ってきたデータはcallback関数に処理させてます.
client_t (と名をつけたもの) のコンストラクタに直接 io_service を渡せないので client_optionsを経由させてあげる必要があります.
というのも basic_client のコンストラクタが BOOST_PARAMETER_CONSTRUCTOR で生成されていて io_service を受け取るコンストラクタは生成されないからです.
ちなみに, 古いバージョンでまともに使えないといったのがここで, コンストラクタは io_service を受け付けないし client_options は受け付けてくれるらしいがそもそも古いバージョンに client_options になんてものは存在しなかったのだ.

結果

{"errors":[{"code":99,"label":"authenticity_token_error","message":"Unable to verify your credentials"}]}

ぐぬぬ