Использование libcurl в приложении C ++ для отправки данных POST из значения в файле .INI - PullRequest
1 голос
/ 24 августа 2011

Итак, у меня есть приложение C ++, которое получает значение из ключа в файле settings.INI, использует libcurl для обращения к странице PHP, публикации этих данных, и оно должно возвращать некоторые другие данные.

И это на самом деле работает, кроме получения данных из INI-файла. Если я явно введу опцию POSTFIELDS для libcurl (например, «Serial = 454534», вместо переменной, хранящей данные, полученные из моего файла).

Вот код ...
PHP:

<?
include("DBHeader.inc.php");
$Serial= $_POST['Serial'];

$sql = "SELECT * FROM `LockCodes` WHERE `sLockCode`=\"$Serial\"";
$RS=mysql_query($sql, $SQLConn);
$num_rows=mysql_num_rows($RS);

if ($num_rows>0)
{
      while ($row = mysql_fetch_array($RS))
  {
       echo $row['iLockCodeID'];
  }
}
else
{
  echo "...";
}


?>

Фрагмент кода C ++:

TCHAR szKeyValue[36];
GetPrivateProfileString(_T("Test"), _T("LockCode"), _T(""), szKeyValue, 36, _T("C:\\Test\\Settings.INI"));

CString sLockCode = szKeyValue;
CURL *curl;
CURLcode res;
CString Serial = _T("Serial=") + sLockCode;
string LCID;

curl_global_init(CURL_GLOBAL_ALL);

curl = curl_easy_init();
if (curl)
{
    curl_easy_setopt(curl, CURLOPT_URL, "http://regserver2.nyksys.com/GetLCID.php");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Serial);
    res = curl_easy_perform(curl);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeCallback);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    res = curl_easy_perform(curl);

    if (data == _T("..."))
    {
        data = "0";
        AfxMessageBox("Invalid Serial Number");
        exit(0);
    }

Мои настройки. INI в стандартном формате ..

[Test]
LockCode=1D4553C7E7228E462DBAAE267977B7CDED8A

Что происходит, когда я использую переменную «Serial» вместо ее ввода, страница PHP возвращает «...» вместо желаемого результата.

Я чувствую, что упускаю что-то очевидное. Любая помощь будет высоко оценена.

1 Ответ

2 голосов
/ 25 августа 2011

Я предполагаю, что вы определили _UNICODE, что означает, что TCHAR - это wchar_t, CString - это CStringT<wchar_t>, а код:

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Serial);

фактически передает широкийстрока символов в curl_easy_setopt(), когда функция ожидает узкую строку символов.Если ваша машина имеет младший порядковый номер, то curl_easy_setopt() интерпретирует параметр как строку "S\x00e\x00r\x00i\x00... (на машине с прямым порядком байтов это "\x00S\x00e\x00r\x00i...), и поскольку curl_easy_setopt() будет использовать strlen(), если CURLOPT_POSTFIELDSIZE не задано,полное тело запроса POST на маленькой машине Endian - S.См., Например, http://codepad.org/JE2MYZfU

Что вам нужно сделать, это использовать узкие строки символов:

#define ARRAY_LEN(arr_id) ((sizeof (arr_id))/(sizeof ((arr_id)[0])))

char szKeyValue[36];
GetPrivateProfileStringA("Test", "LockCode", "", szKeyValue, ARRAY_LEN(szKeyValue), "C:\\Test\\Settings.INI");

CURL *curl;
CURLcode res;
CStringT<char> Body = CStringT<char>("Serial=") + szKeyValue;
string LCID;

curl_global_init(CURL_GLOBAL_ALL);

curl = curl_easy_init();
if (curl)
{
    curl_easy_setopt(curl, CURLOPT_URL, "http://regserver2.nyksys.com/GetLCID.php");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Body);
    res = curl_easy_perform(curl);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeCallback);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    res = curl_easy_perform(curl);
//...

Кроме того, ваш PHP-скрипт выглядит уязвимым для SQL-инъекций.

РЕДАКТИРОВАТЬ: Еще одна вещь.Вы устанавливаете CURLOPT_POST на 1?

    curl_easy_setopt(curl, CURLOPT_POST, 1);
...