2016-08-27 2 views
-2

Я пытаюсь отправить данные в Apache, который работает на localhost. Данные правильно формируется в формате JSON, но, когда я отправить данные с помощью Libcurl и на PHP веб-сервер повторил я из строки с помощьюC++ libcurl отправка неверных данных

echo file_get_contents("php://input"); 

Это возвращают случайные символы, это данные, которые сервер вторит из

`é ²²²²▌▌▌▌4Ég\▌ îHGáF 

и в C++, когда я эхо из json, он печатает правильно.

Request.C++

void Request::execute() { 
auto curl = curl_easy_init(); 

if (curl) { 
    curl_easy_setopt(curl, CURLOPT_URL, mUrl); 
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); 
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "RoBot/ Version 1"); 
    curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L); 
    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1); 

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write); 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &mResponse); 
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &mHeaders); 
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &mResponseCode); 

    if (!mData.empty()) { 
     curl_easy_setopt(curl, CURLOPT_POST, true); 
     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, mData); 
     curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, mData.size()); 
    } 

    if (mHeadersData) { 
     curl_easy_setopt(curl, CURLOPT_HEADER, true); 
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, mHeadersData); 
    } 

    curl_easy_perform(curl); 
    curl_easy_cleanup(curl); 
    curl_slist_free_all(mHeadersData); 
    curl = nullptr; 
} 

И это, как я его выполнения.

json data; 
data["username"] = username; 
data["password"] = password; 
std::cout << data.dump() << std::endl; 

//Request* request = new Request("https://www.roblox.com/MobileAPI/Login"); 
Request* request = new Request("http://localhost:8080/Projects/"); 
request->setPostData(data.dump()); 
//request->addHeader("Content-Type: application/json"); 
request->execute(); 

std::cout << request->getResponse() << std::endl; 
std::cout << request->getHeaders() << std::endl; 

Это то, что получить выводится на консоль

Username: id 
Password: kf 
{"password":"kf","username":"id"} 
`é ²²²²▌▌▌▌4Ég\▌ îHGáF 
HTTP/1.1 200 OK 
Date: Sat, 27 Aug 2016 09:15:07 GMT 
Server: Apache/2.4.6 (Win32) PHP/5.4.17 
X-Powered-By: PHP/5.4.17 
Content-Length: 36 
Content-Type: text/html 

Любые идеи, почему?

[Изменено]

Функция записи показано ниже

size_t write(void *ptr, size_t size, size_t nmemb, std::string* data) { 
data->append((char*)ptr, size * nmemb); 
return size * nmemb; 
} 

Я устанавливаю данные делать, как следовать

void Request::setPostData(std::string data) { 
mData = data; 
} 

[РЕДАКТИРОВАНИЕ 2]

Так что я теперь знаю проблему, очевидно, libcurl принимает только char *, и я отправляю std :: string. Есть ли какой-то путь вокруг этого, так как моя библиотека json конвертирует json-объект в std :: string?

+0

Мне кажется, что у вас есть неисчерпаемая строка стиля C. Пожалуйста, покажите нам функции 'setPostData' и' write'. –

+1

Этого недостает всего несколько бит информации. Что такое 'write()' (потому что libc 'write()' имеет совсем другую подпись, чем функция записи curl)? Что такое 'mData'? 'curl_easy_setopt()' является функцией varargs, поэтому преобразование типа кажется обязательным. – dhke

+0

Хорошо, я обновил его с дополнительной информацией в соответствии с запросом. – Kurieita

ответ

-2

Возможно, попробуйте установить следующие заголовки запроса?

Accept: текст/обычный
Accept-Charset: UTF-8
Accept-Encoding: identity

(возможно, Content-типа, а также, чтобы убедиться, что сервер интерпретирует то, что вы отправляете правильный путь)

ref

+0

Эти заголовки могут быть отменены, если веб-сервер передает ответ в utf16 и/или сжат, а клиентская библиотека предоставляет его в raw. Я не предполагал, что это решение, просто нужно сделать все возможное, чтобы избежать несоответствия кодирования между ожидаемым/фактическим (см. «Возможно, попробуйте ...»?) –

+0

@ DanielStenberg На данный момент я отправил свой два пояснения относительно функции записи и m_data не были доступны (и для меня было время спать). Почему вы решили опубликовать его как ответ, а не комментарии - ограниченные возможности форматирования текста в комментариях. –

+0

@Ahmad Извините, я только выдвинул гипотезу, я не был уверен, что я предлагаю категорически верно. поэтому «Может быть, попытайтесь что-то сделать» вместо «Может быть, вы должны» и «Возможно, Content-type». –

2

Эта линия является неправильным:

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, mData); 

За документацию Libcurl:

CURLOPT_POSTFIELDS explained

Pass полукокса * в качестве параметра, указывая полные данные для отправки в работе с HTTP POST. Вы должны убедиться, что данные отформатированы так, как вы хотите, чтобы сервер их получал. libcurl не будет конвертировать или кодировать его для вас каким-либо образом. Например, веб-сервер может предположить, что эти данные кодируются по URL-адресу.

Данные, указанные на НЕ, не копируются библиотекой: как следствие, она должна быть сохранена вызывающим приложением до тех пор, пока соответствующая передача не завершится. Это поведение можно изменить (поэтому libcurl копирует данные), установив опцию CURLOPT_COPYPOSTFIELDS.

Вы полагаетесь на внутренней реализации std::string начать с char* указателем на символьные данные, но не гарантируется. Строка должна выглядеть следующим образом, вместо:

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, mData.c_str()); 

Это гарантирует вам получить char* указатель на символьные данные. Указатель останется действительным до тех пор, пока std::string не будет изменен или уничтожен.

+0

Вау, клянусь, я попробовал это, и это не сработало. Видимо, теперь это сработало. Большое спасибо. – Kurieita

Смежные вопросы