Curl не будет публиковать несколько данных на сервер

0

Я пишу приложение для работы, которое должно выполнять HTTP-запросы на сервер и получать ответ в JSON.

На данный момент мой код подключается к серверу и получает ответ назад, и это здорово. Однако мне также нужно отправить данные на сервер, который будет обрабатывать его, и отправить мне jSON.

Моя проблема в том, что я могу отправить, благодаря POSTFIELDS, только одно "поле" и не получит никакого ответа, если я вложу больше этого.

Код следующий:

// writefunc works, so there is no point adding its code in here
size_t Simulator::writefunc(void *ptr, size_t size, size_t nmemb, struct string *buffer_in);

void Simulator::move(Player *player)
{
    std::ostringstream ss_url;
    ss_url << API_URL << "functionCalled";
    char const *url = ss_url.str().c_str();

    std::ostringstream ss_postfields;

    // This will not work - And all values do NOT contain any space
    // The server do NOT receive any data (in POST and GET)
    ss_postfields  << "user_name=" << player->getName()
                        << "&user_secret=" << player->secret()
                            << "&app_id=" << player->getApp_id()
                                << "&lat=" << player->getLocation()->getLat()
                                    <<"&lon=" << player->getLocation()->getLon();

    // This will not work either
    // ss_postfields << "user_name=nicolas&app_id=2";

    // This works and will send the data to the server, which will receive and process it.
    // ss_postfields << "user_name=" << player->getName();

    const char *postfields = ss_postfields.str().c_str();

    CURL *curl_handle;
    curl_global_init(CURL_GLOBAL_ALL);
    curl_handle = curl_easy_init();

    if(curl_handle){
        struct string s;
        init_string(&s);

        curl_easy_setopt(curl_handle, CURLOPT_URL, url);
        curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writefunc);
        curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
        curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &s);
        curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postfields);
        curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, strlen(postfields));
        curl_easy_setopt(curl_handle, CURLOPT_POST, 1L);
        CURLcode res = curl_easy_perform(curl_handle);

        if(CURLE_OK != res)
        {
            printf("Error: %s\n", strerror(res));
            exit(0);
        }

        printf("%s\n", s.ptr);
        curl_easy_cleanup(curl_handle);
        curl_global_cleanup();
    }
}

Я думал, что я также дам вывод CURLOPT_HEADER и CURLOPT_VERBOSE, когда я отправляю только одно значение или несколько значений:

Когда я отправляю только одно значение:

* About to connect() to localhost port 8888 (#0)
*   Trying ::1...
* connected
* Connected to localhost (::1) port 8888 (#0)
> POST [api_url]  HTTP/1.1
Host: localhost:8888
Accept: */*
Content-Length: 22
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 22 out of 22 bytes
< HTTP/1.1 200 OK
< Date: Sun, 24 Nov 2013 17:25:14 GMT
< Server: Apache
< X-Powered-By: PHP/5.3.20
< Cache-Control: no-cache
< X-Debug-Token: a41727
< Transfer-Encoding: chunked
< Content-Type: application/json
< 
* Connection #0 to host localhost left intact
0
HTTP/1.1 200 OK
Date: Sun, 24 Nov 2013 17:25:14 GMT
Server: Apache
X-Powered-By: PHP/5.3.20
Cache-Control: no-cache
X-Debug-Token: a41727
Transfer-Encoding: chunked
Content-Type: application/json

[ OUTPUT FROM SERVER HERE ]

* Closing connection #0

И когда я отправляю несколько значений:

* About to connect() to localhost port 8888 (#0)
*   Trying ::1...
* connected
* Connected to localhost (::1) port 8888 (#0)
> POST [api_url] HTTP/1.1
Host: localhost:8888
Accept: */*
Content-Length: 1
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 1 out of 1 bytes
< HTTP/1.1 200 OK
< Date: Sun, 24 Nov 2013 17:30:13 GMT
< Server: Apache
< X-Powered-By: PHP/5.3.20
< Cache-Control: no-cache
< X-Debug-Token: d1947e
< Transfer-Encoding: chunked
< Content-Type: application/json
< 
* Connection #0 to host localhost left intact
0
HTTP/1.1 200 OK
Date: Sun, 24 Nov 2013 17:30:13 GMT
Server: Apache
X-Powered-By: PHP/5.3.20
Cache-Control: no-cache
X-Debug-Token: d1947e
Transfer-Encoding: chunked
Content-Type: application/json

[ OUTPUT FROM SERVER HERE ]

* Closing connection #0
Теги:
curl
post
http
get

2 ответа

0

Поскольку я был в спешке, я переписал все, используя HTTP-сокеты. Но я не мог справиться с этой проблемой, поэтому я вернулся к ней и, наконец, нашел проблему. Кажется, что cUrl не очень нравится потоки.

Я думал, что обновляю этот пост в случае, если у кого-то будет такая же проблема:

Поэтому что-то вроде следующего НЕ будет работать:

std::ostringstream ss_postfields;

// This will not work - And all values do NOT contain any space
// The server do NOT receive any data (in POST and GET)
ss_postfields  << "user_name=" << player->getName()
                    << "&user_secret=" << player->getSecret();

const char *postfields = ss_postfields.str().c_str();
// ...
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postfields);
CURLcode res = curl_easy_perform(curl_handle);

Однако, и причудливо, это будет работать:

std::string str_postfields;
std::string user_name = player->getName();
std::string user_secret = player->getSecret();
std::string str_postfields = "user_name=" +user_name +"&user_secret=" +user_secret;

const char *postfields = str_postfields.c_str();
// ...
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postfields);
CURLcode res = curl_easy_perform(curl_handle);
  • 1
    Одной из возможных причин, по которой не работает версия, основанная на потоке строк, может быть то, что postfields в коде - const char *postfields = ss_postfields.str().c_str(); - фактически будет указывать на память, которая уже удалена, потому что str() возвращает временный строковый объект.
  • 0
    В самом деле, я заметил позже, что str () возвращает временный объект, как вы сказали. Таким образом, на самом деле работало следующее: string s = ss_postfields.str (); const char * postfields = s.c_str ();
0

Ну, похоже, вам не хватает знака равенства!

   ss_postfields  << "user_name=" << player->getName()
                    << "&user_secret=" << player->secret()
                        << "&app_id=" << player->getApp_id()
                            << "&lat=" << player->getLocation()->getLat()
                                <<"&lon=" << player->getLocation()->getLon();

вместо

   ss_postfields  << "user_name=" << player->getName()
                    << "&user_secret" << player->secret()
                        << "&app_id=" << player->getApp_id()
                            << "&lat=" << player->getLocation()->getLat()
                                <<"&lon=" << player->getLocation()->getLon();
  • 0
    Знак равенства есть в моем исходном коде, но спасибо, я его отредактирую. Кроме того, как вы можете видеть в коде, я закомментировал строку только с двумя значениями, что не работает. Из того, что дает нам CURLOPT_HEADER / VERBOSE, мы видим, что при простом значении отправляется 22 байта и 1 байт для нескольких значений. Поэтому я попытался выяснить, могу ли я изменить размер пост-полей и установить его равным 46 байтам при отправке 2-х значений, и сервер получит некоторые странные данные, которые кажутся адресом указателя.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню