I've tried to make a "synchronous" recaptcha verification using the
underlaying Wt's IOService, asynchronous in nature. The code is the
following one:

// response_ready is just a std::condition_variable (I have tested with
boost:: as well
// for mutex, locks and the condition_variable and the result is the same).
void google_recaptcha::p_verify(std::string const& recaptcha_response)
{
    auto* client = new Wt::Http::Client(this);
    client->done().connect(this, &google_recaptcha::p_on_done);

    std::ostringstream os;
    os << "secret=" << st_server_secret << "&response=" <<
recaptcha_response;

    Wt::Http::Message msg;
    msg.addBodyText(os.str());
    msg.setHeader("Content-Type", "application/x-www-form-urlencoded");

    client->post("https://www.google.com/recaptcha/api/siteverify";, msg);

    std::unique_lock<std::mutex> lk(wait_mutex);
    response_ready.wait_for(lk, std::chrono::seconds(15),
                                            [this]() -> bool { return
b_is_done; });
}

void google_recaptcha::p_on_done(boost::system::error_code const& err,
                                                         Wt::Http::Message
const& response)
{
    // Suppose everything works fine, to avoid dealing with exceptions
(temporarily).
    std::cout << "IN SLOT" << std::endl;

    std::stringstream ss(response.body());
    boost::property_tree::ptree ptree;
    boost::property_tree::read_json(ss, ptree);

    auto success_optional = ptree.get_optional<bool>("success");
    o_verified.emit(success_optional.get()); // o_verified is a Wt::Signal.

    std::lock_guard<std::mutex> lk(wait_mutex);
    b_is_done = true;
    response_ready.notify_one();
}

And I don't know why, but when the JSignal is emitted (p_verified is
connected to a JSignal), the thread is blocked at the `wait_for` line, and,
after those 15 seconds of waiting, the `p_on_done` is method is called (it
prints "IN SLOT"). So, they are not executed concurrently. Could it be
because of the `strand` object which Wt's manages internally?

I don't know if the `post` request ends and the `p_on_done` slot is which
is waiting, or the `post` request is which waits. The thing is that it
seems Wt tries to dispatch the `p_on_done` slots in the same thread than
the `p_verify` slot's, so the block.

How can I force `p_on_done` is executed concurrently? I'm interested in
knowing both, the solution and why my approach is a blocking one.
------------------------------------------------------------------------------
_______________________________________________
witty-interest mailing list
witty-interest@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/witty-interest

Reply via email to