Not able to read data using libcurl - c

Below is my code:
#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 *curl;
CURLcode res;
/* Minimalistic http request */
const char *request = "reactantsJSON={\"O=O\":{\"N\":1}}&productsJSON=[\"O=O\",\"[O]\"]&temperature=2273.15&pressure=101.325";
curl_socket_t sockfd; /* socket */
long sockextr;
size_t iolen;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://gibbs.sdsu.edu:8080/axis2/services/GibbsMinimization/solveTP");
/* 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("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, request, strlen(request), &iolen);
if(CURLE_OK != res)
{
printf("Error: %s\n", curl_easy_strerror(res));
return 1;
}
puts("Reading response.");
/* read the response */
for(;;)
{
char buf[1024];
wait_on_socket(sockfd, 1, 60000L);
res = curl_easy_recv(curl, buf, 1024, &iolen);
if(CURLE_OK != res)
break;
printf("Received %u bytes.\n", iolen);
}
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
I am sending a Json string and the response I am expecting is an XML document. When I compile my code it compiles without errors. But for some reason it is not going in the for loop for the receive function. Any kind of help would be appreciated. thanks in advance.

$ gdb ./a.out
GNU gdb (GDB) 7.2-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from a.out...done.
(gdb) b 98
Breakpoint 1 at 0x400f5d: file c.c, line 98.
(gdb) run
Starting program: a.out
[Thread debugging using libthread_db enabled]
Sending request.
Reading response.
Breakpoint 1, main () at c.c:99
99 if(CURLE_OK != res)
(gdb) p res
$1 = CURLE_UNSUPPORTED_PROTOCOL
(gdb)
you have to put everything after the 1st slash in request instead of in curl_easy_setopt, so
curl_easy_setopt(curl, CURLOPT_URL, "http://gibbs.sdsu.edu:8080");
and
const char *request = "GET /axis2/services/GibbsMinimization/solveTP?reactantsJSON={\"O=O\":{\"N\":1}}&productsJSON=[\"O=O\",\"[O]\"]&temperature=2273.15&pressure=101.325 HTTP/1.0\r\n\r\n";
cause of you're doing the http request manually
also, way to initialize buf with all zeroes is
char buf[1024]={0};

Related

client C for API calls with curl_multi_*

I would like to create a C client that makes asynchronous API calls with lib curl and saves the responses, the calls are about a hundred at the same time. I have been looking for internet tutorials and examples for curl_multi_ * and curl_multi_socket with epoll for 4 days (I use linux) but they seem not to exist, and those few examples are not understandable to someone who is a beginner like me. Apparently I'm the only one interested in doing such a thing in C.
I also looked at the official documentation examples, but it uses a maximum of 2 connections at the same time and to do this declares two variables and calls curl_easy_init(), but the problem is that the requests made by the program are not a precise number so I cannot declare a number of variables a priori (even though it's not possible to declare 100 variables).
I found out this example of curl_multi_socket with epoll is difficult to understand and replicate for my case without an explanation of how it works.
Is there anyone who can give me a code example on how to use curl_multi_ * for multiple simultaneous connections to start with? it would be much appreciated.
EDIT:
after hours of research, I finally found an example that might be fit, the problem is that it crashes often and for various reasons
#define NUM_URLS 64
typedef struct data { // 24 / 24 Bytes
struct curl_slist * header;
char ** sub_match_json;
int nbr_sub_match;
int response_counter;
} data_t;
// list of the same URL repeated multiple times
// assume there are 64 url for example
static char *urls[] = {}
void make_header(data_t * data) {
//many curl_slist_append();
}
void init_data(data_t *data) {
data->sub_match_json = (char **)malloc(sizeof(char *) * NUM_URLS);
data->response_counter = 0;
data->nbr_sub_match = NUM_URLS;
make_header(data);
}
static size_t write_cb(void *response, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
data_t * data = (data_t *) userp;
data->sub_match_json[data->response_counter] = malloc(realsize + 1);
if(data->sub_match_json[data->response_counter] == NULL)
{
fprintf(stderr, "Memory allocation failed: %s\n", strerror(errno));
return 0; /* out of memory! */
}
memcpy(data->sub_match_json[data->response_counter], response, realsize);
data->sub_match_json[data->response_counter][realsize] = 0;
data->response_counter++;
return realsize;
}
static void add_transfer(CURLM *cm, int i, data_t *data)
{
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 1<<23);
// curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
// curl_easy_setopt(curl, CURLOPT_TCP_FASTOPEN, 1L);
// curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)data);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, data->header);
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
curl_easy_setopt(curl, CURLOPT_URL, urls[i]);
curl_easy_setopt(curl, CURLOPT_PRIVATE, urls[i]);
curl_multi_add_handle(cm, curl);
}
int main(void)
{
CURLM *cm;
CURLMsg *msg;
data_t global_data;
unsigned int transfers = 0;
int msgs_left = -1;
int still_alive = 1;
curl_global_init(CURL_GLOBAL_ALL);
cm = curl_multi_init();
init_data(NULL, &global_data); // my function
/* Limit the amount of simultaneous connections curl should allow: */
curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX_PARALLEL);
for(transfers = 0; transfers < MAX_PARALLEL; transfers++)
add_transfer(cm, transfers, &global_data);
do {
curl_multi_perform(cm, &still_alive);
while((msg = curl_multi_info_read(cm, &msgs_left))) {
if(msg->msg == CURLMSG_DONE) {
char *url;
CURL *e = msg->easy_handle;
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
fprintf(stderr, "R: %d - %s <%s>\n",
msg->data.result, curl_easy_strerror(msg->data.result), url);
curl_multi_remove_handle(cm, e);
curl_easy_cleanup(e);
}
else {
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
}
if(transfers < global_data.nbr_sub_match)
add_transfer(cm, transfers++, &global_data);
}
if(still_alive)
curl_multi_wait(cm, NULL, 0, 1000, NULL);
} while(still_alive || (transfers < NUM_URLS));
curl_multi_cleanup(cm);
curl_global_cleanup();
while (global_data.response_counter-- >= 0) {
printf("%s\n", global_data.sub_match_json[global_data.response_counter]);
}
return EXIT_SUCCESS;
}
Error:
api_calls(75984,0x100088580) malloc: Incorrect checksum for freed object 0x100604c30: probably modified after being freed.
Corrupt value: 0x600002931f10
api_calls(75984,0x100088580) malloc: *** set a breakpoint in malloc_error_break to debug
this is on curl_easy_cleanup(e);
Exception has occurred.
EXC_BAD_ACCESS (code=1, address=0x0)
otherwise, when no error occurs, in sub_match_json there are bytes and no char. Why this ?

Changing the hostname in libcurl in C

I'm trying to play with libcurl SMTP and everything works fine with this example: http://curl.haxx.se/libcurl/c/smtp-mail.html
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
/* This is a simple example showing how to send mail using libcurl's SMTP
* capabilities. For an exmaple of using the multi interface please see
* smtp-multi.c.
*
* Note that this example requires libcurl 7.20.0 or above.
*/
#define FROM "<sender#example.org>"
#define TO "<addressee#example.net>"
#define CC "<info#example.org>"
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO "\r\n",
"From: " FROM "(Example User)\r\n",
"Cc: " CC "(Another example User)\r\n",
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd#rfcpedant.example.org>\r\n",
"Subject: SMTP example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};
struct upload_status {
int lines_read;
};
static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
{
struct upload_status *upload_ctx = (struct upload_status *)userp;
const char *data;
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
data = payload_text[upload_ctx->lines_read];
if(data) {
size_t len = strlen(data);
memcpy(ptr, data, len);
upload_ctx->lines_read++;
return len;
}
return 0;
}
int main(void)
{
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = NULL;
struct upload_status upload_ctx;
upload_ctx.lines_read = 0;
curl = curl_easy_init();
if(curl) {
/* This is the URL for your mailserver */
curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.example.com");
/* Note that this option isn't strictly required, omitting it will result in
* libcurl sending the MAIL FROM command with empty sender data. All
* autoresponses should have an empty reverse-path, and should be directed
* to the address in the reverse-path which triggered them. Otherwise, they
* could cause an endless loop. See RFC 5321 Section 4.5.5 for more details.
*/
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
/* Add two recipients, in this particular case they correspond to the
* To: and Cc: addressees in the header, but they could be any kind of
* recipient. */
recipients = curl_slist_append(recipients, TO);
recipients = curl_slist_append(recipients, CC);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
/* We're using a callback function to specify the payload (the headers and
* body of the message). You could just use the CURLOPT_READDATA option to
* specify a FILE pointer to read from. */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* Send the message */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* Free the list of recipients */
curl_slist_free_all(recipients);
/* curl won't send the QUIT command until you call cleanup, so you should be
* able to re-use this connection for additional messages (setting
* CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling
* curl_easy_perform() again. It may not be a good idea to keep the
* connection open for a very long time though (more than a few minutes may
* result in the server timing out the connection), and you do want to clean
* up in the end.
*/
curl_easy_cleanup(curl);
}
return (int)res;
}
The email which I send looks like this:
Return-Path: ...
Received: from Hostname (ip)
...
Date:...
Subject:...
...
But how could I change my own hostname from libcurl. Is it possible to send it in the header or something like this? Or I only could change it by adding the lines in /etc/hostname file?

Building SOAP request using libcurl

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
It seems you have syntax mistakes or missing declarations - have a look at the error lines you provide from your log.

Json string in libcurl

Can I send a Json string using libcurl. I am new to both. Any kind of help would be appreciated. Basically i want to send a Json string using libcurl simple send and receive in C
My code is below:
#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 *curl;
CURLcode res;
/* Minimalistic http request */
const char *request = "reactantsJSON={"O=O":{"N":1}}&productsJSON=["O=O","[O]"]&temperature=2273.15&pressure=101.325";
curl_socket_t sockfd; /* socket */
long sockextr;
size_t iolen;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://gibbs.sdsu.edu:8080/axis2/services/GibbsMinimization/solveTP");
/* 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("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, request, strlen(request), &iolen);
if(CURLE_OK != res)
{
printf("Error: %s\n", curl_easy_strerror(res));
return 1;
}
puts("Reading response.");
/* read the response */
for(;;)
{
char buf[1024];
wait_on_socket(sockfd, 1, 60000L);
res = curl_easy_recv(curl, buf, 1024, &iolen);
if(CURLE_OK != res)
break;
printf("Received %u bytes.\n", iolen);
}
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
the error I am getting is that it says a ";" is missing in line 40, which is nothing but the json string, even though I ahve a ";" on that line. It looks like to send json string i need to do something, which I am not aware of. Do I need to specify some flags while compiling the code.
const char *request = "reactantsJSON={"O=O":{"N":1}}&productsJSON=["O=O","[O]"]&temperature=2273.15&pressure=101.325";
You need to escape " in your string literal.
const char *request = "reactantsJSON={\"O=O\":{\"N\":1}}&productsJSON=[\"O=O\",\"[O]\"]&temperature=2273.15&pressure=101.325";

Sending SOAP request using libcurl

I could understand the examples of simple sendrecv for sending REST request using libcurl. Now i want to send a SOAP request using libcurl. I have changed the REST request code to achieve the same, but the code is not working. My code is:
#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 *curl;
CURLcode res;
/* Minimalistic http request */
const char *request = "<?xml version="1.0" encoding="utf-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://ThermodynamicProperties/">
<S:Body>
<tns:getSpeciesInformation>
<speciesSymbol>CO2</speciesSymbol>
<phase>GAS</phase>
</tns:getSpeciesInformation>
</S:Body>
</S:Envelope>";
curl_socket_t sockfd; /* socket */
long sockextr;
size_t iolen;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://thermo.sdsu.edu/servlet/ThermodynamicProperties/ThermodynamicPropertiesService");
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);
/* 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("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,request, strlen(request), &iolen);
if(CURLE_OK != res)
{
printf("Error: %s\n", curl_easy_strerror(res));
return 1;
}
I feel that I am not doing correct in building the SOAP request. Any help would be great as this is a completely new field for me.
SOAP messages are much more complex than REST messages.
My advice would be to download one of the better SOAP utilities like "SOAPUI" and use this to build and test a well formed SOAP request. Once you have a working request you can paste this into your C program.
Also I would recommend using a library like libxml2 (or Xerces if you dont mind C++) to build your SOAP messages if you are doing anything more complex than sending a simple pre formatted request.
SOAPUI is a java based test utility SOAP services. It can generate messages form a given WSDL, generate responses, browse messages etc.
More info here: SOAPUI

Resources