LINUX.ORG.RU

C++ curl задать Content-Type:text/xml


0

1

Добрый день! Хочу попробовать отправлять SOAP запросы и получать ответы с помощью функций curl_easy_send и curl_easy_recv. Может, кто-то уже реализовывал нечто подобное? Есть еще способ c помощью gsoap, но хочется попробовать пока таким образом. Сталкиваюсь с проблемой, описанной http://stackoverflow.com/questions/7441071/regarding-a-handle-for-soap-respon... Не подскажете, где прописывается Content-Type:text/xml? Может, в библиотеке curl есть опция для этого?


Едрена сковородка!

Маша, может быть, ты сначала документацию почитаешь? Я тебе уже 1 или 2 темы назад кинул ссылку на стандарт, где твой SOAP расписан. Ну неужто трудно прочесть?

Anon
()
Ответ на: комментарий от wakuwaku

В примере, который я приводила, вот так struct curl_slist *headerlist=NULL; headerlist = curl_slist_append(headerlist, «Content-Type:text/xml»); проблему не решает.

Masha
() автор топика
Ответ на: комментарий от Masha

тут всё есть, для начала стоило бы убедиться, что такой вариант вообще подходит. В сети должны быть готовые примеры, но информации по этим 3 ссылкам более чем достаточно.

wakuwaku ★★★★
()
Ответ на: комментарий от wakuwaku

Спасибо! Пока пробовала вот так:


#include <stdio.h>
#include <string.h>
#include <curl/curl.h>

/* Auxiliary function that waits on the socket. */ 

int main(void)
{
  CURL *curl;
  CURLcode res;
  /* Minimalistic http request */ 
 	const char *request = "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
 xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
 xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">
	<soap:Body>
		...
	</soap:Body>
</soap:Envelope>";

size_t iolen;

  struct curl_slist *headerlist=NULL;
  struct curl_httppost *formpost=NULL;
  struct curl_httppost *lastptr=NULL;

  headerlist = curl_slist_append(headerlist, "Content-Type:text/xml");

  curl = curl_easy_init();
  curl_formadd(&formpost, &lastptr, CURLFORM_CONTENTTYPE, "text/xml",  CURLFORM_END);

  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "46.173.209.251:8083/PosProcessing/POSProcessing.asmx");
      //указываем прокси сервер
      curl_easy_setopt(curl, CURLOPT_PROXY, "10.7.136.61:8080");
	   curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "USER:123456");
 curl_easy_setopt(curl, CURLOPT_USERPWD, "user:Password");

    /* Do not do the transfer - only connect to host */ 
    curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);


    res = curl_easy_perform(curl);

    if(CURLE_OK != res)
    {
      printf("No connection to server");
      printf("Error: %s\n", strerror(res));
      return 1;
    }

curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);

    puts("Sending request.");
    /* Send the request. Real applications should check the iolen
     * to see if all the request has been sent */ 
    res = curl_easy_send(curl,request, strlen(request), &iolen);

    if(CURLE_OK != res)
    {
      printf("No sending");
      printf("Error: %s\n", curl_easy_strerror(res));
      return 1;
    }
    puts("Reading response.");

    /* read the response */ 

printf("ok1 \n");
      char buf[10240];
  res = curl_easy_recv(curl, buf, 10240, &iolen);
 //printf("ok2 \n");
      if(CURLE_OK != res)

     {
     printf("Not receiving");
printf("Error: %s\n", strerror(res));

       }
	   
else{  

printf("ok2 \n");
printf("data %s \n", buf);


    }

    /* always cleanup */ 
	//curl_slist_free_all(headerlist); 
    curl_easy_cleanup(curl);
	curl_formfree(formpost);
    curl_slist_free_all (headerlist);
  }
  return 0;
}

Masha
() автор топика
Ответ на: комментарий от Masha

Возникает описанная ошибка:

Sending request. Reading response. ok1 Not receivingError: .lib section in a.out corrupted

Masha
() автор топика
Ответ на: комментарий от wakuwaku

Да вот даже не знаю, подходит такой вариант или не подходит...Вроде казалось бы довольно стандартная задача...

Masha
() автор топика
Ответ на: комментарий от Masha
#include <stdio.h>
#include <curl/curl.h>

const char *request =
"<s:Envelope "
"xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" "
"xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" "
"xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\" "
">"
  "<s:Body>"
    "<x:FlickrRequest xmlns:x=\"urn:flickr\">"
      "<method>flickr.test.echo</method>"
      "<name>value</name>"
    "</x:FlickrRequest>"
  "</s:Body>"
"</s:Envelope>";

int main(void)
{
  CURL *curl;
  CURLcode res;

  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);

  /* get a curl handle */
  curl = curl_easy_init();
  if(curl) {
    /* First set the URL that is about to receive our POST. This URL can
       just as well be a https:// URL if that is what should receive the
       data. */
    curl_easy_setopt(curl, CURLOPT_URL, "http://api.flickr.com/services/soap/");
    /* Now specify the POST data */

    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);

    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));

    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  curl_global_cleanup();
  return 0;
}
anonymous
()
Ответ на: комментарий от anonymous

с приемом данных в программе:

#include <stdio.h>
#include <curl/curl.h>

const char *request =
"<s:Envelope "
"xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" "
"xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" "
"xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\" "
">"
  "<s:Body>"
    "<x:FlickrRequest xmlns:x=\"urn:flickr\">"
      "<method>flickr.test.echo</method>"
      "<name>value</name>"
    "</x:FlickrRequest>"
  "</s:Body>"
"</s:Envelope>";


size_t write_data(void *ptr, size_t size, size_t count, void *stream)
{
    printf("DATA: %s", (char*)ptr);
    return count*size;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);

  /* get a curl handle */
  curl = curl_easy_init();
  if(curl) {
    /* First set the URL that is about to receive our POST. This URL can
       just as well be a https:// URL if that is what should receive the
       data. */
    curl_easy_setopt(curl, CURLOPT_URL, "http://api.flickr.com/services/soap/");
    /* Now specify the POST data */

    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);

    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));

    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  curl_global_cleanup();
  return 0;
}

anonymous
()
Ответ на: комментарий от Masha

curl_easy_send - sends raw data over an «easy» connection

посылает чистые данные, http заголовок нужно дописывать.

для отладки ethernet можно использовать tcpdump, wireshark

anonymous
()
Ответ на: комментарий от anonymous

Блин, хватит кормить её. Я конечно всё понимаю, но игнорирование половины форума, твердящей ей, что надо бы пойти изучить основы ради приличия - это уже наглость.

false ★★★★★
()
Ответ на: комментарий от anonymous

Спасибо большое! У Вас так работало? У меня сервер отвечает The server cannot service the request because the media type is unsupported.

Masha
() автор топика
Ответ на: комментарий от Masha

ты хотя поставь нормальный редактор, блин, который нормально умеет форматировать отступы

lazyklimm ★★★★★
()
Ответ на: комментарий от anonymous

Да, вот я вроде пыталась задавать заголовок, но как-то,видимо,криво. headerlist = curl_slist_append(headerlist, «Content-Type:text/xml»);

curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);

Masha
() автор топика
Ответ на: комментарий от anonymous

Спасибо Вам большое!

Выкладываю рабочий вариант, нужно было только заголовок написать так, как я пробовала с curl_easy_send() и curl_easy_recv()


#include <stdio.h>
#include <curl/curl.h>
#include <string>
#include <iostream>

static std::string buffer;

const char *request =
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
 xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
 xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">
	<soap:Body>
		...
	</soap:Body>
</soap:Envelope>";


size_t write_data(char *ptr, size_t size, size_t count, std::string *buffer)
{
	int result = 0;
  //проверяем буфер
  if (buffer != NULL)
  {
    //добавляем к буферу строки из data, в количестве nmemb
    buffer->append(ptr, size * count);
    //вычисляем объем принятых данных
    result = size * count;
  }
  //вовзращаем результат
  //printf("DATA: %s", (char*)ptr);
  //printf("DATA: %s", ptr);
  return result;
    //printf("DATA: %s", (char*)ptr);
    //return count*size;
}

int main(void)
{
  CURL *curl;
  CURLcode res;
struct curl_slist *headerlist=NULL;


headerlist = curl_slist_append(headerlist, "Content-Type:text/xml");
  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);

  /* get a curl handle */
  curl = curl_easy_init();
  if(curl) {
    /* First set the URL that is about to receive our POST. This URL can
       just as well be a https:// URL if that is what should receive the
       data. */
	    
    curl_easy_setopt(curl, CURLOPT_URL, "10.10.10.10:8081/Processing.asmx");
      //указываем прокси сервер
      curl_easy_setopt(curl, CURLOPT_PROXY, "10.10.10.1:8080");
	   curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "user:123456");
 curl_easy_setopt(curl, CURLOPT_USERPWD, "user2:Password2");
 
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
std::cout << "Server response:"<<buffer << "\n";
    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  curl_global_cleanup();
  //curl_formfree(formpost);
  curl_slist_free_all (headerlist);
  return 0;
}

Masha
() автор топика

Язабан. Помогаем тут какому-то ленивому зеленому студенту которому влом почитать доки по используемому стеку технологий чтоб заработать себе на доширак.

NeverLoved ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.