使用 libcurl 构建 SOAP 请求
以下是我构建肥皂请求的代码:
#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;
}
同样,在构建肥皂请求之外,应该如何发送请求,如果我们使用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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您似乎有语法错误或缺少声明 - 查看您从日志中提供的错误行。
It seems you have syntax mistakes or missing declarations - have a look at the error lines you provide from your log.