使用 libcurl 构建 SOAP 请求

发布于 2024-12-04 10:51:43 字数 4743 浏览 1 评论 0原文

以下是我构建肥皂请求的代码:

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

/* Auxiliary function that waits on the socket. */ 
static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms)
{
  struct timeval tv;
  fd_set infd, outfd, errfd;
  int res;

  tv.tv_sec = timeout_ms / 1000;
  tv.tv_usec= (timeout_ms % 1000) * 1000;

  FD_ZERO(&infd);
  FD_ZERO(&outfd);
  FD_ZERO(&errfd);

  FD_SET(sockfd, &errfd); /* always check for error */ 

  if(for_recv)
  {
    FD_SET(sockfd, &infd);
  }
  else
  {
    FD_SET(sockfd, &outfd);
  }

  /* select() returns the number of signalled sockets or -1 */ 
  res = select(sockfd + 1, &infd, &outfd, &errfd, &tv);
  return res;
}

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

  struct curl_slist *headerlist=NULL; 
struct MemoryStruct *bodyStruct=NULL; 
char _gatineauSoapReq[2000]=""; 

const char *WriteMemoryCallback;
  /* Minimalistic http request */ 

  curl_socket_t sockfd; /* socket */ 
  long sockextr;
  size_t iolen;

  ch = curl_easy_init(); 
  curl_easy_setopt(ch, CURLOPT_URL, "http://thermo.sdsu.edu/servlet/ThermodynamicProperties/ThermodynamicPropertiesService"); 
  curl_easy_setopt(ch, CURLOPT_POST, 1); 
  curl_easy_setopt(ch, CURLOPT_HEADER, 1); 
  curl_easy_setopt(ch, CURLOPT_VERBOSE, 1); 
  curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 
  if ((bodyStruct = (struct MemoryStruct *) malloc(sizeof(struct MemoryStruct))) == NULL) exit(1); 
  curl_easy_setopt(ch, CURLOPT_FILE, bodyStruct); 

  curl_slist_free_all(headerlist); 
  headerlist = curl_slist_append(headerlist, "Content-Type: text/xml"); 
  headerlist = curl_slist_append(headerlist, "SOAPAction: \"http://blabla.com/blabla_services/ValidateNow\""); 
  sprintf(_gatineauSoapReq, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\ 
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
   <ns2:getSpeciesInformationResponse
xmlns:ns2="http://ThermodynamicProperties/">
     <return>
     {&quot;Nist&quot;:true,&quot;Abinitio&quot;:[[&quot;3-21G&quot;,&quot;MP2&quot;,&quot;&quot;]],&quot;Nasa&quot;:true,&quot;Chemkin&quot;:true,&quot;Burcat&quot;:true}
     </return>
   </ns2:getSpeciesInformationResponse>
 </S:Body>
</S:Envelope>
  curl_easy_setopt(ch, CURLOPT_POSTFIELDS, _gatineauSoapReq); 
  curl_easy_setopt(ch, CURLOPT_HTTPHEADER, headerlist); 
  curl_easy_perform(ch); 

    //res = curl_easy_perform(curl);

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

    /* Extract the socket from the curl handle - we'll need it for waiting.
     * Note that this API takes a pointer to a 'long' while we use
     * curl_socket_t for sockets otherwise.
     */ 
    res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr);

    if(CURLE_OK != res)
    {
      printf("Error: %s\n", curl_easy_strerror(res));
      return 1;
    }

    sockfd = sockextr;

    /* wait for the socket to become ready for sending */ 
    if(!wait_on_socket(sockfd, 0, 60000L))
    {
      printf("Error: timeout.\n");
      return 1;
    }

    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,, strlen(request), &iolen);

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

    /* read the response */ 
    //for(;;)
    {
      printf("ok1 \n");
      char buf[1024];

      wait_on_socket(sockfd, 1, 60000L);
      res = curl_easy_recv(curl, buf, 1024, &iolen);
 printf("ok2 \n");
      if(CURLE_OK != res)


       //break;

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

 //printf("ok3 \n");
      //printf("Received %u bytes.\n", iolen);
      printf("data %s \n", buf);


    }

    /* always cleanup */ 
    curl_easy_cleanup(curl);

  return 0;
}

同样,在构建肥皂请求之外,应该如何发送请求,如果我们使用curl_easy_send()

我收到以下错误:

curls.c: In function âmainâ:
curls.c:57:45: warning: incompatible implicit declaration of built-in function âmallocâ
curls.c:57:59: error: invalid application of âsizeofâ to incomplete type âstruct MemoryStructâ 
curls.c:57:91: warning: incompatible implicit declaration of built-in function âexitâ
curls.c:63:72: warning: backslash and newline separated by space
curls.c:64:22: error: expected â)â before âhttpâ
curls.c:69:60: error: invalid suffix "G" on integer constant
curls.c:146:1: error: expected â;â before â}â token

Below is my code for building a SOAP request:

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

/* Auxiliary function that waits on the socket. */ 
static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms)
{
  struct timeval tv;
  fd_set infd, outfd, errfd;
  int res;

  tv.tv_sec = timeout_ms / 1000;
  tv.tv_usec= (timeout_ms % 1000) * 1000;

  FD_ZERO(&infd);
  FD_ZERO(&outfd);
  FD_ZERO(&errfd);

  FD_SET(sockfd, &errfd); /* always check for error */ 

  if(for_recv)
  {
    FD_SET(sockfd, &infd);
  }
  else
  {
    FD_SET(sockfd, &outfd);
  }

  /* select() returns the number of signalled sockets or -1 */ 
  res = select(sockfd + 1, &infd, &outfd, &errfd, &tv);
  return res;
}

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

  struct curl_slist *headerlist=NULL; 
struct MemoryStruct *bodyStruct=NULL; 
char _gatineauSoapReq[2000]=""; 

const char *WriteMemoryCallback;
  /* Minimalistic http request */ 

  curl_socket_t sockfd; /* socket */ 
  long sockextr;
  size_t iolen;

  ch = curl_easy_init(); 
  curl_easy_setopt(ch, CURLOPT_URL, "http://thermo.sdsu.edu/servlet/ThermodynamicProperties/ThermodynamicPropertiesService"); 
  curl_easy_setopt(ch, CURLOPT_POST, 1); 
  curl_easy_setopt(ch, CURLOPT_HEADER, 1); 
  curl_easy_setopt(ch, CURLOPT_VERBOSE, 1); 
  curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 
  if ((bodyStruct = (struct MemoryStruct *) malloc(sizeof(struct MemoryStruct))) == NULL) exit(1); 
  curl_easy_setopt(ch, CURLOPT_FILE, bodyStruct); 

  curl_slist_free_all(headerlist); 
  headerlist = curl_slist_append(headerlist, "Content-Type: text/xml"); 
  headerlist = curl_slist_append(headerlist, "SOAPAction: \"http://blabla.com/blabla_services/ValidateNow\""); 
  sprintf(_gatineauSoapReq, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\ 
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
 <S:Body>
   <ns2:getSpeciesInformationResponse
xmlns:ns2="http://ThermodynamicProperties/">
     <return>
     {"Nist":true,"Abinitio":[["3-21G","MP2",""]],"Nasa":true,"Chemkin":true,"Burcat":true}
     </return>
   </ns2:getSpeciesInformationResponse>
 </S:Body>
</S:Envelope>
  curl_easy_setopt(ch, CURLOPT_POSTFIELDS, _gatineauSoapReq); 
  curl_easy_setopt(ch, CURLOPT_HTTPHEADER, headerlist); 
  curl_easy_perform(ch); 

    //res = curl_easy_perform(curl);

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

    /* Extract the socket from the curl handle - we'll need it for waiting.
     * Note that this API takes a pointer to a 'long' while we use
     * curl_socket_t for sockets otherwise.
     */ 
    res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr);

    if(CURLE_OK != res)
    {
      printf("Error: %s\n", curl_easy_strerror(res));
      return 1;
    }

    sockfd = sockextr;

    /* wait for the socket to become ready for sending */ 
    if(!wait_on_socket(sockfd, 0, 60000L))
    {
      printf("Error: timeout.\n");
      return 1;
    }

    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,, strlen(request), &iolen);

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

    /* read the response */ 
    //for(;;)
    {
      printf("ok1 \n");
      char buf[1024];

      wait_on_socket(sockfd, 1, 60000L);
      res = curl_easy_recv(curl, buf, 1024, &iolen);
 printf("ok2 \n");
      if(CURLE_OK != res)


       //break;

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

 //printf("ok3 \n");
      //printf("Received %u bytes.\n", iolen);
      printf("data %s \n", buf);


    }

    /* always cleanup */ 
    curl_easy_cleanup(curl);

  return 0;
}

Also along with building the SOAP request, how should one send the request, should we use the curl_easy_send().

I am getting the following error:

curls.c: In function âmainâ:
curls.c:57:45: warning: incompatible implicit declaration of built-in function âmallocâ
curls.c:57:59: error: invalid application of âsizeofâ to incomplete type âstruct MemoryStructâ 
curls.c:57:91: warning: incompatible implicit declaration of built-in function âexitâ
curls.c:63:72: warning: backslash and newline separated by space
curls.c:64:22: error: expected â)â before âhttpâ
curls.c:69:60: error: invalid suffix "G" on integer constant
curls.c:146:1: error: expected â;â before â}â token

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枕头说它不想醒 2024-12-11 10:51:44

您似乎有语法错误或缺少声明 - 查看您从日志中提供的错误行。

It seems you have syntax mistakes or missing declarations - have a look at the error lines you provide from your log.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文