#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <curl/curl.h>
static ostringstream curl_result;
/* curl write callback, to fill tidy's input buffer... */
uint write_cb(char *in, uint size, uint nmemb, void *out)
{
int r = size * nmemb;
in[r] = '\0';
curl_result << in;
return(r);
}
static bool recaptcha_check_answer(const char *private_key, const char *remoteip,
const char *challenge, const char *response, std::string &error) {
if (!remoteip || !*remoteip) {
error = "For security reasons, you must pass the remote ip to reCAPTCHA";
return false;
}
//discard spam submissions
if (!challenge || !*challenge || !response || !*response) {
error = "Captcha challenge or response missing";
return false;
}
CURL *curl;
CURLcode res;
struct curl_httppost *formpost=NULL;
struct curl_httppost *lastptr=NULL;
if(curl_global_init(CURL_GLOBAL_SSL)) {
error = "Error initialising curl library";
return false;
}
curl = curl_easy_init();
if(!curl) {
error = "Error initialising curl library";
return false;
}
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "privatekey",
CURLFORM_COPYCONTENTS, private_key,
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "remoteip",
CURLFORM_COPYCONTENTS, remoteip,
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "challenge",
CURLFORM_COPYCONTENTS, challenge,
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "response",
CURLFORM_COPYCONTENTS, response,
CURLFORM_END);
const char *surl = "https://api-verify.recaptcha.net/verify";
curl_easy_setopt(curl, CURLOPT_URL, surl);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
#ifdef SKIP_HOSTNAME_VERFICATION
/*
* If the site you're connecting to uses a different host name that what
* they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl will refuse to connect. You can skip
* this check, but this will make the connection less secure.
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
if(res && res != CURLE_RECV_ERROR)
{
std::ostringstream err;
err << "Error " << res << " contacting captcha server";
error = err.str();
return false;
}
std::string resp = curl_result.str();
std::string::size_type pos = resp.find("\n");
std::string part1 = pos == std::string::npos ? resp : resp.substr(0, pos);
if(part1 == "true")
return true;
error = pos == std::string::npos ? "Unknown captcha error" : "Captcha error:" + resp.substr(pos);
return false;
}
This code relies on the curl library to handle the communication with the reCAPTCHA server.
Wednesday, 3 October 2012
Using reCAPTCHA from C++
I wanted to add reCAPTCHA to some old C++ CGI code, but I couldn't find a reCAPTCHA library for C++. Neither could a few other people I saw looking.
So I wrote the following code, which I am happy to share:
Subscribe to:
Post Comments (Atom)

5 comments:
are there some code lines missing at the beginning of your code ?
Thank you
Thanks - the include statement on the first line wasn't complete, because the blog editor messed with the angle brackets. I have fixed it now.
Hi,
you are also mising this:
#include "string"
#include "sstream"
where did you define
write_cb, curl_result
?
Is that better?
yes, thanks
Post a Comment