Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Libcurl C++ - How do I post form data for this specific form?

How do I post and then submit form data for the following form using libcurl and C++?

<form id="loginContainer" class="controllerContainer" action="/j_spring_security_check" method="post">

<h2>Login</h2>
<hr>
<fieldset>

    <div class="field">
        <input class="standard" name="j_username" autocomplete="off" autocapitalize="off" size="25" placeholder="Enter Username">
    </div>
    <div class="field">
        <input class="standard" name="j_password" type="password" value="" size="25" autocapitalize="off" autocomplete="off" placeholder="Enter Password (case-sensitive)">
    </div>
    <div class="field">
        <button class="login" type="submit"></button>
    </div>

</fieldset>

I have tried several examples from the curl website but none of them worked for me.

EDIT: Here is the function I made to login

void loginToWebsite(std::string url, std::string userAgent, std::string username, std::string password)
{
    CURL *curl;
    CURLcode res;
    curl = curl_easy_init();

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, ("j_username=" + username + "&j_password=" + password).c_str());
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3L);
        curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt");

        res = curl_easy_perform(curl);
    }
like image 956
thecppnerd93 Avatar asked Sep 18 '25 17:09

thecppnerd93


1 Answers

You are leaking the curl object. You need to call curl_easy_cleanup() when you are done using it.

But, more importantly, you are using CURLOPT_POSTFIELDS incorrectly. You are passing it a char* pointer to a temporary std::string that goes out of scope immediately, leaving curl with a dangling pointer to invalid memory by the time curl_easy_perform() is called. You need to either

  • use a local std::string variable

  • use CURLOPT_COPYPOSTFIELDS.

You also need to url-encode the form parameters that you post. You can use curl_easy_escape() for that.

With that said, try something more like this:

#include <string>
#include <sstream>

void loginToWebsite(const std::string &url, const std::string &userAgent, const std::string &username, const std::string &password)
{
    CURL *curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
        curl_easy_setopt(curl, CURLOPT_POST, 1L);

        std::ostringstream oss;

        oss << "j_username=";
        char *encoded = curl_easy_escape(curl, username.c_str(), username.length());
        if (encoded)
        {
            oss << encoded;
            curl_free(encoded);
        }

        oss << "&j_password=";
        encoded = curl_easy_escape(curl, password.c_str(), password.length());
        if (encoded)
        {
            oss << encoded;
            curl_free(encoded);
        }

        std::string postdata = oss.str();    
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata.c_str());

        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3L);
        curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt");

        CURLcode res = curl_easy_perform(curl);
        // use res as needed...

        curl_easy_cleanup(curl);
    }
}
like image 70
Remy Lebeau Avatar answered Sep 20 '25 07:09

Remy Lebeau