How to check the SOAP Response using libcurl - c

I am sending a SOAP request to a web service and I want to check what response I have received. How to achieve this?
My code is:
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
const char *temp = "<?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>";
printf("%s",temp);
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://thermo.sdsu.edu/servlet/ThermodynamicProperties/ThermodynamicPropertiesService");
/* Now specify the POST data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, temp);
printf("OK \n");
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
Right now the response I am getting is:
Sending request.
Reading response.
Received 123 bytes.
How to print what I am receiving??

You can use a callback function which gets passed the response. You can find an example here.

Related

Could I able to send a HTTP request using lib cURL in c/c++?

I'm trying to use libcurl to send a request like below in C/C++:
GET https://example.com/ HTTP/1.0
Host: https://example.com
Range: bytes=0-0
Connection: keep-alive
PS: I tried 2 case using : in the end of every header's line has "\r\n" and the last header has "\r\n\r\n" (end of header signal) and not adding "\r\n" in the end of file with curl_slist_append() + CURLOPT_HTTPHEADER.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <curl/curl.h>
int main()
{
CURL *curl = curl_easy_init();
struct curl_slist *list = NULL;
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
list = curl_slist_append(list, "Range: bytes=0-0");
list = curl_slist_append(list, "Connection: keep-alive");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
CURLcode ret = curl_easy_perform(curl);
if (ret == CURLE_OK) {
printf("success\n");
} else {
printf("fail\n");
}
curl_slist_free_all(list); /* free the list */
}
}
But seems like it doesn't work.
I tried to use WireShark to capture the HTTP packages by running it with sudo, and filter "http", but nothing is captured.
Am I right to use curl_slist_append() with option CURLOPT_HTTPHEADER to send the headers like I want?
If that is wrong, how do I send it to an HTTP server using libcurl, or do I have to use a socket connection instead?

Curl get request in C -Store the html data in another file

I am using this code to retrieve the data from the web browser using curl request in c language. I want to store the output in another file or buffer.
#include <stdio.h>
#include <curl/curl.h>
#include <curl/easy.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
/* 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);
}
return 0;
}
The output of this code is an html file. I want to store that html in another file or buffer. How to do that.
Thank you in advance.
Here's a modification to your code that writes the HTML response to a file:
#include <stdio.h>
#include <curl/curl.h>
#include <curl/easy.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
/* create an output file and prepare to write the response */
FILE *output_file = fopen("output_file.html", "w");
curl_easy_setopt(curl, CURLOPT_WRITEDATA, output_file);
/* 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: %sn",
curl_easy_strerror(res));
}
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
Here are some related questions:
Saving a file using libcurl in C
Download file using libcurl in C/C++

trying to figure out how to send json data via lib curl in c

I'm trying to figure it out hoy to send json data to a web service.
json.phph y just a php who prints all the $_REQUEST send to the script. but in hehe end i receive nothing,, i tried sending the form in urlenc format and just normal data D:
im running out of ideas how this can be done.
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
int main(int argc, char *argv[])
{
CURL *curl;
CURLcode res;
struct curl_httppost *formpost=NULL;
struct curl_httppost *lastptr=NULL;
struct curl_slist *headerlist=NULL;
static const char buf[] = "Content-Type: application/json";
curl_global_init(CURL_GLOBAL_ALL);
/*
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "json",
CURLFORM_COPYCONTENTS, "reactantsJSON={\"O=O\":{\"N\":1}}&productsJSON= [\"O=O\",\"[O]\"]&temperature=2273.15&pressure=101.325",
CURLFORM_END);
*/
curl = curl_easy_init();
/* initalize custom header list (stating that Expect: 100-continue is not
* wanted */
headerlist = curl_slist_append(headerlist, buf);
if(curl) {
/* what URL that receives this POST */
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1/json.php");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl,CURLOPT_POST,1);
curl_easy_setopt(curl,CURLOPT_POSTFIELDS, "reactantsJSON%3d%7b%22O%3dO%22%3a%7b%22N%22%3a1%7d%7d%26productsJSON%3d%5b%22O%3dO%22%2c%22%5bO%5d%22%5d%26temperature%3d2273.15%26pressure%3d101.325" );
// curl_easy_setopt(curl,CURLOPT_POSTFIELDS, "reactantsJSON={\"O=O\": {\"N\":1}}&productsJSON=[\"O=O\",\"[O]\"]&temperature=2273.15&pressure=101.325" );
// if ( (argc == 2) && (!strcmp(argv[1], "noexpectheader")) )
/* only disable 100-continue header if explicitly requested */
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
/* then cleanup the formpost chain */
curl_formfree(formpost);
/* free slist */
curl_slist_free_all (headerlist);
}
return 0;
}
You want CURLOPT_HTTPPOST or CURLOPT_POSTFIELDS, not both. They will issue two different kinds of POST requests.

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

HTTP Get request in C

I'm just learning to code in C, and I wan't to know if anyone can point me in the right direction, or give me an example for a simple HTTP Get request in C.
Thanks :)
You may checkout libcurl. And here are some examples. It could be as easy as (taken from the doc):
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se");
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}

Resources